For a project I need an observer class (owned by a Subject that then notifies all of its observers) that handles other behaviours.
These observers work by calling their onNotify( Event* ) method that then executes some behaviour based on the type of observer.
The way the method works is as follows:
void SpecificObserver::onNotify( const Event* nevent )
{
switch (nevent->GetId())
{
case EventId::Eventtype1:
{
const Eventtype1* type1 = dynamic_cast<const Eventtype1*>(nevent);
//some behaviour...
}
break;
case EventId::Eventtype2:
{
const Eventtype2* type2 = dynamic_cast<const Eventtype2*>(nevent);
//some other behaviour...
}
break;
}
}
So the method gets a pointer to a basic Event that only has as a GetId() method and no info, and based on that ID we know what type of event that is and we can cast to that, unlocking the other information it owns.
As it’s coded now it’s something like this:
enum class EventId{ Event, Eventtype1, Eventtype2 };
class Event
{
public:
virtual EventId GetId() const { return EventId::Event; }
};
As you noticed I have to define EVERY TYPE OF EVENT before the event itself, so if I want to add a new type of event I would have to edit the event code.
My question is:
Is there a way to only have an
enum class EventId{ };
that we can then add elements to where they are needed (I.E., where we actually define Event1, Event2…)?
something like
enum class EventId { //add element Eventtype1 };
class Event1 : public Event
{
public:
Event1( Info* i )
:
i(i)
{}
EventId GetId() const override
{ return EventId::Eventtype1; }
public:
Info* i;
};
This way not every type of event or type of observer that uses said event would even need to know about all the other types of event that there are, as they are useless to them, and it would actually be possible to “extend” the types of events that we have without editing the Event class itself.