Sign in to follow this  

Designing a "message based" engine...

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

I have been giving this some thought lately, and the more I think about it the less sure I am how to go about implementing it. What I mean by a "message based" engine is that parts of the program submit "messages" into a queue. For example, the player presses a key. That key press generates a message and that message is added to the queue. Each frame the engine (if you can call it that) goes through the queue and looks at each message. Depending on the nature of the message, the engine makes calls to methods in other parts of the program. For example, the engine comes across the message for a keyboard button press. This would call some specific method in the player class to update the player position (or whatever that button ought to do). Now the problem is how to actually go about programming this. I thought about creating a generic base class for a message. It would contain a few simple variables, such as a name, a boolean value to see if it has been taken care of and can be discarded, and perhaps a few other basic things like that. Now I would derive other classes from this, depending on what the message needs to contain. For example, an imput message is going to contain a key code of which indicates which button was pressed, and whether it was pressed or release. That kind of message would be significantly different from a message to say, play a sound, or a message to indicate that the mouse has moved. The problem I am having is, how would the engine be able to distinguish between the different types of messages? How would the engine 'know' that a message contains variables specific to that kind of message? I haven't really done a lot with C++, but is this where RTTI (run time type identification) comes in? If you have any thoughts to add, please do. I am interested in seeing how other people have done this.

Share this post


Link to post
Share on other sites
RTTI can be used, but is an exceedingly ugly and non-extensible approach. Ordinary polymorphism works quite nicely here: make the events know how to handle themselves by providing a (pure) virtual function in the event base class that takes as a parameter a reference to the engine object. If an event can't do everything it wants to by itself, it can just ask the engine to handle it. This is pretty much how the Visitor pattern works.


struct engine;

struct event
{
virtual void dispatch(engine &) const = 0;
};

struct mouse_event : event
{
int x, y, buttons;
void dispatch(engine &e) const { e.handle(*this); }
};

struct keyb_event : event
{
int key, mod;
void dispatch(engine &e) const { e.handle(*this); }
};

/* and so on */

struct engine
{
void handle(const mouse_event &e) { /* do the deed */ }
void handle(const keyb_event &e) { /* do the deed */ }
};





You should probably also check out boost::variant for an alternative and extremely generic visitor-style approach.

Share this post


Link to post
Share on other sites
That is some pretty neat looking code. Like I said, I haven't had a lot of experience with C++, so I think I will have to do some playing around when I get home.

Share this post


Link to post
Share on other sites
If anyone has any further comments to add, please do. I am interested in seeing how other people handle things.

Share this post


Link to post
Share on other sites
I'm currently in the process of designing my game engine which uses an event system to tigger events throughout the engine. I was thinking of posting what I had currently but the design probably wouldn't do you much good...I could however (if I find time this weekend) code up some dummy classes to give you a general idea of what I'm attempting to do but I can't guarantee it would function 100% as I have no system built up around it. Sharlin's post covers off the general idea regarding events and data contained in them so it's definitely a good starting point :). My approach is slightly different and is a multi-threaded system with some of the following classes:

CListener
---------
Provides a means for the event manager to dispatch events to classes which have registered with it (it being the event manager) as a listener of a certain event. This class contains references to function pointers registered with it as "event handlers" for individual events. The event manager calls CListener::Dispatch( CEvent ) to return an event to the listener class. It is then up to the listener class to route each event to the correct "handler" method which was registered with it earlier.

CEventManager
-------------
Maintains control of the event queue as well as a list of listeners and their registered events. Being a threaded environment this class also has a means to allow a subsystem to send a message asyncronously (CThreadedEvent class...not getting into this :)) and forget about it as well as syncronously where it waits for the manager to inform it the event has been added to the queue. From here a sepearte thread is executing that periodically checks the queue, grabs the event and dispatches it to all registered listeners. This has to be quick to avoid deadlock on the message queue otherwise events will begin to lag behind.

