Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Element2D added → will be moved to lib/graphics afterwards
ProtoClass update
EventListeners do not have to be unsubscribed externally, but still one listener won't unsubscribe

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