Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/event/event_handler.cc @ 5088

Last change on this file since 5088 was 4873, checked in by bensch, 19 years ago

orxonox/trunk: temporary fix in the EvenetHandler
EVENT_NUMBER is not a maximum value of events, but merely a count of how many differnent kinds of events there are
FIXME

File size: 8.6 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Patrick Boenzli
13   co-programmer:
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_EVENT
17
18#include "event_handler.h"
19
20#include "event_listener.h"
21#include "event.h"
22#include "key_mapper.h"
23
24#include "compiler.h"
25#include "debug.h"
26#include "class_list.h"
27
28using namespace std;
29
30
31/**
32 *  standard constructor
33*/
34EventHandler::EventHandler ()
35{
36  this->setClassID(CL_EVENT_HANDLER, "EventHandler");
37
38  this->listeners = new EventListener**[ES_NUMBER];
39  for(int i = 0; i < ES_NUMBER; ++i)
40    this->listeners[i] = new EventListener*[EV_NUMBER];
41
42  /* now initialize them all to zero */
43  for(int i = 0; i < ES_NUMBER; ++i)
44    {
45      for(int j = 0; j < EV_NUMBER; ++j)
46        {
47          this->listeners[i][j] = NULL;
48        }
49    }
50  this->state = ES_GAME;
51}
52
53
54/**
55 *  the singleton reference to this class
56*/
57EventHandler* EventHandler::singletonRef = NULL;
58
59
60/**
61 *  standard deconstructor
62
63*/
64EventHandler::~EventHandler ()
65{
66  for(int i = 0; i < ES_NUMBER; ++i)
67  {
68    for(int j = 0; j < EV_NUMBER; ++j)
69    {
70      if( this->listeners[i][j] != NULL)
71      {
72        PRINTF(2)("forgot to unsubscribe an EventListener %s!\n");//, this->listeners[i][j]->getName());
73      }
74    }
75  }
76  delete this->keyMapper;
77  EventHandler::singletonRef = NULL;
78}
79
80
81/**
82 *  initializes the event handler
83
84   this has to be called before the use of the event handler
85*/
86void EventHandler::init(IniParser* iniParser)
87{
88  this->keyMapper = new KeyMapper();
89  this->keyMapper->loadKeyBindings(iniParser);
90}
91
92
93/**
94 *  set the state of the event handler
95 * @param state: to which the event handler shall change
96*/
97void EventHandler::setState(elState state)
98{
99  this->state = state;
100}
101
102
103/**
104 *  subscribe to an event
105 * @param el: the event listener that wants to subscribe itself, the listener that will be called when the evetn occures
106 * @param state: for which the listener wants to receive events
107 * @param eventType: the event type that wants to be listened for.
108
109   This is one of the most important function of the EventHandler. If you would like to subscribe for more
110   than one state, you have to subscribe for each state again. If you want to subscribe for all states, use
111   state = ES_ALL, which will subscribe your listener for all states together.
112 *
113 * @todo this can also be done with the & operator, and checking for states, just set the esState to 1,2,4,8, and then 15 is equal to ES_ALL
114*/
115void EventHandler::subscribe(EventListener* el, elState state, int eventType)
116{
117  PRINTF(4)("Subscribing event type: %i\n", eventType);
118  if( state == ES_ALL )
119    {
120      for(int i = 0; i < ES_NUMBER; ++i)
121        if( likely(this->listeners[state][eventType] == NULL))
122          this->listeners[i][eventType] = el;
123        else
124          PRINTF(1)("%s of class %s tried to subscribe to event %i @ state %i but this event has already been subscribed\n", el->getName(), el->getClassName(), eventType, state);
125    }
126  else
127    if( likely(this->listeners[state][eventType] == NULL))
128      {
129        this->listeners[state][eventType] = el;
130      }
131    else
132      PRINTF(1)("% of class %s tried to subscribe to event %i @ state %i but this event has already been subscribed\n", el->getName(), el->getClassName(), eventType, state);
133}
134
135
136/**
137 *  unsubscribe from the EventHandler
138 * @param state: the stat in which it has been subscribed
139 * @param eventType: the event, that shall be unsubscribed
140
141   if you want to unsubscribe an event listener from all subscribed events, just use the
142   unsubscribe(EventListener* el, elState state) function
143*/
144void EventHandler::unsubscribe(elState state, int eventType)
145{
146  PRINTF(4)("Unsubscribing event type nr: %i\n", eventType);
147  this->listeners[state][eventType] = NULL;
148}
149
150
151/**
152 *  unsubscribe all events from a specific listener
153 * @param el: the listener that wants to unsubscribe itself
154 * @param state: the state in which the events shall be unsubscribed
155
156*/
157void EventHandler::unsubscribe(EventListener* el, elState state)
158{
159  if( el == NULL)
160    return;
161  if( state == ES_ALL)
162    {
163      for(int i = 0; i < ES_NUMBER; ++i)
164        {
165          for(int j = 0; j < EV_NUMBER; ++j)
166            {
167              if( this->listeners[i][j] == el )
168                this->listeners[i][j] = NULL;
169            }
170        }
171    }
172  else
173    {
174      for(int j = 0; j < EV_NUMBER; ++j)
175        {
176          if( this->listeners[state][j] == el )
177            this->listeners[state][j] = NULL;
178        }
179    }
180}
181
182
183/**
184 *  flush all registered events
185 * @param state: a specific state
186*/
187void EventHandler::flush(elState state)
188{
189  if( state == ES_ALL)
190    {
191      for(int i = 0; i < ES_NUMBER; ++i)
192        {
193          for(int j = 0; j < EV_NUMBER; ++j)
194            {
195              this->listeners[i][j] = NULL;
196            }
197        }
198    }
199  else
200    {
201      for(int j = 0; j < EV_NUMBER; ++j)
202        {
203          this->listeners[state][j] = NULL;
204        }
205    }
206}
207
208
209/**
210 *  core function of event handler: receives all events from SDL
211
212   The event from the SDL framework are collected here and distributed to all listeners.
213*/
214void EventHandler::process()
215{
216  SDL_Event event;
217  Event ev;
218  EventListener* listener = NULL;
219  while( SDL_PollEvent (&event))
220    {
221      switch( event.type)
222        {
223        case SDL_KEYDOWN:
224          ev.bPressed = true;
225          ev.type = event.key.keysym.sym;
226          break;
227        case SDL_KEYUP:
228          ev.bPressed = false;
229          ev.type = event.key.keysym.sym;
230          break;
231        case SDL_MOUSEMOTION:
232          ev.bPressed = false;
233          ev.type = EV_MOUSE_MOTION;
234          ev.x = event.motion.x;
235          ev.y = event.motion.y;
236          ev.xRel = event.motion.xrel;
237          ev.yRel = event.motion.yrel;
238          break;
239        case SDL_MOUSEBUTTONUP:
240          ev.bPressed = false;
241          ev.type = event.button.button + SDLK_LAST;
242          break;
243        case SDL_MOUSEBUTTONDOWN:
244          ev.bPressed = true;
245          ev.type = event.button.button + SDLK_LAST;
246          break;
247        case SDL_JOYAXISMOTION:
248          ev.bPressed = false;
249          ev.type = EV_JOY_AXIS_MOTION;
250          break;
251        case SDL_JOYBALLMOTION:
252          ev.bPressed = false;
253          ev.type = EV_JOY_BALL_MOTION;
254          break;
255        case SDL_JOYHATMOTION:
256          ev.bPressed = false;
257          ev.type = EV_JOY_HAT_MOTION;
258          break;
259        case SDL_JOYBUTTONDOWN:
260          ev.bPressed = true;
261          ev.type = EV_JOY_BUTTON;
262          break;
263        case SDL_JOYBUTTONUP:
264          ev.bPressed = true;
265          ev.type = EV_JOY_BUTTON;
266          break;
267        case SDL_VIDEORESIZE:
268          ev.resize = event.resize;
269          ev.type = EV_VIDEO_RESIZE;
270          break;
271        default:
272          ev.type = EV_UNKNOWN;
273          break;
274        }
275
276      /* small debug routine: shows all events dispatched by the event handler */
277      PRINT(4)("\n==========================| EventHandler::process () |===\n");
278      PRINT(4)("=  Got Event nr %i, for state %i", ev.type, this->state);
279
280      //! @todo fix this debug code away */
281      ////////////////////////////////////////////////////////////////
282      listener = this->listeners[this->state][ev.type];
283      if (!ClassList::exists(listener, CL_EVENT_LISTENER) && listener != NULL)
284      {
285        ClassList::debug(3, CL_EVENT_LISTENER);
286        this->debug();
287        printf("ERROR THIS EVENT DOES NOT EXIST\n");
288        return;
289      }
290      ////////////////////////////////////////////////////////////////
291      if( listener != NULL)
292        {
293          PRINT(4)("=  Event dispatcher msg: This event has been consumed\n");
294          PRINT(4)("=======================================================\n");
295          listener->process(ev);
296        }
297      else
298        {
299          PRINT(4)("=  Event dispatcher msg: This event has NOT been consumed\n");
300          PRINT(4)("=======================================================\n");
301        }
302    }
303}
304
305
306void EventHandler::debug() const
307{
308  PRINT(0)("===============================\n");
309  PRINT(0)(" EventHandle Debug Information \n");
310  PRINT(0)("===============================\n");
311  for(int i = 0; i < ES_NUMBER; ++i)
312  {
313    for(int j = 0; j < EV_NUMBER; ++j)
314    {
315      if( this->listeners[i][j] != NULL)
316      {
317        PRINT(0)("Event %d of State %d subscribed to %s (%p)\n", j, i, this->listeners[i][j]->getName(), this->listeners[i][j]);
318      }
319    }
320  }
321  PRINT(0)("============================EH=\n");
322}
Note: See TracBrowser for help on using the repository browser.