Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: inputLine is working.

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