CEvent
------
Provides a container for an event including it's name/ID and data which receiving handlers will require to correctly handle the event. When a subsystem calls Send(A)SyncEvent() it passes the built up event to the event manager directly.

There are a number of other classes involved in the system (I think a total of 8 but I'm at work and can't remember) but most of those you don't need to worry about. Like I said...I'll try my best to find some time this weekend to put my design document down and code up a very basic outline of my system NOT including threading related items...it will just complicate things. If not hopefully this explanation gives you a general overview of how things can be handled especially when mixed with Sharlin's example code.

I would highly recommend looking into a book called Game Coding Complete - Second Edition if you're looking into getting into your own engine design. It provides some great insight and interesting approaches to problems to get you on the right track. I borrowed some ideas for the event system from this book but have made a large number of enhancements to it to meet the needs of my system.

Share this post


Link to post
Share on other sites
I've tried a couple of methods. The first using the command pattern similar to the example by Sharlin. This is ok, but the message handler interface becomes HUGE and would require an entire engine recompile if you add new message types.

The second method I've tried is the method used in the Game Coding Complete 2 book, where the message and the data are separate and are based off a standard interface class. Effectively, you have IMessage, IMessageData and IMessageHandler (and some util functions to register handlers) - It's up to the coder to correctly cast them to the required types by identifying them on a unique 'type' key.

I found this worked pretty well in the system that I used. The way Mike McShaffry defines his types is to take a hash of the string id for it; this is better than having a single include file with all the numeric IDs for the message types as again, it lets you add messages without a full recompile.

Share this post


Link to post
Share on other sites
I am not too concerned about having to recompile often. Considering the size of the project at this point, it only take a few seconds anyway.

I have been trying to get ahold of cow_in_the_well to talk to him about this. Cow_in_the_well did something similar in the Mango Game Engine (used in his 4 Elements contest entry). I thought the idea was quite intriguing and like the design, so I figured I would do my own version of it.

Share this post


Link to post
Share on other sites
Quote:
Original post by evolutional
I've tried a couple of methods. The first using the command pattern similar to the example by Sharlin. This is ok, but the message handler interface becomes HUGE and would require an entire engine recompile if you add new message types.

The second method I've tried is the method used in the Game Coding Complete 2 book, where the message and the data are separate and are based off a standard interface class. Effectively, you have IMessage, IMessageData and IMessageHandler (and some util functions to register handlers) - It's up to the coder to correctly cast them to the required types by identifying them on a unique 'type' key.

I found this worked pretty well in the system that I used. The way Mike McShaffry defines his types is to take a hash of the string id for it; this is better than having a single include file with all the numeric IDs for the message types as again, it lets you add messages without a full recompile.

I found the system worked well for myself to a certain extent but my engine design is modularised so I'm having a hard time figuring out where to define events that inherit from CEvent so that the entire system (or only sub-systems that require them) have access to them without exposing too much of a sub-system to others. I've taken the basic outline and re-worked it in a number of ways including "callback" functions (not sure how to word this in my engine being developed as a single codebase for linux, mac and windows) to handle events rather than the if-elseif format used in the book. As well adding threading makes it much more robust but at the same time creates additional headaches in syncronization and performance. The example definitely proivdes an excellent starting point though and should work exceptionally well as-is for those looking to quickly implement an event based system in a single-threaded, unmodularised environment. While the entire engine is intended to be released as an open-source project I've considered releasing individual portions of the codebase (mainly my foundation classes) as I go which others may wish to just plug into their games/engines rather than using my solution.

EDIT:

Moe...while you may not be worried about it right now always keep in mind that you may wish to re-use this code at one point or another so it shouldn't be overly dependent on the design of your current project. In a system the size of mine if changing one interface means re-compiling the entire system I may as well go out for dinner while my build machine chugs away...I'm trying to reduce dependencies as much as possible to make the code truly flexible for almost any project :).

