Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: todo-list

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  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
47  this->state = ES_GAME;
48  this->keyMapper = NULL;
49}
50
51
52/**
53 *  the singleton reference to this class
54*/
55EventHandler* EventHandler::singletonRef = NULL;
56
57
58/**
59 *  standard deconstructor
60
61*/
62EventHandler::~EventHandler ()
63{
64  for(int i = 0; i < ES_NUMBER; ++i)
65  {
66    for(int j = 0; j < EV_NUMBER; ++j)
67    {
68      if( this->listeners[i][j] != NULL)
69      {
70        PRINTF(2)("forgot to unsubscribe an EventListener!\n");// %s!\n", this->listeners[i][j]->getName());
71      }
72    }
73  }
74  delete this->keyMapper;
75
76  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
77
78  EventHandler::singletonRef = NULL;
79}
80
81
82/**
83 *  initializes the event handler
84 *
85 * this has to be called before the use of the event handler
86*/
87void EventHandler::init(IniParser* iniParser)
88{
89  this->keyMapper = new KeyMapper();
90  this->keyMapper->loadKeyBindings(iniParser);
91}
92
93/**
94 *  subscribe to an event
95 * @param el: the event listener that wants to subscribe itself, the listener that will be called when the evetn occures
96 * @param state: for which the listener wants to receive events
97 * @param eventType: the event type that wants to be listened for.
98
99   This is one of the most important function of the EventHandler. If you would like to subscribe for more
100   than one state, you have to subscribe for each state again. If you want to subscribe for all states, use
101   state = ES_ALL, which will subscribe your listener for all states together.
102 */
103void EventHandler::subscribe(EventListener* el, elState state, int eventType)
104{
105  PRINTF(4)("Subscribing event type: %i\n", eventType);
106  if( state == ES_ALL )
107    {
108      for(unsigned int i = 0; i < ES_NUMBER; i++)
109        if( likely(this->listeners[i][eventType] == NULL))
110          this->listeners[i][eventType] = el;
111        else
112          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);
113    }
114  else
115    if( likely(this->listeners[state][eventType] == NULL))
116      {
117        this->listeners[state][eventType] = el;
118      }
119    else
120      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);
121}
122
123
124/**
125 *  unsubscribe from the EventHandler
126 * @param state: the stat in which it has been subscribed
127 * @param eventType: the event, that shall be unsubscribed
128
129   if you want to unsubscribe an event listener from all subscribed events, just use the
130   unsubscribe(EventListener* el, elState state) function
131*/
132void EventHandler::unsubscribe(elState state, int eventType)
133{
134  PRINTF(4)("Unsubscribing event type nr: %i\n", eventType);
135  if (state == ES_ALL)
136    for (unsigned int i = 0; i < ES_NUMBER; i++)
137      this->listeners[i][eventType] = NULL;
138  else
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 || state >= ES_NUMBER)
152    return;
153  if( state == ES_ALL)
154    {
155      for(unsigned int i = 0; i < ES_NUMBER; i++)
156        {
157          for(unsigned 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      listener = this->listeners[this->state][ev.type];
273      if( listener != NULL)
274        {
275          PRINT(4)("=  Event dispatcher msg: This event has been consumed\n");
276          PRINT(4)("=======================================================\n");
277          listener->process(ev);
278        }
279      else
280        {
281          PRINT(4)("=  Event dispatcher msg: This event has NOT been consumed\n");
282          PRINT(4)("=======================================================\n");
283        }
284    }
285}
286
287
288int EventHandler::eventFilter(const SDL_Event *event)
289{
290  if (event->type == SDL_KEYDOWN &&  event->key.keysym.sym == SDLK_TAB && SDL_GetKeyState(NULL)[SDLK_LALT])
291  {
292    printf("Not sending event to the WindowManager\n");
293    return 0;
294  }
295  return 1;
296}
297
298/**
299 * outputs some nice information about the EventHandler
300 */
301void EventHandler::debug() const
302{
303  PRINT(0)("===============================\n");
304  PRINT(0)(" EventHandle Debug Information \n");
305  PRINT(0)("===============================\n");
306  for(int i = 0; i < ES_NUMBER; ++i)
307    for(int j = 0; j < EV_NUMBER; ++j)
308      if( this->listeners[i][j] != NULL)
309        PRINT(0)("Event %d of State %d subscribed to %s (%p)\n", j, i, this->listeners[i][j]->getName(), this->listeners[i][j]);
310  PRINT(0)("============================EH=\n");
311}
Note: See TracBrowser for help on using the repository browser.