I read in the wiki that it's OK to have multiple event queues but is there any down side to having a bunch of these? I'm looking at making a Timer class to abstract timers, and to make them 100% independent from each other I was thinking of giving them their own event queue. Is this going to cause any issues if I have 20 event queues laying around?
You have to make sure to check all eventqueues in your event loop, so instead of just calling al_wait_for_event once, you'll have to revert to polling your event queues, which kind of defeats the purpose of an event system.
RickyLee - I recently did an abstraction of timers, here it is if you would like to see it :
You can have as many timers as you like because they each have their own event queue, so yeah to answer your question I think it is fine.
BUT I think you need to rethink how many timers you actually need. 20 is a bit many. There should be maybe one or two, at most 3? I would say.
If you're doing a game, you'll probably want to tie most timing to the game-logic anyway. I.e. if your game has to proceed 0.1 seconds, 2 ticks, or whatever unit you use, it can tell to all objects in the game how much to advance their internal time.
Multiple timers is more for timing real world stuff. (E.g. an internet connection time-out.)
Thanks guys. I got it working and seems to be fine with multiple event queue's. Probably just comes down to how you like to structure your code. I really try to separate out different systems and make them self contained.
If anyone is interested here is what I have. A long time ago, on this site actually, someone posted event code for C++ that acts more like it does in .NET. Easily allowing callbacks to C++ object methods. I make heavy usage of this in most all my code to really keep systems separate and fire events instead of having objects be coupled together.
Event.h (this can be confusing if you aren't good with templates so it can be skipped. usage is simple though.)
My timer class that uses an Event<> to fire when it's interval is up:
Not sure which is more appropriate:
Or:
Abstractions on top of abstractions on top of abstractions on top of abstractions. Abstractions all the way down?
I know, but I find the usage to be so much better with this style of event handling. The event queue seems like a neat idea at first, but having the entire game be tied to 1 event queue just doesn't seem like it promotes decoupling of objects. If I have a player object that collects input I'll have an event queue inside that object as well so it's not dependent on my main games event queue which is just doing the draw/update work.
I hate querying for events and then branching off logic in the main loop. I'd much rather register my events on initialization and then just have them get fired when the event happens, but hey that's just me. I'm a .NET guy.
Or you can have your event loop pass the events into your Game class, which then further passes events down to individual objects in the game.
The way you do it, you have to keep a list of all objects, then call a quite questionable Update method on all of them. (Waiting up to 0.01 seconds inside.) It would indeed be much cleaner if you do like Tomasu says - wait until an event occurs then pass it along to the objects (with the same Update method, but this time it doesn't wait some arbitrary time but gets passed the object to process).
That sounds pretty coupled together though. All my objects relying on Allegro events being passed to them? In the event style programming I like, the classes aren't tied together with anything, which makes the usage of them cross-library. All I have to do is change the insides to the library specific stuff and all the glue code doesn't require modification. For example that same Timer interface I've written versions for in a couple other libraries. The exposed interface stays the same, just the insides change. I'm finding that to be very flexible.
I'd prefer not to wait 0.01 seconds but it seemed the event queue function blocks waiting for an event to happen so that was a way to make it non blocking. The examples I've seen do that by making a timer that runs 60 times a second. I would prefer if it could just check if there are any events instead of waiting for an event. Is there a way to do that instead?
That sounds pretty coupled together though. All my objects relying on Allegro events being passed to them?
You don't have to pass an ALLEGRO_EVENT to your objects. You could, or you could send your own event objects, or even call specific methods per event type.
I'm trying to picture how I structure my games and how this event queue would work together. With a main Game class and a StateManager class managing game state objects that switch between each other.
To have 1 event queue it would have to be in the Game class, but, for example, my MainMenu state class could have timers and such in it doing various things. The Game class itself would know nothing about the MainMenu state class (as it shouldn't). It would just know enough to create the class and push it onto the stack of states and switch to it. It doesn't need to know anything about it's insides, so in order to get these game states to know about this event queue I'd have to pass it along to them all so they could register events against it, creating a dependency that otherwise would not need to exist in a game library I use for different engines. Global var is out of the question. I never have those.
I'll have to think about this some, but the event queue system seems like it pigeon holes you some into a certain structure at first glance.
The thing is, most other game libraries I know ALSO use an event queue. SDL and SFML, for example, seem to have only one event queue, so a multiple queue design will not work for those libraries.
The way to deal with this then, if you don't want to be bound too tightly with Allegro is to have an adapter class in the middle that will poll the event queue and emit Allegro independent method calls to your game objects, as Thomas suggested.
I would prefer if it could just check if there are any events instead of waiting for an event. Is there a way to do that instead?
al_is_event_queue_empty
Everything has already been said. You'd probably be happiest implementing the event listener design pattern, with a simple translation to your generalized events from Allegro events. Your game objects don't need to know about the queue, because all events arrive in order[1] anyway.
Separate timers really aren't that sweet. Maybe you could go with two separate kind of objects (templates). One that listens to an external timer, and one that has a build-in timer. One could easily be derived from the other.
>_> TBH I'm a noob. I only know this stuff in theory.
Thanks for that function, that should do the trick for what I'm looking for with this stuff.
The way you do it, you have to keep a list of all objects, then call a quite questionable Update method on all of them.
I'm not all that worried about storing objects. I store tons of different objects in a game, this is no different. I changed the update method to do al_is_event_queue_empty() instead of waiting any timeout.
I'm still playing with the ideas of sharing the 1 event queue. Just not sure how I'd implement my event handling code with 1 event queue. I still want my Timer class in some fashion for a nice abstraction around what a timer is. I would somehow need to know what Timer object was fired just by examining the event structure.
If you are making your own timers which you just poll, then you really don't need Allegro timers and event queues at all. You just need to know the current time when Update is called (e.g. using al_get_time), the time of the last tick, then count the number of ticks between one and the other.
Or you can use ALLEGRO_TIMERs without event queues: al_get_timer_count