Share this post


Link to post
Share on other sites
True enough! Mind you, I think my largest project to date was only 2500 lines (my 4 Elements 2 entry).

Here is what I was thinking:

I would have a basic class called "Event" or "Message", something like this:

class Event
{
private:
boolean m_processed;
int m_eventDuration;
public:
String m_description;
int m_eventType;

//get and set variables here, like usual

}



The description is a brief textual description of the event. I figure it could come in handy when I have to debug things later on. The m_processed is set to true if that event has been processed in that frame. The m_eventDuration is the duration of how long the event should stay in the queue. If it is something that should persist more than one frame (for example, a force in the physics engine that is persistant in the game world for several seconds), it would be set to some value. I am thinking this will most likely be a duration of milliseconds. If it is set to 0, the event is handled then discarded immediately after. The m_eventType determines where the event should get passed off to - the sound system, physics, AI, etc. It will probably be a const int (like an enum). For each type of event, I would have a const int (or enum).

Now each kind of event would be derived from that basic class. For example, to play a sound, I would need a sound event (please forgive my syntax, it has been a while):

class PlaySoundEvent : Event
{
private:
String m_filename;
int m_duration;
bool m_loopSound;
public:

};



A mouse input event might look something like this:

class MouseMoveEvent : Event
{
private:
int x; //amount moved on x axis
int y; //amount moved on y axis
public:

};




Now for each kind of event, I would have an event manager class that would receive those types of events and handle them. For example, the SoundEventManager class could be something like this:

class SoundEventManager
{
private:
PlaySound(String filename, bool loop, int duration);
StopSound(String filename);
public:
HandleEvent(Event &event);

};




Now the main super-big event handler would simply go through the queue and pass of the events to each EventManager class, as needed:

Engine::EventHandler()
{
//I am sure there is lots of other code to go here...
for(int i = 0; i < eventQueue.count; i++)
{
if(eventQueue.event[i].getEventType() == EVENT_TYPE_SOUND)
soundEventManager.HandleEvent(&eventQueue.event[i]);

if(eventQueue.event[i].getEventType() == EVENT_TYPE_MOUSEMOVE)
inputEventManager.HandleEvent(&eventQueue.event[i]);

if(eventQueue.event[i].getEventType() == whatever other type there is)
that event type handler.HandleEvent(&eventQueue.event[i]);

}

}



How is this looking so far? I know it isn't as modular as it could be, but because I haven't done any real programming in the last 3 years I am trying to go for something simple that will work.

Share this post


Link to post
Share on other sites
Oh wow, funny I just saw this thread. The past week, I've been experimenting with a different architecture that was "message based" similar to what you are talking about. I'm not going to give away eveything yet, because I'm still working with the idea and I like it so far, so here's some commentary on what you have said in addtion to what I've come across:

Quote:
What I mean by a "message based" engine is that parts of the program submit "messages" into a queue. ... Each frame the engine (if you can call it that) goes through the queue and looks at each message. Depending on the nature of the message, the engine makes calls to methods in other parts of the program.


The first time I started this project, I actually tried the idea of keeping a message queue, then dispatching the messages by allowing each object to know what message to start at, so it can iterate though and process the messages. The main problem with this approach is first the overhead of storing messages in your queue. When do you remove them? What if a message needs to go to several different classes?

From what I saw, storing all of the messages then passing them to the objects could also create desynchronization. For example, if I passed two messages, one side effect would be that one object would "catch" up by processing the events in the message queue until there were no more and then the next object would do the same. What resulted was some objects doing messages out of order, which was bad. Now I could have made it so objects only processed messages one at a time, but then I was thinking, what's the point of that?

Next I saw if I was just going to be passing messages as they occured, why store them? If they only need to go to a specific object, then message processing could just send it as it is received, thus eliminating any desyncing as well as the additional overhead. With that in mind, I then based the rest of the design in terms of an "instant feedback" approach. Now, as you may be wonder, and as wa asked, "what about delayed events". At first I was thinking that was the only thing my approach could not accommodate for, but then I thought about it.

