Archived

This topic is now archived and is closed to further replies.

Scheduling Game Events

This topic is 5150 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

Hello, In the book Game Programming Gem 3, there is a section on "Scheduling Game Events" by Michael Harvey and Carl Marshall of Intel Labs. This is something I have been focusing on. I am in the process of putting some finishing touches on what I am calling my GameEventManager. The current implemenation uses a calendar queue data structure for enqueueing and dequeueing the game events. Does any know of any good articles or source code or any information on other games useage of a GameEventManager? If you have used something to help you schedule game events, what data structure did you use? How did you manage the processing of events versus the running game time? Thanks in advance, Dan

Share this post


Link to post
Share on other sites
I''m not sure if this will help, nor am I sure if it is good or not, but I''ll tell you how our game system worked.

We had a game event system where game modules had EventHandlers() that were registered with a bitmask saying which events they were interested in. Events were defined in a header file using an enumeration. In another file we had a system that let us define the bitmask for each event. Some events were targetted at the SOUND module, some were targetted at ALL modules, etc. Any part of the game could create an event by calling EventManager::CreateEvent( eventID ). This would return an EventObject from a list of pre-allocated ''free'' events. The event object had a union that let us store up to four uint32''s in it (or 4 pointers). Events went into a queue and were dispatched once per frame. We had no system for a calendar style of event management where events could be broadcast into the future. Instead, we had a Clock manager that could be configured to fire events after a certain amount of time had expired. These could be one-shot events or cyclical. In addition to firing events they could fire callback functions. Although the two systems were seperate they worked quite well in our application ( a sports game ).

On a large project involving a lot of different entities all trying to operate independantly an event system using ''post into the future'' style capabilties might make more sense but we opted for having the different modules handle that through the clock system instead.

Not that this information will help much but it might add some insight.

Share this post


Link to post
Share on other sites
i''ll tell you how i did it so if you''re not interested in specifics (but i guess you are) just skip it

I''ve done a general purpose event system like Sphet but even more abstracted (and much easier to add new events):

1) no events are predefined (except those generated by sdl which are infact processed by the eventmanager himself)

2) Using an uint32 for the event number there should be plenty space for ANY need

3) an event can carry up to 28 bytes of date (28 to pad the struct to a full 32 bytes not sure if it helps anything, but it''s definatly enough (use as pointers if needed more))

4) in addition every event handler can get one int of data specified when it is registered (to have the same function handle the same event differently, again not used now but who knows )

5) by using functors (thanks superpig for the enginuity ) every function and even class member functions can receive events (modified IFunctor to take 2 parameters --> IFunctor2)

6) as a result of (1) no numbers fixed --> easily extendable without modifying more later on

7) nifty features as stopping event processing on behalf of the handlers
the functions: you just activated your console and don''t want other handlers to process keyboard/mouse events? --> just return 1 instead of 0 from your handler and the manager will consider this event as finished. not sure where i got this from but it''s a really great feature but needs some pre thought about stacking the handlers.

(should be self explaining, if not fell free to ask)

//Event Functions

// register a handler for a specific event

void RegisterHandler(unsigned int EventNumber,IFunctor2<sEvent&,int> *Handler,int DefaultData=0);
// delete a handler

void DeleteHandler(unsigned int EventNumber,IFunctor2<sEvent&,int> *Handler,int DefaultData=0);
// add an event at the end of the queue

void AddEventLast(sEvent *ev){m_Events.push_back(*ev);};
// add an event at the front of the queue (for high priority events, not recommended (why?))

void AddEventFirst(sEvent *ev){m_Events.push_front(*ev);};
// post the QUIT message to clean up

void PostQuitMessage(){sEvent PostEvent;PostEvent.Type=QUIT;AddEventLast(&PostEvent);};
// request a free event number

int RequestFreeEvent();
// release a previously registered event number

int ReleaseFreeEvent(int EventNumber);


now everything needing an event just does:

//this is taken a bit out of context but i thing you get the idea

int TNum=EngineCore::Get().RequestFreeEvent();
EngineCore::Get().RegisterHandler(TNum,new CStdFunctor2<sEvent &,int>(Whatever),0);


to call the event do:

//sEvent is a union containing 3 arrays, again ask if you cant imagine

sEvent Event;
Event.Type=TNum;
Event.iData[0]=1;
Event.cData[4]=12345;
Event.fData[2]=3.14;
//this is resulting in the bytes 5,6,7 not beeing defined

EngineCore::Get().AddEventLast(&Event);


if this event is no longer needed just
ReleaseFreeEvent(TNum);
which has included regaining event numbers to be sure not to overrun


with this system i added a really easy timer class to have timed events:

//you want to respawn that rpg with RPGNum in exactly 10 seconds:

int TNum=EngineCore::Get().RequestFreeEvent();
EngineCore::Get().RegisterHandler(TNum,new CStdFunctor2<sEvent &,int>(RespawnRPG),RPGNum);
Timer.RegisterTimer(10000,TNum,0);
//RespawnRPG sould release the event to not run out of numbers


//you want to display your fps every second without worrying about it just do this before your game loop:

int TNum=EngineCore::Get().RequestFreeEvent();
EngineCore::Get().RegisterHandler(TNum,new CStdFunctor2<sEvent &,int>(SowFPS),0);
Timer.RegisterTimer(1000,TNum,1000);


all in all the system is perfectly fitting my needs as it''s in no way keeping me from extending it (without modifying the eventmanager code itself) and has all the features i currently need, and more.

if you like code i''ll post some here or mail it to you. after using it now for 1 year, while dithching most of my other stuff, i consider it now mostly bug free (it was a hell to get right, based heavily onto the stl after seeing that it''s soo much more powerful than my own classes ) and don''t think i will change anytime soon.

Share this post


Link to post
Share on other sites