comparison engine/core/eventchannel/eventmanager.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children e84dccee1bb7
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /***************************************************************************
2 * Copyright (C) 2005-2008 by the FIFE team *
3 * http://www.fifengine.de *
4 * This file is part of FIFE. *
5 * *
6 * FIFE 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 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 // Standard C++ library includes
23 #include <iostream>
24
25 // 3rd party library includes
26
27 // FIFE includes
28 // These includes are split up in two parts, separated by one empty line
29 // First block: files included from the FIFE root src directory
30 // Second block: files included from the same folder
31 #include "util/base/exception.h"
32 #include "eventchannel/key/ec_key.h"
33 #include "eventchannel/key/ec_keyevent.h"
34 #include "eventchannel/mouse/ec_mouseevent.h"
35 #include "eventchannel/widget/ec_widgetevent.h"
36 #include "eventchannel/command/ec_command.h"
37 #include "eventchannel/trigger/ec_trigger.h"
38
39 #include "eventmanager.h"
40
41 namespace FIFE {
42
43 EventManager::EventManager():
44 m_commandlisteners(),
45 m_keylisteners(),
46 m_mouselisteners(),
47 m_sdleventlisteners(),
48 m_widgetlisteners(),
49 m_pending_widgetlisteners(),
50 m_nonconsumablekeys(),
51 m_keystatemap(),
52 m_mousestate(0),
53 m_mostrecentbtn(MouseEvent::EMPTY)
54 {
55 }
56
57 EventManager::~EventManager() {
58 }
59
60 void EventManager::fillMouseEvent(const SDL_Event& sdlevt, MouseEvent& mouseevt) {
61 mouseevt.setX(sdlevt.button.x);
62 mouseevt.setY(sdlevt.button.y);
63 mouseevt.setButton(MouseEvent::EMPTY);
64 mouseevt.setType(MouseEvent::MOVED);
65 if ((sdlevt.type == SDL_MOUSEBUTTONUP) || (sdlevt.type == SDL_MOUSEBUTTONDOWN)) {
66 switch (sdlevt.button.button) {
67 case SDL_BUTTON_LEFT:
68 mouseevt.setButton(MouseEvent::LEFT);
69 break;
70 case SDL_BUTTON_RIGHT:
71 mouseevt.setButton(MouseEvent::RIGHT);
72 break;
73 case SDL_BUTTON_MIDDLE:
74 mouseevt.setButton(MouseEvent::MIDDLE);
75 break;
76 default:
77 mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON);
78 break;
79 }
80
81
82 if (sdlevt.type == SDL_MOUSEBUTTONUP ) {
83
84 mouseevt.setType(MouseEvent::RELEASED);
85
86 } else {
87 mouseevt.setType(MouseEvent::PRESSED);
88 }
89
90 switch (sdlevt.button.button) {
91 case SDL_BUTTON_WHEELDOWN:
92 mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN);
93 break;
94 case SDL_BUTTON_WHEELUP:
95 mouseevt.setType(MouseEvent::WHEEL_MOVED_UP);
96 break;
97 default:
98 break;
99 }
100 }
101 if ((mouseevt.getType() == MouseEvent::MOVED) && m_mousestate) {
102 mouseevt.setType(MouseEvent::DRAGGED);
103 mouseevt.setButton(m_mostrecentbtn);
104 }
105 }
106
107 void EventManager::fillKeyEvent(const SDL_Event& sdlevt, KeyEvent& keyevt) {
108 if (sdlevt.type == SDL_KEYDOWN) {
109 keyevt.setType(KeyEvent::PRESSED);
110 } else if (sdlevt.type == SDL_KEYUP) {
111 keyevt.setType(KeyEvent::RELEASED);
112 } else {
113 throw EventException("Invalid event type in fillKeyEvent");
114 }
115 keyevt.setShiftPressed(sdlevt.key.keysym.mod & KMOD_SHIFT);
116 keyevt.setControlPressed(sdlevt.key.keysym.mod & KMOD_CTRL);
117 keyevt.setAltPressed(sdlevt.key.keysym.mod & KMOD_ALT);
118 keyevt.setMetaPressed(sdlevt.key.keysym.mod & KMOD_META);
119 keyevt.setNumericPad(sdlevt.key.keysym.sym >= SDLK_KP0
120 && sdlevt.key.keysym.sym <= SDLK_KP_EQUALS);
121
122 SDL_keysym keysym = sdlevt.key.keysym;
123 Key::KeyType value = Key::INVALID_KEY;
124 std::string repr("");
125
126 if (keysym.unicode < 255) {
127 value = static_cast<Key::KeyType>(keysym.unicode);
128 repr.push_back(value);
129 }
130
131 #define MAP_KEY(_orig, _new) case _orig: value = _new; repr = #_new; break;
132 switch (keysym.sym) {
133 MAP_KEY(SDLK_TAB, Key::TAB);
134 MAP_KEY(SDLK_LALT, Key::LEFT_ALT);
135 MAP_KEY(SDLK_RALT, Key::RIGHT_ALT);
136 MAP_KEY(SDLK_LSHIFT, Key::LEFT_SHIFT);
137 MAP_KEY(SDLK_RSHIFT, Key::RIGHT_SHIFT);
138 MAP_KEY(SDLK_LCTRL, Key::LEFT_CONTROL);
139 MAP_KEY(SDLK_RCTRL, Key::RIGHT_CONTROL);
140 MAP_KEY(SDLK_BACKSPACE, Key::BACKSPACE);
141 MAP_KEY(SDLK_PAUSE, Key::PAUSE);
142 MAP_KEY(SDLK_ESCAPE, Key::ESCAPE);
143 MAP_KEY(SDLK_DELETE, Key::DELETE_KEY);
144 MAP_KEY(SDLK_INSERT, Key::INSERT);
145 MAP_KEY(SDLK_HOME, Key::HOME);
146 MAP_KEY(SDLK_END, Key::END);
147 MAP_KEY(SDLK_PAGEUP, Key::PAGE_UP);
148 MAP_KEY(SDLK_PRINT, Key::PRINT_SCREEN);
149 MAP_KEY(SDLK_PAGEDOWN, Key::PAGE_DOWN);
150 MAP_KEY(SDLK_F1, Key::F1);
151 MAP_KEY(SDLK_F2, Key::F2);
152 MAP_KEY(SDLK_F3, Key::F3);
153 MAP_KEY(SDLK_F4, Key::F4);
154 MAP_KEY(SDLK_F5, Key::F5);
155 MAP_KEY(SDLK_F6, Key::F6);
156 MAP_KEY(SDLK_F7, Key::F7);
157 MAP_KEY(SDLK_F8, Key::F8);
158 MAP_KEY(SDLK_F9, Key::F9);
159 MAP_KEY(SDLK_F10, Key::F10);
160 MAP_KEY(SDLK_F11, Key::F11);
161 MAP_KEY(SDLK_F12, Key::F12);
162 MAP_KEY(SDLK_F13, Key::F13);
163 MAP_KEY(SDLK_F14, Key::F14);
164 MAP_KEY(SDLK_F15, Key::F15);
165 MAP_KEY(SDLK_NUMLOCK, Key::NUM_LOCK);
166 MAP_KEY(SDLK_CAPSLOCK, Key::CAPS_LOCK);
167 MAP_KEY(SDLK_SCROLLOCK, Key::SCROLL_LOCK);
168 MAP_KEY(SDLK_RMETA, Key::RIGHT_META);
169 MAP_KEY(SDLK_LMETA, Key::LEFT_META);
170 MAP_KEY(SDLK_LSUPER, Key::LEFT_SUPER);
171 MAP_KEY(SDLK_RSUPER, Key::RIGHT_SUPER);
172 MAP_KEY(SDLK_MODE, Key::ALT_GR);
173 MAP_KEY(SDLK_UP, Key::UP);
174 MAP_KEY(SDLK_DOWN, Key::DOWN);
175 MAP_KEY(SDLK_LEFT, Key::LEFT);
176 MAP_KEY(SDLK_RIGHT, Key::RIGHT);
177 MAP_KEY(SDLK_RETURN, Key::ENTER);
178 MAP_KEY(SDLK_KP_ENTER, Key::ENTER);
179 case SDLK_SPACE:
180 // Special characters like ~ (tilde) ends up with the keysym.sym SDLK_SPACE which
181 // without this check would be lost. The check is only valid on key down events in SDL.
182 if (sdlevt.type == SDL_KEYUP || keysym.unicode == ' ') {
183 value = Key::SPACE;
184 }
185 break;
186 default:
187 break;
188 }
189
190 if (!(keysym.mod & KMOD_NUM)) {
191 switch (keysym.sym) {
192 MAP_KEY(SDLK_KP0, Key::INSERT);
193 MAP_KEY(SDLK_KP1, Key::END);
194 MAP_KEY(SDLK_KP2, Key::DOWN);
195 MAP_KEY(SDLK_KP3, Key::PAGE_DOWN);
196 MAP_KEY(SDLK_KP4, Key::LEFT);
197 MAP_KEY(SDLK_KP5, Key::INVALID_KEY);
198 MAP_KEY(SDLK_KP6, Key::RIGHT);
199 MAP_KEY(SDLK_KP7, Key::HOME);
200 MAP_KEY(SDLK_KP8, Key::UP);
201 MAP_KEY(SDLK_KP9, Key::PAGE_UP);
202 default:
203 break;
204 }
205 }
206
207 keyevt.setKey(Key(value, repr));
208 }
209
210 template<typename T>
211 void removeListener(std::vector<T>& vec, T& listener) {
212 vec.push_back(listener);
213 }
214
215 template<typename T>
216 void addListener(std::vector<T>& vec, T& listener) {
217 vec.push_back(listener);
218 }
219
220 void EventManager::addCommandListener(ICommandListener* listener) {
221 addListener<ICommandListener*>(m_pending_commandlisteners, listener);
222 }
223
224 void EventManager::removeCommandListener(ICommandListener* listener) {
225 removeListener<ICommandListener*>(m_pending_cldeletions, listener);
226 }
227
228 void EventManager::addKeyListener(IKeyListener* listener) {
229 addListener<IKeyListener*>(m_pending_keylisteners, listener);
230 }
231
232 void EventManager::removeKeyListener(IKeyListener* listener) {
233 removeListener<IKeyListener*>(m_pending_kldeletions, listener);
234 }
235
236 void EventManager::addMouseListener(IMouseListener* listener) {
237 addListener<IMouseListener*>(m_pending_mouselisteners, listener);
238 }
239
240 void EventManager::removeMouseListener(IMouseListener* listener) {
241 removeListener<IMouseListener*>(m_pending_mldeletions, listener);
242 }
243
244 void EventManager::addSdlEventListener(ISdlEventListener* listener) {
245 addListener<ISdlEventListener*>(m_pending_sdleventlisteners, listener);
246 }
247
248 void EventManager::removeSdlEventListener(ISdlEventListener* listener) {
249 removeListener<ISdlEventListener*>(m_pending_sdldeletions, listener);
250 }
251
252 void EventManager::addWidgetListener(IWidgetListener* listener) {
253 addListener<IWidgetListener*>(m_pending_widgetlisteners, listener);
254 }
255
256 void EventManager::removeWidgetListener(IWidgetListener* listener) {
257 removeListener<IWidgetListener*>(m_pending_wldeletions, listener);
258 }
259
260 void EventManager::dispatchCommand(Command& command) {
261 if(!m_pending_commandlisteners.empty()) {
262 std::vector<ICommandListener*>::iterator i = m_pending_commandlisteners.begin();
263 while (i != m_pending_commandlisteners.end()) {
264 m_commandlisteners.push_back(*i);
265 ++i;
266 }
267 m_pending_commandlisteners.clear();
268 }
269
270 if (!m_pending_cldeletions.empty()) {
271 std::vector<ICommandListener*>::iterator i = m_pending_cldeletions.begin();
272 while (i != m_pending_cldeletions.end()) {
273 std::vector<ICommandListener*>::iterator j = m_commandlisteners.begin();
274 while (j != m_commandlisteners.end()) {
275 if(*j == *i) {
276 m_commandlisteners.erase(j);
277 break;
278 }
279 ++j;
280 }
281 ++i;
282 }
283 m_pending_cldeletions.clear();
284 }
285
286 std::vector<ICommandListener*>::iterator i = m_commandlisteners.begin();
287 while (i != m_commandlisteners.end()) {
288 (*i)->onCommand(command);
289 if (command.isConsumed()) {
290 break;
291 }
292 ++i;
293 }
294 }
295
296 void EventManager::dispatchKeyEvent(KeyEvent& evt) {
297 bool nonconsumablekey = false;
298 for (std::vector<int>::iterator it = m_nonconsumablekeys.begin();
299 it != m_nonconsumablekeys.end(); ++it) {
300 if (*it == evt.getKey().getValue()) {
301 nonconsumablekey = true;
302 break;
303 }
304 }
305
306 if(!m_pending_keylisteners.empty()) {
307 std::vector<IKeyListener*>::iterator i = m_pending_keylisteners.begin();
308 while (i != m_pending_keylisteners.end()) {
309 m_keylisteners.push_back(*i);
310 ++i;
311 }
312 m_pending_keylisteners.clear();
313 }
314
315 if (!m_pending_kldeletions.empty()) {
316 std::vector<IKeyListener*>::iterator i = m_pending_kldeletions.begin();
317 while (i != m_pending_kldeletions.end()) {
318 std::vector<IKeyListener*>::iterator j = m_keylisteners.begin();
319 while (j != m_keylisteners.end()) {
320 if(*j == *i) {
321 m_keylisteners.erase(j);
322 break;
323 }
324 ++j;
325 }
326 ++i;
327 }
328 m_pending_kldeletions.clear();
329 }
330
331 std::vector<IKeyListener*>::iterator i = m_keylisteners.begin();
332 while (i != m_keylisteners.end()) {
333 switch (evt.getType()) {
334 case KeyEvent::PRESSED:
335 (*i)->keyPressed(evt);
336 break;
337 case KeyEvent::RELEASED:
338 (*i)->keyReleased(evt);
339 break;
340 default:
341 break;
342 }
343 if ((!nonconsumablekey) && (evt.isConsumed())) {
344 break;
345 }
346 ++i;
347 }
348 }
349
350 void EventManager::fillModifiers(InputEvent& evt) {
351 evt.setAltPressed(m_keystatemap[Key::ALT_GR] |
352 m_keystatemap[Key::LEFT_ALT] |
353 m_keystatemap[Key::RIGHT_ALT]);
354 evt.setControlPressed(m_keystatemap[Key::LEFT_CONTROL] |
355 m_keystatemap[Key::RIGHT_CONTROL]);
356 evt.setMetaPressed(m_keystatemap[Key::LEFT_META] |
357 m_keystatemap[Key::RIGHT_META]);
358 evt.setShiftPressed(m_keystatemap[Key::LEFT_SHIFT] |
359 m_keystatemap[Key::RIGHT_SHIFT]);
360 }
361
362 void EventManager::dispatchMouseEvent(MouseEvent& evt) {
363 if(!m_pending_mouselisteners.empty()) {
364 std::vector<IMouseListener*>::iterator i = m_pending_mouselisteners.begin();
365 while (i != m_pending_mouselisteners.end()) {
366 m_mouselisteners.push_back(*i);
367 ++i;
368 }
369 m_pending_mouselisteners.clear();
370 }
371
372 if (!m_pending_mldeletions.empty()) {
373 std::vector<IMouseListener*>::iterator i = m_pending_mldeletions.begin();
374 while (i != m_pending_mldeletions.end()) {
375 std::vector<IMouseListener*>::iterator j = m_mouselisteners.begin();
376 while (j != m_mouselisteners.end()) {
377 if(*j == *i) {
378 m_mouselisteners.erase(j);
379 break;
380 }
381 ++j;
382 }
383 ++i;
384 }
385 m_pending_mldeletions.clear();
386 }
387
388 std::vector<IMouseListener*>::iterator i = m_mouselisteners.begin();
389 while (i != m_mouselisteners.end()) {
390 switch (evt.getType()) {
391 case MouseEvent::MOVED:
392 (*i)->mouseMoved(evt);
393 break;
394 case MouseEvent::PRESSED:
395 (*i)->mousePressed(evt);
396 break;
397 case MouseEvent::RELEASED:
398 (*i)->mouseReleased(evt);
399 break;
400 case MouseEvent::WHEEL_MOVED_DOWN:
401 (*i)->mouseWheelMovedDown(evt);
402 break;
403 case MouseEvent::WHEEL_MOVED_UP:
404 (*i)->mouseWheelMovedUp(evt);
405 break;
406 case MouseEvent::CLICKED:
407 (*i)->mouseClicked(evt);
408 break;
409 case MouseEvent::ENTERED:
410 (*i)->mouseEntered(evt);
411 case MouseEvent::EXITED:
412 (*i)->mouseExited(evt);
413 break;
414 case MouseEvent::DRAGGED:
415 (*i)->mouseDragged(evt);
416 break;
417 default:
418 break;
419 }
420 if (evt.isConsumed()) {
421 break;
422 }
423 ++i;
424 }
425 }
426
427 void EventManager::dispatchSdlEvent(SDL_Event& evt) {
428 if (!m_pending_sdleventlisteners.empty()) {
429 std::vector<ISdlEventListener*>::iterator i = m_pending_sdleventlisteners.begin();
430 while(i != m_pending_sdleventlisteners.end()) {
431 m_sdleventlisteners.push_back(*i);
432 ++i;
433 }
434 m_pending_sdleventlisteners.clear();
435 }
436
437 if (!m_pending_sdldeletions.empty()) {
438 std::vector<ISdlEventListener*>::iterator i = m_pending_sdldeletions.begin();
439 while (i != m_pending_sdldeletions.end()) {
440 std::vector<ISdlEventListener*>::iterator j = m_sdleventlisteners.begin();
441 while (j != m_sdleventlisteners.end()) {
442 if(*j == *i) {
443 m_sdleventlisteners.erase(j);
444 break;
445 }
446 ++j;
447 }
448 ++i;
449 }
450 m_pending_sdldeletions.clear();
451 }
452
453 std::vector<ISdlEventListener*>::iterator i = m_sdleventlisteners.begin();
454 while (i != m_sdleventlisteners.end()) {
455 (*i)->onSdlEvent(evt);
456 ++i;
457 }
458 }
459
460 void EventManager::dispatchWidgetEvent(WidgetEvent& evt) {
461 if(!m_pending_widgetlisteners.empty()) {
462 std::vector<IWidgetListener*>::iterator i = m_pending_widgetlisteners.begin();
463 while (i != m_pending_widgetlisteners.end()) {
464 m_widgetlisteners.push_back(*i);
465 ++i;
466 }
467 m_pending_widgetlisteners.clear();
468 }
469
470 if (!m_pending_wldeletions.empty()) {
471 std::vector<IWidgetListener*>::iterator i = m_pending_wldeletions.begin();
472 while (i != m_pending_wldeletions.end()) {
473 std::vector<IWidgetListener*>::iterator j = m_widgetlisteners.begin();
474 while (j != m_widgetlisteners.end()) {
475 if(*j == *i) {
476 m_widgetlisteners.erase(j);
477 break;
478 }
479 ++j;
480 }
481 ++i;
482 }
483 m_pending_wldeletions.clear();
484 }
485
486 std::vector<IWidgetListener*>::iterator i = m_widgetlisteners.begin();
487 while (i != m_widgetlisteners.end()) {
488 (*i)->onWidgetAction(evt);
489 if (evt.isConsumed()) {
490 break;
491 }
492 ++i;
493 }
494 }
495
496 void EventManager::onWidgetAction(WidgetEvent& evt) {
497 dispatchWidgetEvent(evt);
498 }
499
500 void EventManager::processEvents(){
501 SDL_Event event;
502 while (SDL_PollEvent(&event)) {
503 dispatchSdlEvent(event);
504 switch (event.type) {
505 case SDL_QUIT: {
506 Command cmd;
507 cmd.setSource(this);
508 cmd.setCommandType(CMD_QUIT_GAME);
509 dispatchCommand(cmd);
510 break;
511 }
512 case SDL_ACTIVEEVENT:
513 break;
514 case SDL_KEYDOWN:
515 case SDL_KEYUP: {
516 KeyEvent keyevt;
517 keyevt.setSource(this);
518 fillKeyEvent(event, keyevt);
519 m_keystatemap[keyevt.getKey().getValue()] = (keyevt.getType() == KeyEvent::PRESSED);
520 dispatchKeyEvent(keyevt);
521 }
522 break;
523 case SDL_MOUSEBUTTONUP:
524 case SDL_MOUSEMOTION:
525 case SDL_MOUSEBUTTONDOWN: {
526 MouseEvent mouseevt;
527 mouseevt.setSource(this);
528 fillMouseEvent(event, mouseevt);
529 fillModifiers(mouseevt);
530 if (event.type == SDL_MOUSEBUTTONDOWN) {
531 m_mousestate |= static_cast<int>(mouseevt.getButton());
532 m_mostrecentbtn = mouseevt.getButton();
533 } else if (event.type == SDL_MOUSEBUTTONUP) {
534 m_mousestate &= ~static_cast<int>(mouseevt.getButton());
535 }
536 // fire scrollwheel events only once
537 if (event.button.button == SDL_BUTTON_WHEELDOWN || event.button.button == SDL_BUTTON_WHEELUP) {
538 if (event.type == SDL_MOUSEBUTTONUP) {
539 break;
540 }
541 }
542 dispatchMouseEvent(mouseevt);
543 break;
544 }
545 }
546 }
547
548 pollTriggers();
549 }
550
551 EventSourceType EventManager::getEventSourceType() {
552 return ES_ENGINE;
553 }
554
555 void EventManager::setNonConsumableKeys(const std::vector<int>& keys) {
556 m_nonconsumablekeys = keys;
557 }
558
559 std::vector<int> EventManager::getNonConsumableKeys() {
560 return m_nonconsumablekeys;
561 }
562
563 void EventManager::registerTrigger(Trigger& trigger){
564 m_triggers.push_back(&trigger);
565 }
566
567 void EventManager::unregisterTrigger(Trigger& trigger){
568 m_triggers.remove(&trigger);
569 }
570
571 void EventManager::pollTriggers(){
572 for (std::list<Trigger*>::iterator it = m_triggers.begin(); it!=m_triggers.end(); ++it) {
573 (*it)->pollTrigger();
574 }
575 }
576 }