Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7164 was 7164, checked in by bensch, 18 years ago

deleted unused stuff

File size: 9.7 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  this->flush(ES_ALL);
46  this->withUNICODE(false);
47  this->grabEvents(false);
48
49  this->state = ES_GAME;
50  this->keyMapper = NULL;
51  this->eventsGrabbed = false;
52}
53
54
55/**
56 *  the singleton reference to this class
57*/
58EventHandler* EventHandler::singletonRef = NULL;
59
60
61/**
62 *  standard deconstructor
63
64*/
65EventHandler::~EventHandler ()
66{
67  for(int i = 0; i < ES_NUMBER; ++i)
68  {
69    for(int j = 0; j < EV_NUMBER; ++j)
70    {
71      if( this->listeners[i][j] != NULL)
72      {
73        PRINTF(2)("forgot to unsubscribe an EventListener!\n");// %s!\n", this->listeners[i][j]->getName());
74      }
75    }
76  }
77  delete this->keyMapper;
78
79  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
80
81  EventHandler::singletonRef = NULL;
82}
83
84
85/**
86 *  initializes the event handler
87 *
88 * this has to be called before the use of the event handler
89*/
90void EventHandler::init(IniParser* iniParser)
91{
92  if (this->keyMapper == NULL)
93  {
94    this->keyMapper = new KeyMapper();
95    this->keyMapper->loadKeyBindings(iniParser);
96  }
97}
98
99/**
100 * pushes the current State in the State-stack, and selects state
101 * @param state the new State to set
102 */
103void EventHandler::pushState(elState state)
104{
105  if (likely(state != ES_NULL && state != ES_ALL ))
106  {
107    this->stateStack.push(this->state);
108    this->setState(state);
109  }
110  else
111  {
112    PRINTF(2)("unable to push State\n");
113  }
114}
115
116/**
117 * this removes the topmost stack-entry and select the underlying one
118 * @returns the next stack-entry
119 */
120elState EventHandler::popState()
121{
122  elState state =  (elState)stateStack.top();
123  this->stateStack.pop();
124  if (state == ES_NULL)
125  {
126    PRINTF(2)("No more states availiable. (unable to pop state)\n");
127    return ES_NULL;
128  }
129  else
130  {
131    this->setState(state);
132    return state;
133  }
134}
135
136
137/**
138 *  subscribe to an event
139 * @param el: the event listener that wants to subscribe itself, the listener that will be called when the evetn occures
140 * @param state: for which the listener wants to receive events
141 * @param eventType: the event type that wants to be listened for.
142
143   This is one of the most important function of the EventHandler. If you would like to subscribe for more
144   than one state, you have to subscribe for each state again. If you want to subscribe for all states, use
145   state = ES_ALL, which will subscribe your listener for all states together.
146 */
147void EventHandler::subscribe(EventListener* el, elState state, int eventType)
148{
149  PRINTF(4)("Subscribing event type: %i\n", eventType);
150  if( state == ES_ALL )
151  {
152    for(unsigned int i = 0; i < ES_NUMBER; i++)
153      if( likely(this->listeners[i][eventType] == NULL))
154        this->listeners[i][eventType] = el;
155      else
156        PRINTF(2)("%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);
157  }
158  else
159    if( likely(this->listeners[state][eventType] == NULL))
160    {
161      this->listeners[state][eventType] = el;
162    }
163    else
164      PRINTF(2)("% 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);
165}
166
167
168/**
169 *  unsubscribe from the EventHandler
170 * @param state: the stat in which it has been subscribed
171 * @param eventType: the event, that shall be unsubscribed
172
173   if you want to unsubscribe an event listener from all subscribed events, just use the
174   unsubscribe(EventListener* el, elState state) function
175*/
176void EventHandler::unsubscribe(elState state, int eventType)
177{
178  PRINTF(4)("Unsubscribing event type nr: %i\n", eventType);
179  if (state == ES_ALL)
180    for (unsigned int i = 0; i < ES_NUMBER; i++)
181      this->listeners[i][eventType] = NULL;
182  else
183    this->listeners[state][eventType] = NULL;
184}
185
186
187/**
188 * unsubscribe all events from a specific listener
189 * @param el: the listener that wants to unsubscribe itself
190 * @param state: the state in which the events shall be unsubscribed
191
192*/
193void EventHandler::unsubscribe(EventListener* el, elState state)
194{
195  if( el == NULL || state >= ES_NUMBER)
196    return;
197  if( state == ES_ALL)
198  {
199    for(unsigned int i = 0; i < ES_NUMBER; i++)
200    {
201      for(unsigned int j = 0; j < EV_NUMBER; j++)
202      {
203        if( this->listeners[i][j] == el )
204          this->listeners[i][j] = NULL;
205      }
206    }
207  }
208  else
209  {
210    for(int j = 0; j < EV_NUMBER; j++)
211    {
212      if( this->listeners[state][j] == el )
213        this->listeners[state][j] = NULL;
214    }
215  }
216}
217
218
219/**
220 * flush all registered events
221 * @param state: a specific state
222*/
223void EventHandler::flush(elState state)
224{
225  if( state == ES_ALL)
226  {
227    for(int i = 0; i < ES_NUMBER; ++i)
228    {
229      for(int j = 0; j < EV_NUMBER; ++j)
230      {
231        this->listeners[i][j] = NULL;
232      }
233    }
234  }
235  else
236  {
237    for(int j = 0; j < EV_NUMBER; ++j)
238    {
239      this->listeners[state][j] = NULL;
240    }
241  }
242}
243
244
245void EventHandler::withUNICODE(bool enableUNICODE)
246{
247  SDL_EnableUNICODE(enableUNICODE);
248  this->bUNICODE = enableUNICODE;
249}
250
251void EventHandler::grabEvents(bool grabEvents)
252{
253  this->eventsGrabbed = grabEvents;
254  if(!grabEvents)
255  {
256    SDL_ShowCursor(SDL_ENABLE);
257    SDL_WM_GrabInput(SDL_GRAB_OFF);
258  }
259  else
260  {
261    SDL_WM_GrabInput(SDL_GRAB_ON);
262    SDL_ShowCursor(SDL_DISABLE);
263  }
264}
265
266/**
267 *  core function of event handler: receives all events from SDL
268
269   The event from the SDL framework are collected here and distributed to all listeners.
270*/
271void EventHandler::process()
272{
273  SDL_Event event;
274  Event ev;
275  EventListener* listener = NULL;
276  while( SDL_PollEvent (&event))
277  {
278    switch( event.type)
279    {
280      case SDL_KEYDOWN:
281        ev.bPressed = true;
282        ev.type = event.key.keysym.sym;
283        if (unlikely(this->bUNICODE))
284          ev.x = event.key.keysym.unicode;
285        break;
286      case SDL_KEYUP:
287        ev.bPressed = false;
288        ev.type = event.key.keysym.sym;
289        if (unlikely(this->bUNICODE))
290          ev.x = event.key.keysym.unicode;
291        break;
292      case SDL_MOUSEMOTION:
293        ev.bPressed = false;
294        ev.type = EV_MOUSE_MOTION;
295        ev.x = event.motion.x;
296        ev.y = event.motion.y;
297        ev.xRel = event.motion.xrel;
298        ev.yRel = event.motion.yrel;
299        break;
300      case SDL_MOUSEBUTTONUP:
301        ev.bPressed = false;
302        ev.type = event.button.button + SDLK_LAST;
303        break;
304      case SDL_MOUSEBUTTONDOWN:
305        ev.bPressed = true;
306        ev.type = event.button.button + SDLK_LAST;
307        break;
308      case SDL_JOYAXISMOTION:
309        ev.bPressed = false;
310        ev.type = EV_JOY_AXIS_MOTION;
311        break;
312      case SDL_JOYBALLMOTION:
313        ev.bPressed = false;
314        ev.type = EV_JOY_BALL_MOTION;
315        break;
316      case SDL_JOYHATMOTION:
317        ev.bPressed = false;
318        ev.type = EV_JOY_HAT_MOTION;
319        break;
320      case SDL_JOYBUTTONDOWN:
321        ev.bPressed = true;
322        ev.type = EV_JOY_BUTTON;
323        break;
324      case SDL_JOYBUTTONUP:
325        ev.bPressed = true;
326        ev.type = EV_JOY_BUTTON;
327        break;
328      case SDL_VIDEORESIZE:
329        ev.resize = event.resize;
330        ev.type = EV_VIDEO_RESIZE;
331        break;
332      case SDL_QUIT:
333        ev.type = EV_MAIN_QUIT;
334        break;
335      default:
336        ev.type = EV_UNKNOWN;
337        break;
338    }
339
340    /* small debug routine: shows all events dispatched by the event handler */
341    PRINT(4)("\n==========================| EventHandler::process () |===\n");
342    PRINT(4)("=  Got Event nr %i, for state %i", ev.type, this->state);
343
344    listener = this->listeners[this->state][ev.type];
345    if( listener != NULL)
346    {
347      PRINT(4)("=  Event dispatcher msg: This event has been consumed\n");
348      PRINT(4)("=======================================================\n");
349      listener->process(ev);
350    }
351    else
352    {
353      PRINT(4)("=  Event dispatcher msg: This event has NOT been consumed\n");
354      PRINT(4)("=======================================================\n");
355    }
356  }
357}
358
359
360int EventHandler::eventFilter(const SDL_Event *event)
361{
362  if (likely(EventHandler::getInstance()->eventsGrabbed))
363  {
364    if (event->type == SDL_KEYDOWN &&  event->key.keysym.sym == SDLK_TAB && SDL_GetKeyState(NULL)[SDLK_LALT])
365    {
366      PRINTF(3)("Not sending event to the WindowManager\n");
367      EventHandler::getInstance()->grabEvents(false);
368      return 0;
369    }
370  }
371  else
372  {
373    if (event->type == SDL_MOUSEBUTTONDOWN)
374    {
375      EventHandler::getInstance()->grabEvents( true);
376      return 0;
377    }
378  }
379
380  return 1;
381}
382
383/**
384 * outputs some nice information about the EventHandler
385 */
386void EventHandler::debug() const
387{
388  PRINT(0)("===============================\n");
389  PRINT(0)(" EventHandle Debug Information \n");
390  PRINT(0)("===============================\n");
391  for(int i = 0; i < ES_NUMBER; ++i)
392    for(int j = 0; j < EV_NUMBER; ++j)
393      if( this->listeners[i][j] != NULL)
394        PRINT(0)("Event %d of State %d subscribed to %s (%p)\n", j, i, this->listeners[i][j]->getName(), this->listeners[i][j]);
395  PRINT(0)("============================EH=\n");
396}
Note: See TracBrowser for help on using the repository browser.