Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: SDL_EventSystem now has the Threaded EventSystem from SDL

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