0
101 Sep 30, 2004 at 16:03

I’ve been working away at a simple game framework, and came into a problem/design requirement that I’m sure most of you have faced plenty of times, needing a robust messageing system between objects.

For Keyboard event notification, settings update propagation and so on

I’ve thought lots. but havn’t really came up with a nice OOP way to work it. Please hit some ideas at me with a cluebat :)

#### 14 Replies

0
101 Sep 30, 2004 at 16:34

Setup one object that controls the messages. The most generic way is like the windows message queue. You can probably find a more specific way of doing this that works better when you restrict the domain to your game framework.

When objects want to find out if the keyboard has been pressed they ask that object. When objects want to simulate a keyboard event they tell that object.

0
101 Sep 30, 2004 at 18:11

The most generic way is like the windows message queue. [snapback]12184[/snapback]

0
101 Sep 30, 2004 at 20:24

Basically a queue<Message> ;)

Look for PostMessage, GetMessage, PeekMessage, MSG in the online MSDN.

0
101 Oct 01, 2004 at 04:40

Okay, thanks. I’m going to look at more event based models however.

Thanks :)

0
101 Oct 01, 2004 at 11:32

When objects want to find out if the keyboard has been pressed they ask that object. When objects want to simulate a keyboard event they tell that object.

i find event polling unelegant somehow. objects shouldn’t have to know where the events come from. they should just have to specify which events they want to capture (keyboard or mouse for example) by deriving from some receiver class or provide a delegate for that (depending on the language you use) and receive the events once they happen

0
101 Oct 01, 2004 at 12:06

That is the messaging system from my project. It is not necessary good for everything, I just wanted to make my input platform-independent. The idea is to use Context-Receiver scheme.

struct Message
{
...
};

{
virtual void onKeyDown(unsigned short key, unsigned rep)=0;
virtual void onKeyUp(unsigned short key, unsigned rep)=0;
virtual void onMouseDown(int x, int y, unsigned button)=0;
...
};

class Context
{
protected:
public:
virtual ~Context()=0;
virtual void update()=0;
virtual void sendMessage(Message mes)=0;
...
};


The system proved to be good for aboth ssinchronous and synchronous events handling.

The framework installs Context.
The system scans hardware when updates and sends corresponding messages to the Receiver.
User can send own messages through sendMessage function.
Context-Receiver pairs can be written for most subsystems. The code above is just the example of doing it for input.

Maybe that helps.

0
101 Oct 01, 2004 at 13:19

here’s something really quick and dirty:

class Event
{
union
{
struct
{
char ScanCode;
};

struct
{
int MouseButton;
};
};
};

{
virtual HandleIOEvent( Event* pe ) = 0;
};

{
virtual OnWheelRotate( int amount ) = 0;
virtual OnLeftButtonDown() = 0;
virtual OnRightButtonDown() = 0;
};

{
virtual OnKeyUp( char k ) = 0;
virtual OnKeyDown( char k ) = 0;
};

class EventManager
{
static HandleIO()
{
// get keyboard and mouse info, iterate through all keyboard
for( each keyboard/mouse receiver handle IO depending on type )
{
switch( IOType )
{
case KeyUp:
// Go through keyboards and call the OnKeyUp function
case KeyDown:
// Go through keyboards and call the OnKeyDown function
// etc...
}
}
};


You basically have your IO module right. And your IO manager checks if any input has taken place, then tell the objects that can handle any type of input to handle it. This way, objects dont have to constantly scan for input. When input happens, they’ll be told it happened and can do what they want. Any object that wants to handle the keyboard/mouse will have to register itself with the manager. ie:

class Player : public KeyboardReceiver
{
Player()
{
}
OnKeyUp( char k )
{
// do whatever
}
};

0
101 Oct 01, 2004 at 14:19
0
101 Oct 01, 2004 at 14:54

Wow! Thank you very much.

Boost is interesting, however I don’t like having so much abstracted from me, when I can write more specific code to do the same task.

Decibit, your approach was interesting too, and I think I’ll go for an approach similar to Bladder’s subscribe/manager pattern.

Thank you, I’m all sorted now :)

0
101 Oct 01, 2004 at 17:58

0
101 Oct 01, 2004 at 18:03

never underestimate the awesomeness of boost…

0
101 Nov 20, 2004 at 11:32

@bladder: Looks lot a like Observer-pattern (?)

0
101 Mar 03, 2005 at 15:42

You might also consider the Windows GetAsyncKeyState() function to test for whether or not a key is down.

0
101 Mar 03, 2005 at 16:14

It’s Linux ATM, so I wanted to write it OS agnostic. I went for the Publisher & Subcriber / Observer pattern, and it’s worked very nicely so far. Thanks Bladder and rest :)