Message System, C++
Started by Ed Mack, Sep 30 2004 04:03 PM
14 replies to this topic
#1
Posted 30 September 2004 - 04:03 PM
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 :)
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 :)
#2
Posted 30 September 2004 - 04:34 PM
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.
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.
Jesse Coyle
#4
Posted 30 September 2004 - 08:24 PM
Basically a queue<Message> ;)
Look for PostMessage, GetMessage, PeekMessage, MSG in the online MSDN.
Look for PostMessage, GetMessage, PeekMessage, MSG in the online MSDN.
#5
Posted 01 October 2004 - 04:40 AM
Okay, thanks. I'm going to look at more event based models however.
Thanks :)
Thanks :)
#6
Posted 01 October 2004 - 11:32 AM
Quote
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
If Prolog is the answer, what is the question ?
#7
Posted 01 October 2004 - 12:06 PM
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.
The system proved to be good for aboth ssinchronous and synchronous events handling.
The framework installs Context.
User adds custom Receiver to 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.
struct Message
{
...
};
class Receiver
{
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:
Receiver* m_pTargetReceiver;
public:
virtual ~Context()=0;
virtual void update()=0;
virtual Receiver* setTargetReceiver(Receiver* tr)=0;
virtual void sendMessage(Message mes)=0;
...
};
The system proved to be good for aboth ssinchronous and synchronous events handling.
The framework installs Context.
User adds custom Receiver to 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.
#8
Posted 01 October 2004 - 01:19 PM
here's something really quick and dirty:
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 Event
{
union
{
struct
{
char ScanCode;
};
struct
{
int MouseButton;
};
};
};
class Receiver
{
virtual HandleIOEvent( Event* pe ) = 0;
};
class MouseReceiver : public Receiver
{
virtual OnWheelRotate( int amount ) = 0;
virtual OnLeftButtonDown() = 0;
virtual OnRightButtonDown() = 0;
};
class KeyboardReceiver : public Receiver
{
virtual OnKeyUp( char k ) = 0;
virtual OnKeyDown( char k ) = 0;
};
class EventManager
{
static vector<KeyboardReceivers> m_KRs;
static vector<MouseReceivers> m_MRs;
static RegisterKeyboardReceiver( KeyboardReceiver* pkr );
static RegisterMouseReceiver( MouseReceiver* pkr );
static HandleIO()
{
// get keyboard and mouse info, iterate through all keyboard
// receivers and mouse receivers and handle events
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()
{
EventManager::RegisterKeyboardReceiver( this );
}
OnKeyUp( char k )
{
// do whatever
}
};
- TripleBuffer
- Me blog
- Me blog
#9
Posted 01 October 2004 - 02:19 PM
#10
Posted 01 October 2004 - 02:54 PM
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 :)
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 :)
#11
Posted 01 October 2004 - 05:58 PM
Good, glad you found your way.
Jesse Coyle
#12
Posted 01 October 2004 - 06:03 PM
never underestimate the awesomeness of boost...
Brandon Bloom
http://brandonbloom.name
http://brandonbloom.name
#13
Posted 20 November 2004 - 11:32 AM
@bladder: Looks lot a like Observer-pattern (?)
#14
Posted 03 March 2005 - 03:42 PM
You might also consider the Windows GetAsyncKeyState() function to test for whether or not a key is down.
#15
Posted 03 March 2005 - 04:14 PM
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 :)
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users