A delayed event is an event that is sent at some time, to which it actually happens a later time. More specifically in real life, it's some 'cause' that triggers some 'effect' in the future. Now, with the old version of storing messages in a queue, you could allow that system to track the time and dispatch messages only when some delay reaches 0, but I did not think that was realistic. My whole idea fo this "delayed event" is that an event is sent to some object, and the object itself handles the delaying.

For example, if you set an alarm clock to go off at some time, the object itself controls when the "effect" actually happens. If that object was turned off, then the event would not happen at all, which is more realistic with my model than that of the conventioanl message queue, which would still dispatch that message to the object. In addition, the actual messaging system would have to be some centralized component that received messages anddispatched them while keeping track of time and who it can send to and all of that. I opted for something much different.

Quote:
I thought about creating a generic base class for a message. It would contain a few simple variables, such as a name, a boolean value to see if it has been taken care of and can be discarded, and perhaps a few other basic things like that. Now I would derive other classes from this, depending on what the message needs to contain.


Good start with the idea of a generic base class for a message, that is what I do currently. However, I left it at that. Simple and easy to use, there is only one message class that stores 3 things, who sent it, data of the message, as well as the names of the message. The reason I did this was to minimize the dependecies that would otherwise be created with your proposal. For example, if you have 3 different classes with 3 different messages, all 3 would have to know about each other's format of the message if they want to interact.

I took the approach of "void* message passing". Yes, this of course seems more dangerous and unsafe, but, it's one of those things that is fine to do when you know exactly what you are trying to do. In my system, I pass a 1:1 ratio of named messages with void* data. This way, any object that receives a message can parse the message name and if it implements it, then it can process the data accordingly. My approach does rely on more of a "you know the data being passed around", so it is more error prone, but with a reasonable amount of checking, it is very flexible.

Quote:
The problem I am having is, how would the engine be able to distinguish between the different types of messages? How would the engine 'know' that a message contains variables specific to that kind of message?


As mentioned in the previous paragraph, the message name will let the object know what the message is. "What is done" with the message is specifically up to the object itself. If it does not handle the named message, then it will naturally just ignore that message. If it does handle it though, then it can process the data if any. Since each data will have a name with it, the end user can handle data in any order it comes. What I was going after with this approach is that of more a life-like representation. For example, let's say I pass a "kick" message to a boulder. Naturally, the boulder will not handle that message since it will not be affected by it.

Now I just said if I pass a "kick" message to a boulder, it would not handle it. With my design, all messages are sent to all objects! So if the player "kicks", all messages will receive the message as well as the data associted with it, such as where it took place, how hard was it and so on. If an object does not handle the kick message, it will simply ignore it. If it does handle it though, then it can see if it is actually affected by it.

Next comes the whole aspect of knowing what messages to pass and all of that. At first I just typed in the messages using strings and handled the handling of them doing the same. The problem that I saw was if that I needed to change a message one place, I'd have to change it in the other place, so what I did was make one header file that defined all of the messages being used. Of course each time I made a new message, I'd have to recompile, but it was a lot clearned and easier to use.

With my current design, I will be finding another way to do this, something that involves a map to which I can just register events and use them without having to worry about inconsistances. The idea would be that I can register messages and track them, so at any time, if a message is used that is not registered I can stop execution and warn myself that a typo was made or something was used that needs to actually be handling. That will make debugging a lot easier as well.

One last response on the idea of the actual messages being used. My main goal is to define a set of engine specific messages that are used to denote common events, such as when a key is pressed, what key it is will be passed as well. By doing this, I can then tie in any framework or library to use my system which would make integrating it a lot easier. In that case, all you would have to do is add in the specific message broad casting of events that corerlate to the engines defined ones and you are all set.

