Event System for a Monogame engine

Started by
2 comments, last by ddlox 3 years, 6 months ago

I was just wondering, is it properly implemented Event System when I have my input classes, ie, Mouse class and Keyboard class, which just send events into a EventHandler singleton who dispatches them across my game (either by subscriber pattern or something alongside those). Where Events can be intercepted by the UI and handle them before others can receive them. I am just scared that this would add overhead and slower responsiveness. I couldn't find any resources for the idea I've had if anyone can give me their opinion or just a resource where I can read more about this.

Advertisement

This sounds quite similar to what we have in our engine code. The system is written in C++ so it might work something different than in C# but here it is:

Our EventDispatcher class is a template class for the type of event that it should dispatch. Accessing it initializes a new instance of the class on first call and returns that instance. The event dispatcher class contains 4 vector objects (List<T>) which are each a pair of subscribers and the event data. Those vectors will be swapped when we dispatch all events to prevent subscribers from breaking the code. Imagine you fire an event that tells a subscriber to unsubscribe from the event. We prevent any data inconistency by just swapping the lists e.g. copying subscribers from one to the other.

You should not try to use locks here because you would recursively lock yourself out if you dispatch an event that causes the subscriber list to be modified meanwhile.

Finally we put the dispatch call onto a scheduled thread pool to have it executed once in a while. Events are collected in the dispatcher until a dispatch thread is running to spread those events one by one to all subscribers. It works quite well however because events run when the game is in idle mode somewhere

@sir7 i'm assuming that u know about polling, but u prefer events;

yes it's fine to have events, have a queue in the system so u don't lose any generated events, and if you think the system is not responsive enough then check on the number of listeners, see how many there are because it could take some time to propagate to them (by iteration);

Talking of which, make sure you implement posting and sending of your events to and off the queue (or to designated listener(s)), this way when an event E is being processed by listener L1, L2 does not have to wait until L1 is done and thus can also process E the moment it receives it;

you could make each subsystem have its own queue, this reduces latencies

and don't forget to add a good message pump for each queue with read-only (peek) / read-then-remove (poke), etc…

There are many nifty little tricks, you can do to add more excitement to your events and queues, for example, timed events stored in the queue (if an event has been in the queue longer than X msec, ignore it or skip it), repeaters or ref counted events (use me X times only: this saves on waiting for more to come), etc… etc…

and when done with a listener, make sure to unsubscribe it , otherwise your dispatcher will keep passing events to it;

That's it … all the best ?

This topic is closed to new replies.

Advertisement