3

i created an eventhandler system simplified described by following classes

IEventType - containing string name and hashed int value of the name for fast search
IEventData - data send along with a triggered event
EventManager - containing a std::map of <int, boost::signals2< bool( boost::shared_ptr< IEventData > ) >

(there some other listeneres too for lua script side events and more, but i think thats irrelevant now)

the actual problem is: when i derive an IEventData, let's say:

class EData_WriteToConsole : IEventData
{
  std::string text;
  int layer;
  ...
}

then i register some member function to the signal:

OnWriteToConsole( boost::shared_ptr< IEventData > ){ ... }
m_EventManager->AddListener(boost::bind(&Console::OnWriteToConsole, m_Console, _1));

and then use the EventManager's TriggerEvent function

boost::shared_ptr< EData_WriteToConsole > eventData(new EData_WriteToConsole("Text..", 1));
m_EventManager->TriggerEvent(eventData);

finally my event gets triggered: but i can't access EData_WriteToConsole specific event data because OnWriteToConsole only receives a base class IEventData ptr.

so i need to downcast the IEventData that boost::shared_ptr points to, into a derived class EData_WriteToConsole.

I'm currently stuck because my brain didnt get enough sleep the last days and i just can't think of a solution without downcasting. Is there a way around this, can i somehow restructure my class hierarchy so i don't need to upcast? (i thought about creating a std::map with data that is passed as eventdata so the receiving function can search for stuff it needs, but seems slow and silly to me) please help

cppanda
  • 1,235
  • 1
  • 15
  • 29
  • 1
    Casting from base class pointer to derived class pointer is *downcasting*, not upcasting. Inheritance trees have their roots at the top, blame computer scientists who don't get out in the fresh air enough... – Steve Jessop Mar 01 '11 at 10:00
  • thanks i corrected it, my mistake. i feel stupid about that now :/ – cppanda Mar 01 '11 at 10:08

1 Answers1

2

Could you put a virtual method in the IEventData interface e.g. actionEvent() that is implemented in the derived classes to call whatever is required to action the event?

It would restrict you a bit if the event needs to be actioned in several different ways though.

DanS
  • 1,677
  • 20
  • 30
  • i'm actually doing this on the lua eventlisteners and eventdata i have, but for the c++ eventmanger stuff this is not possible due to boost::signals2, because it calls all slots itself. i'd have to remove all boost::signals2 stuff to enable this functionality. but if there's really no other solution to that, i'd to it – cppanda Mar 01 '11 at 09:04
  • I ended with same approach in my question https://stackoverflow.com/questions/55695922/pattern-for-abstracting-object-and-behavior-simultaneously Key point is that `IEventData` knows how to process itself. But if you don't want to add behavior to data object you need service dispatching and downcasting inside appropriate service (( – gavenkoa Apr 16 '19 at 16:15