Ok, now I have covered pretty much the basics of my system. Time for demos! As I went along developing this system, I needed a way to test it in application to see where any problems were. What resulted was me making a SDL Selection Box demo. I have screenshots of the demos, the demos themselves, as well as screenshots of code to give you the idea of what is going on.

After I got to version 8 of that last example, I felt it was time to move on, so I hacked together an example, but this time using 3D and Opengl . OpenGL Selection Box. In that example, I implemented my messaging architecture and saw a few things had to be changed. Ok for controls:
Left mouse - Select or draw drag rectangle
Arrow Keys - When an object/objects are selected, change their rotation
Pg Up/Down - When object(s) are selected, will change their Z values.

That's about it for that demo, the hardest part for me was actually getting the OpenGL stuff to work correctly (one little thing I was doing wrong in my picking that threw me off for hours).

That's about it for now, I am working on integrating this system into a new engine that will use it. By doing this, I can see where some problems might occur or additional functionality I might need. For example, I always had the ability to send a message to a specific object, based on it's guid, but with the logics I had, it was being done incorrectly. Final note on this system are that it is decentralized -- there is no main message component. As to what I do, you should be able to figure it out though the code screenshots.

If you have any questions on this (Yes I see that I kinda wrote a lot [grin]), feel free to ask! I'm not giving away any code right now though, but I can show certain specific parts. On a final note, you can take aa look at my old threads at attempts to this as well: Void* Messaging for Classes, Self Managing Objects - Part 2, Self Tracking Object Design

Phew, that took a while [smile] Good luck!

Share this post


Link to post
Share on other sites
Wow, thanks Drew! I think it will take a while for my poor brain to absorb all of this!

For anyone else, feel free to add your comments if you have any!

Share this post


Link to post
Share on other sites
@Drew:

On Timers:
I agree that it would be simpler for objects to handle the "delay" and then fire an event when the timer comes for it. That's what my engine does. Letting the engine handle time sorting of events is an extra, unneeded hassle. Letting objects handle their own problems frees the engine up and makes it run cleaner IMHO.

On Queues:
I agree on getting rid of queues as well. It seems to make more sense just to just say:

event.DoIt();

than to say:

Engine.YouDoItInstead( event );

@Moe

On Maps:

Maps are your friend in this case. Instead of doing this business:

if (eventname == EVENT_MOUSECLICK) { do stuph }
else if (eventname == EVENT_KEYPRESS) { do stuph }
... etc ...

... you'll want a map. This assumes you have 1.2 bajillion message types and it's getting messy. With a map, you just do like so:

message_map["mouse_click"].DoIt();

On Problems:

The biggest problem that you'll find is that events, or what handles events, needs to know about other objects. Let's say for instance that the key "ENTER" is pressed on the keyboard. This shoots a gun in your game. Well, the problem is that the engine or event must know about this said gun and must also know how to operate it. The naive way would be like this:

Engine::HandleKeypress( key ) {
if ( key == "ENTER" ) {
gun_pointer->Shoot();
}
}


But as you can see, the engine needs a pointer to the gun. You will find as you grow that the number of objects and things your messaging system needs to be aware of is going to get ugly. You'll need pointers to the player, the gun, some timed events, GUI widgets of various flavors, the network if multiplayer, and all sorts of other silly little things. This is really ugly.

Ideally you need a system where the "engine" has no concept of how to specifically handle events. All it does is process them. You can do this in a few ways. None of them are ideal.

One way is the Command pattern, which i have used with some success. A command is an "event" that is linked to a user-input action of some kind.

Here is a basic class for a command:

class Command {
public:
Command() {};
virtual ~Command() {};
virtual void Execute() = 0;
};

And here is an inherited Command that lets the player shoot:

class CommandPlayerFire: public Command {
public:
CommandPlayerFire( player* p ) {};
~CommandPlayerFire() {};
void Execute();
private:
player* p;
};


