= Event-Handler = Maintainer: Patrick Boenzli, boenzli at orxonox.ethz.ch == Overview == All files used for event handling are located in the {{{./src/util/event}}} directory. Here a short overview: * {{{event_handler.{cc, h} }}} - this is where all the event handling is going on: signals from the SDL env are interpreted and transmitted to the registered event listener * {{{event_listener.{cc, h} }}} - this is an abstract class. A class that extends it will have to implement all abstract functions ({{{process(...)}}}) and will be able to register itself to the EventHandler to receive events. * {{{event.{cc, h} }}} - a small class representing an event, that has occured * {{{key_mapper.{cc, h} }}} - a parser, that reads in the {{{orxonox.conf}}} file and translates the keynames to key-ids used in orxonox * {{{key_names.{cc, h} }}} - a file containig all key names with key-ids == Usage == The usage of the !EventHandler System is realy stright forward: consider a case, where you have a !PNode, that wants to receive some key-events: [[br]] The {{{pilot_me.h}}} could look like this: {{{ #!cpp #include "p_node.h" #include "event_listener.h" class Event; // forward declaration of a Event class class PilotMe : public PNode, public EventListener // extending EventListener { PilotMe(); virtual ~PilotMe(); void process(const Event &event); // abstract process class }; }}} The {{{pilot_me.cc}}} class could look like this: {{{ #!cpp #include "pilot_me.h" #include "event_listener.h" //the event listener interface #include "event.h" //the event structure PilotMe::PilotMe() { EventHandler::getInstance()->subscribe(this, ES_GAME, SDLK_LEFT); //subscribe this class to the left-key EventHandler::getInstance()->subscribe(this, ES_GAME, SDLK_RIGHT); //subscribe this class to the right-key } PilotMe::~PilotMe() { EventHandler::getInstance()->unsubscribe(this); //just unsubscribe all subscribtions of this class } . void PilotMe::process(const Event &event) { if( event.type == SDLK_LEFT) { if( event.bPressed == true) // whatever you want to do, when the left button is pressed else // whatever you want to do, when the left button is released } else if( event.type == SDLK_RIGHT) { if( event.bPressed == true) // whatever you want to do, when the right button is pressed else // whatever you want to do, when the right button is released } } }}} As you have seen, the whole event-management system is very simple, let's review all the necessary steps: 1. Extend {{{EventListener}}} with any class that want to receive events. 2. Implement the {{{void process(const Event &event);}}} function. 3. Subscribe for an event {{{EventHandler::subscribe(EventListener* el, elState state, int keyID)}}}.[[br]] You will find the complete list of all SDL Commands in the {{{usr/include/SDL/SDL_keysym.h}}} file. Orxonox has extended the list with some other events, that you will find in {{{./src/util/event/event_def.h}}}. The {{{elState}}} describes the state of the event handler: When the menu is displayed, there are is a diffrent key mapping than when you are playing the game. So this means that there are different states of the eventhandler: {{{ {ES_GAME, ES_MENU, ES_ALL} }}}. So if you subscribe to an event for the state {{{ES_GAME}}} this event will only shoot, if the eventhandler is in this state. 4. Don't forget to unsubscribe the event again via {{{EventHandler::unsubscribe(EventListener* el)}}}[[br]]. If you forget to do this, there will be a reference to an object that is probably not existent anymore, this will most certanly cause a segfault :D == Advanced == There is some more stuff to say :D. Its possible to define !KeyAliases in the {{{orxonox.conf}}} file. These aliases are wrapped in the {{{KeyMapper}}} class and are available from this class as static variables: Eg: * {{{KeyMapper::PEV_UP}}} - is the Up Key defined in the config file * {{{KeyMapper::PEV_FIRE1}}} - is the fire button defined in the config file * {{{KeyMapper::PEV_VIEW0}}} - is the view nr zero key * ... To see the whole list (and to extend it) read the {{{./src/util/event/key_mapper.{cc, h}}}} files, they are very short. To subscribe to such an event, you can use the code from above and alter it just a little: {{{ #!c //subscribe this class to the orxonox.conf left EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_LEFT); //subscribe this class to the orxonox.conf right EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_RIGHT); }}} == References == To see more references, look at some source code files, eg: * {{{./src/world_entities/camera.{cc, h} }}} - the camera can change the view by pressing some keys * {{{./src/world_entities/player.{cc, h} }}} - the player shoots and changes location