Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Iniparser is passed on to the EvenetHandler over orxonox

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