So what you do is create a Command and attach it to something. All the "something" needs to know how to do is the Execute() function:

// create a shooting command:
Command* shoot_command = new CommandPlayerFire( pointer_to_player );

// "register" it with the engine-thingy somehow
engine->RegisterCommandWithKeypress(KEY_ENTER, shoot_command):


Then somewhere deep in the belly of the event processing system, you have this:

Engine::ProcessEvent( event ) {
if ( event.type == KEYPRESS ) {
key_map[KEY_ENTER]->Execute();
}
}


Then the engine doesn't even have to know what kind of Command is attached to the ENTER key. All it knows is that when ENTER is pressed it needs to Execute() the command attached to it.

Gotchas:

This sort of thing works pretty well for certain situations but you may find problems:

Let's say the player dies:

// player death:
delete player;

Oh! Now press ENTER!

// press enter
*** segmentation fault ***

The pointer to the player is now invalid.

Which means that your objects and your commands have to have some sort of communication if this sort of thing happens.

If you do this, you also need a way to update/add/remove commands registered with your engine.

Anyway, i hope that gives you some ideas. I'm not saying this is the silver bullet, it's just another approach to think about.

Share this post


Link to post
Share on other sites
I am also using a message based system within my engine but since my engine uses the systems approach the messaging is just a small part that allows the subsystems to talk to each other without knowing if they are there. In C# the delegates/events really help this since anyone can listen to an event that gets fired when a new message is sent through the top system. My message class has a few things...

Source - Where the message came from.
Destination - The intended destination of the message.
Title - Usually a command of sorts.
Message - The actual message.
InnerMessage - A recursive link to the same Message class just in case I need it. This is of course optional.

One thing I have really liked about the message system is I have a console class that takes input from the user at runtime and sends a message if the user types the send message command. Since all objects in the game's systems are added through the root manager I keep a reference to them and using Reflection I am able to change there properties pretty easily at runtime.

So messaging of some sort, I would say, is a nice feature if not a must in most engines today. I am currently in the process of adding the property changing feature, but if you want to take a look at my code and whatnot just click the link below. I am providing lots of documentation as I go along.

Share this post


Link to post
Share on other sites
Quote:
Original post by leiavoia
Which means that your objects and your commands have to have some sort of communication if this sort of thing happens.


In Game Coding Complete 2, Mike McShaffry addressed this problem quite well. Everything in the game had a unique ID; so your actors would Have their own Ids, so would sounds, textures, etc. Instead of passing a pointer around in the messaging system the game would pass one of these Ids around; when you try and resolve the Id to a pointer (dereferencing the handle) it will return NULL if the object has since been deleted, thus adding in a safety mechanism to the system.

Share this post


Link to post
Share on other sites
I just got a response back from cow_in_the_well. I figure it is relevant, so I will post it here:

Quote:
Original e-mail from cow_in_the_well

In MGE I toyed around with some messaging systems mostly as an abstraction between Python and C++, but it never got used substantially. A win32 style MsgProc type messaging thing is the simplest way to go about things, but I prefer to go about things in more of a C++ manner.

