Sign in to follow this  

Event dispatching, Event manager for engine core system.

This topic is 3594 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I´m thinking about building a little event manager/dispatcher for my engine. I will be using it for example to send messagges between entities, queue timed actions like "remove this entity in ten secs". I will be using this to handle things for comunications between systems, for example input system can notify a "player in the world" about that "Up action" has been produced, etc... I´m kind of new on this, so, I would like to know if there is any paper on this, can anyone give any feedback on this, or in the other hand complain about my dumb idea. Thanks in advance, HexDump.

Share this post


Link to post
Share on other sites
I assume you mean boost::signals? Boost is great and I've used many parts of it but generic programming is by definition usually too generic (extra overhead for stuff that you really don't need).

Without more refined explanation of how you want your system to work it's hard to give an proper answer. In the system I'm designing currently we use a combination of delegates (google fast delegates), lock free queues and some other weird lock free state changes. This of course wouldn't make any sense if we weren't creating a multi threaded system [wink].

Share this post


Link to post
Share on other sites
Hi again,

Well, It could sound stupid, but I don´t really know what I really need.

I feel I need something like a event manager thing that will coordinate all system messages (game level mainly). For example as I said, connecting the player to the input system, sending messages between entities, etc... SO I would like to know if anyone has implemented something like this. What are you using it for, beside the things I told, etc...

Sorry for the vague explanation, but it is diffciult to explain something that you really don´t know how it looks like.

I could make a little list of things I will need to:

1) TImed events (an event that will be fired in x secs, like remove this from world in x secs).
2) Entity events. A entity can tell others about hazards, etc... or where they can find good items, etc...
3) Inter System events. For example, Logic system can send a meesage to the sound system to play sound X.
4) etc...

I don´t know if this is too much overbloated, because, for example insted of 3 I could have sound system as a singleton and just do CSoundSystem::GetPtr()->PlaySound(x).

I guess, this will really depend on my game, and if I aim net game. Anyway, I would like some one to discuss how they do this type of things, if they are usefful or just my view is overbloated/overenginiered.

Thanks in advance,
HexDump.

Share this post


Link to post
Share on other sites
Quote:
I could make a little list of things I will need to:

1) TImed events (an event that will be fired in x secs, like remove this from world in x secs).
2) Entity events. A entity can tell others about hazards, etc... or where they can find good items, etc...
3) Inter System events. For example, Logic system can send a meesage to the sound system to play sound X.
4) etc...


That's not how it works.

In event system, the core are events. They don't tell anyone anything, they trigger, and if someone happens to be listening, they react.

1) Timers are unrelated to events. They can just be implemented via events.
2) You don't query an entity, and it doesn't tell anyone. Player P enters room R. P subscribes to R's events. At some point, R fires "explosion" event. P will be notified, and will do something. In addition, HazardMonitor is also listening to explosion events, and when it happens, it will deal damage to all objects within range
3) Other way around again. When player enters a room, sound system subscribes to it. When player does something, it fires an event. Among others, sound system will receive it.


Pseudo design for this is something like this:

class Player {

void shoot()
{
ammo--;
calculateDamage();
fireGunEvent.fire(getGunType());
}
Event fireGunEvent;
Event moveEvent;
};

class SoundSystem {
void onEnvironmentEvent(int type, int x, int y, int damage)
{
if (type == BIG_EXPLOSION) {
play("big_explosion.wav");
}
}
void onGunFired(int gun_type) {
if (gun_type == PISTOL) {
play("pistol_shot.wav");
}
if (gun_type == SHOTGUN) {
play("shotgun_shot.wav");
}
}
}

class Room {

Room()
{
timer.schedule( onExplosion, 15 ); // in 15 seconds, explode
}

void onExplosion() {
// fire big explosion, at 100,150, with 5000 damage
environmentEffect.fire(BIG_EXPLOSION, 100, 150, 5000);
timer.schedule( onExplosion, 15 ); // fire another one in 15 seconds
}
Event environmentEvent;
};



