Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: other minor valgrid found error-fixes

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