The first step towards this would be to use the base Event class system that you mentioned. The base event class would store an event ID, and a derived class would store the data for that event ID. The problem I have with this method is that your message handler, which would take an Event* would have to upcast the class type from Event* to the specific event type in order to get the data, but upcasting is technically "unsafe" without using dynamic_cast (C++'s built in RTTI), but dynamic_cast isn't fantastic either. Upcasting is what I did in MGE, e.g:


if (event.GetType() == KeyPress)
KeyPressEvent* kpe = (KeyPressEvent*)event;


A way around this would be to have the Event class handle the event itself, via a virtual function in the base class such as Event->HandleEvent(), but this sort of defeats the purpose of messages as the message itself is now acting as the message handler (although the event class could simply be a proxy that calls some other handler; for example the KeyPressEvent could look up a key bindings map that maps a key to a specific game play function pointer).

Really, the biggest issue is where and who handles the actual message. The simplest way would be to have a single monolithic win32 style MsgProc that gets events and then dispatches the event to whoever needs to know, but this leads to too much potential of having high level gameplay logic in the low level part of the engine (unless you post off events to another handler until it propagates up to the higher levels).

The way I did it is to have a base EventListener class, and instances of this class could be registered with the singleton EventManager class. When an event gets triggered, all the event listeners (who asked to be told about that type of event) will get their virtual HandleEvent function called. This allows for a more dynamic handling system where event listeners can be plugged in and out at runtime.

In any case, for my current version of MGE (and for Stick Soldiers for that matter) I am not using a pure message based system for the entire engine. It's mostly just a traditional game loop that goes through and updates each subsystem one after another.

For the places where I need some kind of abstraction from whoever uses the event (such as key input), my primary method at the moment is to use a quake 3 style keybinding system that binds keypresses to console commands. This provides abstraction at pretty much the highest level (code that has access to the engine core can, however, get key states directly from the engine if the want).

For example, I can go into the console and type: "bind W forward".

This simply associates the "W" button on the keyboard with the console command "forward", so that "forward" is called once per frame while the button is held down. It's important to note, however, that when you bind something to a button it is simply associating a raw string with the button (so could type "bind W aergnaerugi" and it would be bound, but it would not do anything when pressed since aergnaerugi is not a valid command -_^.

This being the case, we can do funky stuff like

bind F10 "toggle fullscreen; restartvideo"

which is actually running two console statements. "toggle fullscreen" toggles the fullscreen console variable from true to false, and then it runs "restartvideo" command which, as you can imagine, restarts the video with the current settings :).

Axis events (ie. mice) are also handled in a similar manner, except the mouse deltas are passed to the console command as parameters.

ANYWAY, I chose not to do a pure message system in my new version of the engine because I find they tend to be less deterministic (anyone anywhere can inject a message into the system in any order at any time ^___^) which means they are trickier to debug (potentially :P). They are, however, probably more elegant in the long run (I do think tho that it would be even more elegant in languages other than C++, such as Python or C#).

If you want to go the whole hog, you might want to check out superpig's Enginuity article which covers making a "process" based engine (http://www.gamedev.net/reference/articles/article1947.asp) although you've probably already seen it.




Share this post


Link to post
Share on other sites
Wow it's almost scary how close his system behaves to the one I have designed for my system. After toying with a bunch of ideas the listener class seems to be the simplest route for me to pursue especially with the entire event system being multithreaded. The event manager now allows a message to be broadcast throughout the system syncronously or asyncronously (and each listener class can decipher this as well since they handle dispatching to each event handler) but I'm still messing with the idea of components being able to broadcast messages internally to themselves without having to go directly through the queue (since some of my events would only be handled by the module generating them).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Moe
Quote:
Original e-mail from cow_in_the_well
...A win32 style MsgProc type messaging thing is the simplest way to go about things, but I prefer to go about things in more of a C++ manner.


For an example of how to easily turn a MsgProc procedure into a C++ 'pump', you can see http://www.codeproject.com/library/DWinLib.asp#winBaseO. You would probably turn 'WinBaseO' into 'EventObject' or something like that, to modify it for your needs.

Your problem description seems a little lacking, though. For instance, will some keystrokes move the current player and some keystrokes activate 'engine' routines, such as saving the game? Will some mouse events activate the player while others save the game? You probably don't want to broadcast all events to all entities, as that is kinda wasteful. Figure out a way to send the events to where you want them handled, in the simplest manner possible. I suppose you are getting the events from your system (Windows, Unix, ...), so you must build your system with that in mind as well.

It sounds like a fun problem, so enjoy it!

Share this post


Link to post
Share on other sites

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