Event driven programming question

Started by
6 comments, last by Grain 18 years, 8 months ago
Sorry if this is a bit simple; I've been thinking about this problem today and I'm not that knowledgable about designing event driven programs (and my mind's not the clearest today). I'm also not really able to speak in the lingo, so I might be using the wrong terms. If I wanted to create a class that wants to communicate events to some non-pre-defined set of other classes when a event happens (such as the user pressing the "J" key, or after every 5 seconds etc), what would be the best way to send that data? Does the class keep a record of which classes would be interested in that kind of information in a big list (obviously the other classes would have to register for this list)? Or does the class send out a big signal on some sort of publically available part of memory for the other classes to check (kind of like a big noticeboard, I guess). Thanks in advance!
Advertisement
A simple way is to make threeclasses. An event manager and an eventsubscriber interface and lastly a message.

class CMessage { int nType; void *pData;};class IEventSubscriber {  int message ( int nType, CMessage* pData );};class IEventManager { // map <level, subscriptions_of_that_level> std::map< int, vector< IEventSubscriber*> > mvSubscriptions; unSubscribe(level, IEventSubscriber*); subscribe (level, IEventSubscriber*); sendMsg ( level, CMessage *);};


Every class that you want to be able to recieve a message should be derived from IEventSubscriber. When you have initialized the class you call the Manager and tell it you want messages from level X (ie LVL_TIMER). The manager puts all subscribers in the mvSubscriptions list.

When a class some time later calls "sendMsg" with the level LVL_TIMER, the manager calls the "message" function in all the subscribers list of that level. Hence any subscriber can pick what type of messages it wants a reaction on.

A simple and easy to implement way of doing it.
Domine non secundum peccata nostra facias nobis
So if I understand correctly, there's an intermediatory class that acts a bit like a herald for communicating the messages, right?

So this herald class has the following properties:
- a list of classes to tell when a message is given (and the methods for adding and removing from this list)
- a way for it to be given messages to pass to the classes on the list.

That makes sense. But is there usually a herald message class for every type of message, or one big message manager class for handing all messages?

Thanks again!
Quote:Original post by Trapper Zoid
So if I understand correctly, there's an intermediatory class that acts a bit like a herald for communicating the messages, right?

So this herald class has the following properties:
- a list of classes to tell when a message is given (and the methods for adding and removing from this list)
- a way for it to be given messages to pass to the classes on the list.

That makes sense. But is there usually a herald message class for every type of message, or one big message manager class for handing all messages?

Thanks again!


Well since the sendMsg function takes a CMessage * as parameter you just inherit from that class.

something like this for sending the message to all classes that wants the timer message. In the Message function of the subscriber you just cast the message to the prefered type. So short answer. One manager for all messages. The subscriptionpart is just so that you do not have to send all messages to every reciever. Only those that subscribe on a certain level.

 struct sMessage {   int  nType;   void *pMsgData; } tMessage;  struct sTimerMessage {   int    nType   time_t  time;  };.... tTimerMessage aTimerMsg; aTimerMsg.type = EVENTMSG_TIMESTAMP; aTimerMsg.time = gettime(); sendMsg ( EVENT_TIMER, (tMessage*)&aTimerMsg );....void sendMsg ( int nLevel, tMessage * pMessage ) { std::vector<IEventReciever*>::iterator it = this->m_vEventRecievers[nType].begin(); std::vector<IEventReciever*>::iterator itEnd = this->m_vEventRecievers[nType].end(); // Send the message to all recievers in the nLevel vector while ( it!=itEnd ) {  ((IEventReciever*)*it)->Message( nType, pMessage );  it++; };};
Domine non secundum peccata nostra facias nobis
Quote:Original post by Zorak

Every class that you want to be able to recieve a message should be derived from IEventSubscriber.

It would probably be better to have IEventSubscriber as a member of those objects instead if deriving from it, It’s simpler to manage especially when you want to have you objects derived from other base classes. This way you won’t be dealing with multiple inheritance which can get messy.
Quote:Original post by Grain
Quote:Original post by Zorak

Every class that you want to be able to recieve a message should be derived from IEventSubscriber.

It would probably be better to have IEventSubscriber as a member of those objects instead if deriving from it, It’s simpler to manage especially when you want to have you objects derived from other base classes. This way you won’t be dealing with multiple inheritance which can get messy.


Then how do you propose to store them in the manager? In the example i store a vector of IEventSubscriber*.
Domine non secundum peccata nostra facias nobis
Quote:Original post by Zorak
Well since the sendMsg function takes a CMessage * as parameter you just inherit from that class.


I'm not sure what you mean by inheritance in this case, but I can see how you can pass an identifier within the CMessage class to tell a singleton event manager class which destination classes to send the event to.

Thanks Zorak! I knew I'd seen this implementation somewhere before, but I'd forgotten how it was done. I'm sure I can come up with a workable solution now.

Quote:Original post by Zorak
Quote:Original post by Grain
Quote:Original post by Zorak

Every class that you want to be able to recieve a message should be derived from IEventSubscriber.

It would probably be better to have IEventSubscriber as a member of those objects instead if deriving from it, It’s simpler to manage especially when you want to have you objects derived from other base classes. This way you won’t be dealing with multiple inheritance which can get messy.


Then how do you propose to store them in the manager? In the example i store a vector of IEventSubscriber*.

In the same way. In this case it those pointers would point to a member of the object instead of the object it self.

This topic is closed to new replies.

Advertisement