Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5474 was 5474, checked in by patrick, 19 years ago

orxonox/lib/event: fixed the mouse button bug

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