Here, each system knows only about itself. It's up to the governing system to connect these events properly.

This gives you a lot of flexibility, since SoundSystem may not originally know about explosions in room, yet you can later connect it, possibly dynamically as needed.

For example, as player moves between rooms, you can unsubscribe player from hearing events that happen in far away rooms.

Share this post


Link to post
Share on other sites
To be honest, systems like this are often engineered for very large game engines where it is used to decouple dependencies between objects. This isn't an essential system.

struct Message
{
long object_id;
long type;
int message;
union
{
int param;
struct
{
short lparam;
short rparam;
};
void* data;
};
};

class IMessageListener
{
public:
virtual ~IMessageListener(){}

virtual int OnMessage( const Message& message )=0;
};

class EventManager
{
private:
typedef std::vector< IMessageListener* > MessageListenerList;
MessageListenerList m_MessageListenerList;

public:
EventManager();
~EventManager();

void RegisterMessageListener( IMessageListener* listener );
void UnRegisterMessageListener( IMessageListener* listener );

void SendMessage( long object_id, long type, int message, int param );
};

Share this post


Link to post
Share on other sites
As mentioned above the idea of events is to abstract the actor from the reactor. In our system they're used for that and by the nature of events they are pretty good for multi-threading. In our designs some events do know their target and can send the event "explicitly" to them like file system events (data available), that's they still need to go through some event queue to decouple threads (subsystem vs general purpose threads).

For example in thread N the script triggers an explosion and wants to know all the affected people, the underlying implementation fires an spatial event that the spatial hierarchy listens to and it fires another event when it has managed to process who're in the area.

The bad thing is that the system constantly changes state so if you fire that explosion effect and some object moves out after it was fired but before the spatial system has managed to gather all the objects it's unaffected. Here it's a matter of taste/need, in interactive graphics the changes are usually small enough that humans can't perceive them so it's acceptable.

I can't really give an concrete example since we/I haven't had time to test the system on larger (proper) scale. And on that note if anyone has experience with similar system I'd like to know some feedback too.

E: With our system Input/GUI are just another systems that sends events and subscribe to events (force-feedback, GUI animation).

Share this post


Link to post
Share on other sites
In my spare time at work I've been considering such a system but based in Lua (yay tables!).

The basic idea is that 'events' are passed into some kinda controller which then dispatches them to those intrested/named subsystems.

Timed events are handled by simply supplying a time as a parameter and then put into a heap, while the current time > next event in heap dispatch the event; heaps are nicely self organising so I don't invision it being that taxing to work out.

If I get more spare time I might try and knock something up...

Share this post


Link to post
Share on other sites
Phantom, this was more or less the way I had in mynd for my sistem. Anyway I think it is too early to try to build a system like this. I have got to this conclusion after reading the messages the other pals wrote.

I will leave this for a later time, concentrate now in more shot term taks, and try to see what I really need in the future.


Thanks for all the answers,
HexDump.

Share this post


Link to post
Share on other sites
Quote:
Original post by HexDump
I feel I need something like a event manager thing that will coordinate all system messages (game level mainly).

Using an event manager, rather than events scattered around, is IMO a bad design decision. It's also a very common decision, with good reason; on the face of it, it promises an unprecedented level of abstraction between components. However, this simplicity is a lot like making all your variables global: it's a short-term feel-good fix which makes your life MORE difficult in the long run, by obscuring cause and effect relationships. I've opined about this more fancifully in the past. (Actually, that whole thread is a treasure trove.)

BTW, not to toot my own horn, but if you want an event handling mechanism and don't want the overhead of boost::signal, check out a library I wrote which gives you much of the functionality of boost::signal in a much more efficient implementation.

Share this post


Link to post
Share on other sites
Hi again,

I´m using c++, and today just before entering the forums I noticed the article.

Sneftel thanks for the links, gonna read all the information you provide.

Thanks in advance,
HexDump.

Share this post


Link to post
Share on other sites

This topic is 3594 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this