Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: nicer quit-modi
TextEngine is now deleted by GraphicsEngine
trying to fix errors in the Element2D deletion

File size: 8.8 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  this->setName("EventHandler");
38
39  SDL_InitSubSystem(SDL_INIT_JOYSTICK);
40  SDL_InitSubSystem(SDL_INIT_EVENTTHREAD);
41//  SDL_SetEventFilter(EventHandler::eventFilter);
42
43
44  /* now initialize them all to zero */
45  for(int i = 0; i < ES_NUMBER; i++)
46    {
47      for(int j = 0; j < EV_NUMBER; j++)
48        {
49          this->listeners[i][j] = NULL;
50        }
51    }
52  this->state = ES_GAME;
53  this->keyMapper = NULL;
54}
55
56
57/**
58 *  the singleton reference to this class
59*/
60EventHandler* EventHandler::singletonRef = NULL;
61
62
63/**
64 *  standard deconstructor
65
66*/
67EventHandler::~EventHandler ()
68{
69  for(int i = 0; i < ES_NUMBER; ++i)
70  {
71    for(int j = 0; j < EV_NUMBER; ++j)
72    {
73      if( this->listeners[i][j] != NULL)
74      {
75        PRINTF(2)("forgot to unsubscribe an EventListener!\n");// %s!\n", this->listeners[i][j]->getName());
76      }
77    }
78  }
79  delete this->keyMapper;
80
81  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
82
83  EventHandler::singletonRef = NULL;
84}
85
86
87/**
88 *  initializes the event handler
89 *
90 * this has to be called before the use of the event handler
91*/
92void EventHandler::init(IniParser* iniParser)
93{
94  this->keyMapper = new KeyMapper();
95  this->keyMapper->loadKeyBindings(iniParser);
96}
97
98/**
99 *  subscribe to an event
100 * @param el: the event listener that wants to subscribe itself, the listener that will be called when the evetn occures
101 * @param state: for which the listener wants to receive events
102 * @param eventType: the event type that wants to be listened for.
103
104   This is one of the most important function of the EventHandler. If you would like to subscribe for more
105   than one state, you have to subscribe for each state again. If you want to subscribe for all states, use
106   state = ES_ALL, which will subscribe your listener for all states together.
107 *
108 * @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
109*/
110void EventHandler::subscribe(EventListener* el, elState state, int eventType)
111{
112  PRINTF(4)("Subscribing event type: %i\n", eventType);
113  if( state == ES_ALL )
114    {
115      for(int i = 0; i < ES_NUMBER; ++i)
116        if( likely(this->listeners[state][eventType] == NULL))
117          this->listeners[i][eventType] = el;
118        else
119          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);
120    }
121  else
122    if( likely(this->listeners[state][eventType] == NULL))
123      {
124        this->listeners[state][eventType] = el;
125      }
126    else
127      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);
128}
129
130
131/**
132 *  unsubscribe from the EventHandler
133 * @param state: the stat in which it has been subscribed
134 * @param eventType: the event, that shall be unsubscribed
135
136   if you want to unsubscribe an event listener from all subscribed events, just use the
137   unsubscribe(EventListener* el, elState state) function
138*/
139void EventHandler::unsubscribe(elState state, int eventType)
140{
141  PRINTF(4)("Unsubscribing event type nr: %i\n", eventType);
142  this->listeners[state][eventType] = NULL;
143}
144
145
146/**
147 * unsubscribe all events from a specific listener
148 * @param el: the listener that wants to unsubscribe itself
149 * @param state: the state in which the events shall be unsubscribed
150
151*/
152void EventHandler::unsubscribe(EventListener* el, elState state)
153{
154  if( el == NULL)
155    return;
156  if( state == ES_ALL)
157    {
158      for(int i = 0; i < ES_NUMBER; ++i)
159        {
160          for(int j = 0; j < EV_NUMBER; ++j)
161            {
162              if( this->listeners[i][j] == el )
163                this->listeners[i][j] = NULL;
164            }
165        }
166    }
167  else
168    {
169      for(int j = 0; j < EV_NUMBER; ++j)
170        {
171          if( this->listeners[state][j] == el )
172            this->listeners[state][j] = NULL;
173        }
174    }
175}
176
177
178/**
179 * flush all registered events
180 * @param state: a specific state
181*/
182void EventHandler::flush(elState state)
183{
184  if( state == ES_ALL)
185    {
186      for(int i = 0; i < ES_NUMBER; ++i)
187        {
188          for(int j = 0; j < EV_NUMBER; ++j)
189            {
190              this->listeners[i][j] = NULL;
191            }
192        }
193    }
194  else
195    {
196      for(int j = 0; j < EV_NUMBER; ++j)
197        {
198          this->listeners[state][j] = NULL;
199        }
200    }
201}
202
203
204/**
205 *  core function of event handler: receives all events from SDL
206
207   The event from the SDL framework are collected here and distributed to all listeners.
208*/
209void EventHandler::process()
210{
211  SDL_Event event;
212  Event ev;
213  EventListener* listener = NULL;
214  while( SDL_PollEvent (&event))
215    {
216      switch( event.type)
217        {
218        case SDL_KEYDOWN:
219          ev.bPressed = true;
220          ev.type = event.key.keysym.sym;
221          break;
222        case SDL_KEYUP:
223          ev.bPressed = false;
224          ev.type = event.key.keysym.sym;
225          break;
226        case SDL_MOUSEMOTION:
227          ev.bPressed = false;
228          ev.type = EV_MOUSE_MOTION;
229          ev.x = event.motion.x;
230          ev.y = event.motion.y;
231          ev.xRel = event.motion.xrel;
232          ev.yRel = event.motion.yrel;
233          break;
234        case SDL_MOUSEBUTTONUP:
235          ev.bPressed = false;
236          ev.type = event.button.button + SDLK_LAST;
237          break;
238        case SDL_MOUSEBUTTONDOWN:
239          ev.bPressed = true;
240          ev.type = event.button.button + SDLK_LAST;
241          break;
242        case SDL_JOYAXISMOTION:
243          ev.bPressed = false;
244          ev.type = EV_JOY_AXIS_MOTION;
245          break;
246        case SDL_JOYBALLMOTION:
247          ev.bPressed = false;
248          ev.type = EV_JOY_BALL_MOTION;
249          break;
250        case SDL_JOYHATMOTION:
251          ev.bPressed = false;
252          ev.type = EV_JOY_HAT_MOTION;
253          break;
254        case SDL_JOYBUTTONDOWN:
255          ev.bPressed = true;
256          ev.type = EV_JOY_BUTTON;
257          break;
258        case SDL_JOYBUTTONUP:
259          ev.bPressed = true;
260          ev.type = EV_JOY_BUTTON;
261          break;
262        case SDL_VIDEORESIZE:
263          ev.resize = event.resize;
264          ev.type = EV_VIDEO_RESIZE;
265          break;
266        default:
267          ev.type = EV_UNKNOWN;
268          break;
269        }
270
271      /* small debug routine: shows all events dispatched by the event handler */
272      PRINT(4)("\n==========================| EventHandler::process () |===\n");
273      PRINT(4)("=  Got Event nr %i, for state %i", ev.type, this->state);
274
275      //! @todo fix this debug code away */
276      ////////////////////////////////////////////////////////////////
277      listener = this->listeners[this->state][ev.type];
278      if (!ClassList::exists(listener, CL_EVENT_LISTENER) && listener != NULL)
279      {
280        ClassList::debug(3, CL_EVENT_LISTENER);
281        this->debug();
282        printf("ERROR THIS EVENT DOES NOT EXIST\n");
283        return;
284      }
285      ////////////////////////////////////////////////////////////////
286      if( listener != NULL)
287        {
288          PRINT(4)("=  Event dispatcher msg: This event has been consumed\n");
289          PRINT(4)("=======================================================\n");
290          listener->process(ev);
291        }
292      else
293        {
294          PRINT(4)("=  Event dispatcher msg: This event has NOT been consumed\n");
295          PRINT(4)("=======================================================\n");
296        }
297    }
298}
299
300int EventHandler::eventFilter(const SDL_Event *event)
301{
302  /*
303  if (event->type == SDL_KEYDOWN &&  event->key.keysym.sym == SDLK_TAB && SDL_GetKeyState(NULL)[SDLK_LALT])
304  {
305    printf("test\n");
306
307  }
308  return 1;
309  */
310}
311
312/**
313 * outputs some nice information about the EventHandler
314 */
315void EventHandler::debug() const
316{
317  PRINT(0)("===============================\n");
318  PRINT(0)(" EventHandle Debug Information \n");
319  PRINT(0)("===============================\n");
320  for(int i = 0; i < ES_NUMBER; ++i)
321  {
322    for(int j = 0; j < EV_NUMBER; ++j)
323    {
324      if( this->listeners[i][j] != NULL)
325      {
326        PRINT(0)("Event %d of State %d subscribed to %s (%p)\n", j, i, this->listeners[i][j]->getName(), this->listeners[i][j]);
327      }
328    }
329  }
330  PRINT(0)("============================EH=\n");
331}
Note: See TracBrowser for help on using the repository browser.