Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: implemented an EventFilter, that should filter alt-TAB

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