# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

How to deal with events

Author:
Stephane Coutelas

Overall view

To manage events, a class has to get or create a server. The server stores emitters, listeners, and events. When the server is required to pump events, it checks every emitters to get last events. All the listeners are stored in the server as a pair (type of event, listener). Thus a particular event can be handled by several listeners. It's the class which adds emitters and listeners it needs to the server.

CEvent

CEvent inherits CClassId. A predefined event is built by inheriting CEvent and using a CClassId, built whith a unique id. Existing events can be found in events.h.

IEventListener

The interface provides a callback. A listener must implements this interface. Existing listeners can be found in event_listener.h.

In the following example, the listener is supposed to have been added to an event server along with the event type EventCharId:

CCallback cb;
server.addListener (EventCharId, &cb); 
When this callback is called whith such event it prints the char :
class CCallback : public IEventListener
{
        virtual void operator ()(const CEvent& event)
        {
                CEventChar ec = (CEventChar &) event; // here we know that we receive a CEventChar event
                printf("%c", ec.Char);
        }
};

IEventEmitter

It's the interface which gets low-level events and posts them to the server as NEL events. An emitter must implements this interface. Existing emitters can be found in emitters.h.

CEventServer

A server is made of :

  • a multimap of (CClassId, IEventListener*)
  • a list of IEventEmitter*
  • a list of CEvent*
When a call to the method pump is done, the server pumps its emitters for events. Events are stacked up in the list.

event_pump.png
Then, for each event, according to their id, the server applies the right callbacks stored in the multimap.

event_listener.png

As for emitters, both server and class know the IListener. The listener callback is the operator() which takes an event in parameter. Thus, the user defines the listener/callback he needs and adds it to the server.

event_callback.png

Example :

Here is an example of the use of the special listener CEventListenerAsync (defined in event_listener.cpp).

Rq : This listener stores key states : if a key is pressed its value is on, else it's off.

// declaring a listener
CEventListenerAsync asyncListener;

// declaring the server
CEventServer server;

// adding an emitter to the server 
... // here, a driver is initialized
server.addEmitter(driver->getEventEmitter()); //in this ex the driver provides the emitter

// adding the listener to the server
asyncListener.addToServer(server);

// events loop
do
{
 //pump for events
 server.pump();
 
 // user main function
 mainproc();
}
while(!asyncListener.isKeyPush(KeyESCAPE)); 

// removing listener from server
asyncListener.removeFromServer(Server);

Notes about the listener CEventListenerAsync : this listener adds two types of event to a server : EventKeyUpId and EventKeyDownId.

void CEventListenerAsync::addToServer (CEventServer& server)
{
 server.addListener (EventKeyUpId, this);
 server.addListener (EventKeyDownId, this);
}

The remove method is similar to add method, we must precise both event id and listener to be removed.

void CEventListenerAsync::removeFromServer (CEventServer& server)
{
 server.removeListener (EventKeyUpId, this);
 server.removeListener (EventKeyDownId, this);
}