|  | 1 | = Event-Handler = | 
                          |  | 2 |  | 
                          |  | 3 | Maintainer: Patrick Boenzli, boenzli at orxonox.ethz.ch | 
                          |  | 4 |  | 
                          |  | 5 | == Overview == | 
                          |  | 6 |  | 
                          |  | 7 | All files used for event handling are located in the {{{./src/util/event}}} directory. Here a short overview: | 
                          |  | 8 | * {{{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 | 
                          |  | 9 | * {{{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. | 
                          |  | 10 | * {{{event.{cc, h} }}} - a small class representing an event, that has occured | 
                          |  | 11 | * {{{key_mapper.{cc, h} }}} - a parser, that reads in the {{{orxonox.conf}}} file and translates the keynames to key-ids used in orxonox | 
                          |  | 12 | * {{{key_names.{cc, h} }}} - a file containig all key names with key-ids | 
                          |  | 13 |  | 
                          |  | 14 | == Usage == | 
                          |  | 15 | 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]] | 
                          |  | 16 | The {{{pilot_me.h}}} could look like this: | 
                          |  | 17 | {{{ | 
                          |  | 18 | #!cpp | 
                          |  | 19 | #include "p_node.h" | 
                          |  | 20 | #include "event_listener.h" | 
                          |  | 21 |  | 
                          |  | 22 | class Event;                                         // forward declaration of a Event class | 
                          |  | 23 |  | 
                          |  | 24 | class PilotMe : public PNode, public EventListener   // extending EventListener | 
                          |  | 25 | { | 
                          |  | 26 | PilotMe(); | 
                          |  | 27 | virtual ~PilotMe(); | 
                          |  | 28 |  | 
                          |  | 29 | void process(const Event &event);                // abstract process class | 
                          |  | 30 |  | 
                          |  | 31 | }; | 
                          |  | 32 | }}} | 
                          |  | 33 | The {{{pilot_me.cc}}} class could look like this: | 
                          |  | 34 | {{{ | 
                          |  | 35 | #!cpp | 
                          |  | 36 | #include "pilot_me.h" | 
                          |  | 37 | #include "event_listener.h"                        //the event listener interface | 
                          |  | 38 | #include "event.h"                                 //the event structure | 
                          |  | 39 |  | 
                          |  | 40 | PilotMe::PilotMe() | 
                          |  | 41 | { | 
                          |  | 42 | EventHandler::getInstance()->subscribe(this, ES_GAME, SDLK_LEFT);  //subscribe this class to the left-key | 
                          |  | 43 | EventHandler::getInstance()->subscribe(this, ES_GAME, SDLK_RIGHT); //subscribe this class to the right-key | 
                          |  | 44 | } | 
                          |  | 45 |  | 
                          |  | 46 | PilotMe::~PilotMe() | 
                          |  | 47 | { | 
                          |  | 48 | EventHandler::getInstance()->unsubscribe(this);  //just unsubscribe all subscribtions of this class | 
                          |  | 49 | } | 
                          |  | 50 | . | 
                          |  | 51 | void PilotMe::process(const Event &event) | 
                          |  | 52 | { | 
                          |  | 53 | if( event.type == SDLK_LEFT) | 
                          |  | 54 | { | 
                          |  | 55 | if( event.bPressed == true) | 
                          |  | 56 | // whatever you want to do, when the left button is pressed | 
                          |  | 57 | else | 
                          |  | 58 | // whatever you want to do, when the left button is released | 
                          |  | 59 | } | 
                          |  | 60 | else if( event.type == SDLK_RIGHT) | 
                          |  | 61 | { | 
                          |  | 62 | if( event.bPressed == true) | 
                          |  | 63 | // whatever you want to do, when the right button is pressed | 
                          |  | 64 | else | 
                          |  | 65 | // whatever you want to do, when the right button is released | 
                          |  | 66 |  | 
                          |  | 67 | } | 
                          |  | 68 | } | 
                          |  | 69 | }}} | 
                          |  | 70 | As you have seen, the whole event-management system is very simple, let's review all the necessary steps: | 
                          |  | 71 | 1. Extend {{{EventListener}}} with any class that want to receive events. | 
                          |  | 72 |  | 
                          |  | 73 | 2. Implement the {{{void process(const Event &event);}}} function. | 
                          |  | 74 |  | 
                          |  | 75 | 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. | 
                          |  | 76 |  | 
                          |  | 77 | 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 | 
                          |  | 78 |  | 
                          |  | 79 |  | 
                          |  | 80 | == Advanced == | 
                          |  | 81 | 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: | 
                          |  | 82 | * {{{KeyMapper::PEV_UP}}} - is the Up Key defined in the config file | 
                          |  | 83 | * {{{KeyMapper::PEV_FIRE1}}} - is the fire button defined in the config file | 
                          |  | 84 | * {{{KeyMapper::PEV_VIEW0}}} - is the view nr zero key | 
                          |  | 85 | * ... | 
                          |  | 86 | 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: | 
                          |  | 87 | {{{ | 
                          |  | 88 | #!c | 
                          |  | 89 | //subscribe this class to the orxonox.conf left | 
                          |  | 90 | EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_LEFT); | 
                          |  | 91 | //subscribe this class to the orxonox.conf right | 
                          |  | 92 | EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_RIGHT); | 
                          |  | 93 | }}} | 
                          |  | 94 |  | 
                          |  | 95 | == References == | 
                          |  | 96 | To see more references, look at some source code files, eg: | 
                          |  | 97 | * {{{./src/world_entities/camera.{cc, h} }}} - the camera can change the view by pressing some keys | 
                          |  | 98 | * {{{./src/world_entities/player.{cc, h} }}} - the player shoots and changes location |