eventmanager.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <iostream>
00024
00025
00026
00027
00028
00029
00030
00031 #include "util/base/exception.h"
00032 #include "eventchannel/key/ec_key.h"
00033 #include "eventchannel/key/ec_keyevent.h"
00034 #include "eventchannel/key/ec_ikeyfilter.h"
00035 #include "eventchannel/mouse/ec_mouseevent.h"
00036 #include "eventchannel/command/ec_command.h"
00037
00038 #include "eventmanager.h"
00039
00040 namespace FIFE {
00041
00042 EventManager::EventManager():
00043 m_commandlisteners(),
00044 m_keylisteners(),
00045 m_mouselisteners(),
00046 m_sdleventlisteners(),
00047 m_keystatemap(),
00048 m_keyfilter(0),
00049 m_mousestate(0),
00050 m_mostrecentbtn(MouseEvent::EMPTY)
00051 {
00052 }
00053
00054 EventManager::~EventManager() {
00055 }
00056
00057 template<typename T>
00058 void removeListener(std::deque<T>& vec, T& listener) {
00059 vec.push_back(listener);
00060 }
00061
00062 template<typename T>
00063 void addListener(std::deque<T>& vec, T& listener) {
00064 vec.push_back(listener);
00065 }
00066
00067 void EventManager::addCommandListener(ICommandListener* listener) {
00068 addListener<ICommandListener*>(m_pending_commandlisteners, listener);
00069 }
00070
00071 void EventManager::addCommandListenerFront(ICommandListener* listener) {
00072 addListener<ICommandListener*>(m_pending_commandlisteners, listener);
00073 }
00074
00075 void EventManager::removeCommandListener(ICommandListener* listener) {
00076 removeListener<ICommandListener*>(m_pending_cldeletions, listener);
00077 }
00078
00079 void EventManager::addKeyListener(IKeyListener* listener) {
00080 addListener<IKeyListener*>(m_pending_keylisteners, listener);
00081 }
00082
00083 void EventManager::addKeyListenerFront(IKeyListener* listener) {
00084 addListener<IKeyListener*>(m_pending_keylisteners_front, listener);
00085 }
00086
00087 void EventManager::removeKeyListener(IKeyListener* listener) {
00088 removeListener<IKeyListener*>(m_pending_kldeletions, listener);
00089 }
00090
00091 void EventManager::addMouseListener(IMouseListener* listener) {
00092 addListener<IMouseListener*>(m_pending_mouselisteners, listener);
00093 }
00094
00095 void EventManager::addMouseListenerFront(IMouseListener* listener) {
00096 addListener<IMouseListener*>(m_pending_mouselisteners, listener);
00097 }
00098
00099 void EventManager::removeMouseListener(IMouseListener* listener) {
00100 removeListener<IMouseListener*>(m_pending_mldeletions, listener);
00101 }
00102
00103 void EventManager::addSdlEventListener(ISdlEventListener* listener) {
00104 addListener<ISdlEventListener*>(m_pending_sdleventlisteners, listener);
00105 }
00106
00107 void EventManager::addSdlEventListenerFront(ISdlEventListener* listener) {
00108 addListener<ISdlEventListener*>(m_pending_sdleventlisteners, listener);
00109 }
00110
00111 void EventManager::removeSdlEventListener(ISdlEventListener* listener) {
00112 removeListener<ISdlEventListener*>(m_pending_sdldeletions, listener);
00113 }
00114
00115 void EventManager::dispatchCommand(Command& command) {
00116 if(!m_pending_commandlisteners.empty()) {
00117 std::deque<ICommandListener*>::iterator i = m_pending_commandlisteners.begin();
00118 while (i != m_pending_commandlisteners.end()) {
00119 m_commandlisteners.push_back(*i);
00120 ++i;
00121 }
00122 m_pending_commandlisteners.clear();
00123 }
00124
00125 if(!m_pending_commandlisteners_front.empty()) {
00126 std::deque<ICommandListener*>::iterator i = m_pending_commandlisteners_front.begin();
00127 while (i != m_pending_commandlisteners_front.end()) {
00128 m_commandlisteners.push_front(*i);
00129 ++i;
00130 }
00131 m_pending_commandlisteners_front.clear();
00132 }
00133
00134 if (!m_pending_cldeletions.empty()) {
00135 std::deque<ICommandListener*>::iterator i = m_pending_cldeletions.begin();
00136 while (i != m_pending_cldeletions.end()) {
00137 std::deque<ICommandListener*>::iterator j = m_commandlisteners.begin();
00138 while (j != m_commandlisteners.end()) {
00139 if(*j == *i) {
00140 m_commandlisteners.erase(j);
00141 break;
00142 }
00143 ++j;
00144 }
00145 ++i;
00146 }
00147 m_pending_cldeletions.clear();
00148 }
00149
00150 std::deque<ICommandListener*>::iterator i = m_commandlisteners.begin();
00151 while (i != m_commandlisteners.end()) {
00152 (*i)->onCommand(command);
00153 if (command.isConsumed()) {
00154 break;
00155 }
00156 ++i;
00157 }
00158 }
00159
00160 void EventManager::dispatchKeyEvent(KeyEvent& evt) {
00161 if(!m_pending_keylisteners.empty()) {
00162 std::deque<IKeyListener*>::iterator i = m_pending_keylisteners.begin();
00163 while (i != m_pending_keylisteners.end()) {
00164 m_keylisteners.push_back(*i);
00165 ++i;
00166 }
00167 m_pending_keylisteners.clear();
00168 }
00169
00170 if(!m_pending_keylisteners_front.empty()) {
00171 std::deque<IKeyListener*>::iterator i = m_pending_keylisteners_front.begin();
00172 while (i != m_pending_keylisteners_front.end()) {
00173 m_keylisteners.push_front(*i);
00174 ++i;
00175 }
00176 m_pending_keylisteners_front.clear();
00177 }
00178
00179 if (!m_pending_kldeletions.empty()) {
00180 std::deque<IKeyListener*>::iterator i = m_pending_kldeletions.begin();
00181 while (i != m_pending_kldeletions.end()) {
00182 std::deque<IKeyListener*>::iterator j = m_keylisteners.begin();
00183 while (j != m_keylisteners.end()) {
00184 if(*j == *i) {
00185 m_keylisteners.erase(j);
00186 break;
00187 }
00188 ++j;
00189 }
00190 ++i;
00191 }
00192 m_pending_kldeletions.clear();
00193 }
00194
00195 std::deque<IKeyListener*>::iterator i = m_keylisteners.begin();
00196 while (i != m_keylisteners.end()) {
00197 switch (evt.getType()) {
00198 case KeyEvent::PRESSED:
00199 (*i)->keyPressed(evt);
00200 break;
00201 case KeyEvent::RELEASED:
00202 (*i)->keyReleased(evt);
00203 break;
00204 default:
00205 break;
00206 }
00207 ++i;
00208 }
00209 }
00210
00211 void EventManager::dispatchMouseEvent(MouseEvent& evt) {
00212 if(!m_pending_mouselisteners.empty()) {
00213 std::deque<IMouseListener*>::iterator i = m_pending_mouselisteners.begin();
00214 while (i != m_pending_mouselisteners.end()) {
00215 m_mouselisteners.push_back(*i);
00216 ++i;
00217 }
00218 m_pending_mouselisteners.clear();
00219 }
00220
00221 if(!m_pending_mouselisteners_front.empty()) {
00222 std::deque<IMouseListener*>::iterator i = m_pending_mouselisteners_front.begin();
00223 while (i != m_pending_mouselisteners_front.end()) {
00224 m_mouselisteners.push_front(*i);
00225 ++i;
00226 }
00227 m_pending_mouselisteners_front.clear();
00228 }
00229
00230 if (!m_pending_mldeletions.empty()) {
00231 std::deque<IMouseListener*>::iterator i = m_pending_mldeletions.begin();
00232 while (i != m_pending_mldeletions.end()) {
00233 std::deque<IMouseListener*>::iterator j = m_mouselisteners.begin();
00234 while (j != m_mouselisteners.end()) {
00235 if(*j == *i) {
00236 m_mouselisteners.erase(j);
00237 break;
00238 }
00239 ++j;
00240 }
00241 ++i;
00242 }
00243 m_pending_mldeletions.clear();
00244 }
00245
00246 std::deque<IMouseListener*>::iterator i = m_mouselisteners.begin();
00247 while (i != m_mouselisteners.end()) {
00248 switch (evt.getType()) {
00249 case MouseEvent::MOVED:
00250 (*i)->mouseMoved(evt);
00251 break;
00252 case MouseEvent::PRESSED:
00253 (*i)->mousePressed(evt);
00254 break;
00255 case MouseEvent::RELEASED:
00256 (*i)->mouseReleased(evt);
00257 break;
00258 case MouseEvent::WHEEL_MOVED_DOWN:
00259 (*i)->mouseWheelMovedDown(evt);
00260 break;
00261 case MouseEvent::WHEEL_MOVED_UP:
00262 (*i)->mouseWheelMovedUp(evt);
00263 break;
00264 case MouseEvent::CLICKED:
00265 (*i)->mouseClicked(evt);
00266 break;
00267 case MouseEvent::ENTERED:
00268 (*i)->mouseEntered(evt);
00269 break;
00270 case MouseEvent::EXITED:
00271 (*i)->mouseExited(evt);
00272 break;
00273 case MouseEvent::DRAGGED:
00274 (*i)->mouseDragged(evt);
00275 break;
00276 default:
00277 break;
00278 }
00279 if (evt.isConsumed()) {
00280 break;
00281 }
00282 ++i;
00283 }
00284 }
00285
00286 bool EventManager::dispatchSdlEvent(SDL_Event& evt) {
00287 bool ret = false;
00288 if (!m_pending_sdleventlisteners.empty()) {
00289 std::deque<ISdlEventListener*>::iterator i = m_pending_sdleventlisteners.begin();
00290 while(i != m_pending_sdleventlisteners.end()) {
00291 m_sdleventlisteners.push_back(*i);
00292 ++i;
00293 }
00294 m_pending_sdleventlisteners.clear();
00295 }
00296
00297 if (!m_pending_sdleventlisteners_front.empty()) {
00298 std::deque<ISdlEventListener*>::iterator i = m_pending_sdleventlisteners_front.begin();
00299 while(i != m_pending_sdleventlisteners_front.end()) {
00300 m_sdleventlisteners.push_front(*i);
00301 ++i;
00302 }
00303 m_pending_sdleventlisteners_front.clear();
00304 }
00305
00306 if (!m_pending_sdldeletions.empty()) {
00307 std::deque<ISdlEventListener*>::iterator i = m_pending_sdldeletions.begin();
00308 while (i != m_pending_sdldeletions.end()) {
00309 std::deque<ISdlEventListener*>::iterator j = m_sdleventlisteners.begin();
00310 while (j != m_sdleventlisteners.end()) {
00311 if(*j == *i) {
00312 m_sdleventlisteners.erase(j);
00313 break;
00314 }
00315 ++j;
00316 }
00317 ++i;
00318 }
00319 m_pending_sdldeletions.clear();
00320 }
00321
00322 std::deque<ISdlEventListener*>::iterator i = m_sdleventlisteners.begin();
00323 while (i != m_sdleventlisteners.end()) {
00324 ret = ret || (*i)->onSdlEvent(evt);
00325 ++i;
00326 }
00327 return ret;
00328 }
00329
00330 bool EventManager::combineEvents(SDL_Event& event1, const SDL_Event& event2) {
00331 if(event1.type == event2.type) {
00332 switch (event1.type) {
00333 case SDL_MOUSEMOTION:
00334 if(event1.motion.state == event2.motion.state) {
00335 event1.motion.x = event2.motion.x;
00336 event1.motion.y = event2.motion.y;
00337 event1.motion.xrel += event2.motion.xrel;
00338 event1.motion.yrel += event2.motion.yrel;
00339 return true;
00340 }
00341 return false;
00342 }
00343 }
00344 return false;
00345 }
00346
00347 void EventManager::processEvents() {
00348
00349
00350 SDL_Event event, next_event;
00351 bool has_next_event = SDL_PollEvent(&event);
00352 while (has_next_event) {
00353 has_next_event = SDL_PollEvent(&next_event);
00354 if(has_next_event && combineEvents(event, next_event))
00355 continue;
00356
00357 switch (event.type) {
00358 case SDL_QUIT: {
00359 Command cmd;
00360 cmd.setSource(this);
00361 cmd.setCommandType(CMD_QUIT_GAME);
00362 dispatchCommand(cmd);
00363 }
00364 break;
00365
00366 case SDL_ACTIVEEVENT:
00367 processActiveEvent(event);
00368 break;
00369
00370 case SDL_KEYDOWN:
00371 case SDL_KEYUP:
00372 processKeyEvent(event);
00373 break;
00374
00375 case SDL_MOUSEBUTTONUP:
00376 case SDL_MOUSEMOTION:
00377 case SDL_MOUSEBUTTONDOWN:
00378 processMouseEvent(event);
00379 break;
00380 }
00381 if(has_next_event)
00382 event = next_event;
00383 }
00384 }
00385
00386 void EventManager::processActiveEvent(SDL_Event event) {
00387 if(dispatchSdlEvent(event))
00388 return;
00389
00390 Command cmd;
00391 cmd.setSource(this);
00392 SDL_ActiveEvent actevt = event.active;
00393 if (actevt.state == SDL_APPMOUSEFOCUS)
00394 {
00395 if (actevt.gain)
00396 cmd.setCommandType(CMD_MOUSE_FOCUS_GAINED);
00397 else
00398 cmd.setCommandType(CMD_MOUSE_FOCUS_LOST);
00399 }
00400 else if (actevt.state == SDL_APPINPUTFOCUS)
00401 {
00402 if (actevt.gain)
00403 cmd.setCommandType(CMD_INPUT_FOCUS_GAINED);
00404 else
00405 cmd.setCommandType(CMD_INPUT_FOCUS_LOST);
00406 }
00407 else if (actevt.state == SDL_APPACTIVE)
00408 {
00409 if (actevt.gain)
00410 cmd.setCommandType(CMD_APP_RESTORED);
00411 else
00412 cmd.setCommandType(CMD_APP_ICONIFIED);
00413 }
00414 dispatchCommand(cmd);
00415 }
00416
00417 void EventManager::processKeyEvent(SDL_Event event) {
00418 KeyEvent keyevt;
00419 keyevt.setSource(this);
00420 fillKeyEvent(event, keyevt);
00421 m_keystatemap[keyevt.getKey().getValue()] = (keyevt.getType() == KeyEvent::PRESSED);
00422
00423 bool dispatchAsSdl = !keyevt.getKey().isFunctionKey();
00424 if( dispatchAsSdl && m_keyfilter ) {
00425 dispatchAsSdl = !m_keyfilter->isFiltered(keyevt);
00426 }
00427
00428 if( dispatchAsSdl ) {
00429 if( dispatchSdlEvent(event) )
00430 return;
00431 }
00432
00433 dispatchKeyEvent(keyevt);
00434 }
00435
00436 void EventManager::processMouseEvent(SDL_Event event) {
00437 if(dispatchSdlEvent(event))
00438 return;
00439
00440 MouseEvent mouseevt;
00441 mouseevt.setSource(this);
00442 fillMouseEvent(event, mouseevt);
00443 fillModifiers(mouseevt);
00444 if (event.type == SDL_MOUSEBUTTONDOWN) {
00445 m_mousestate |= static_cast<int>(mouseevt.getButton());
00446 m_mostrecentbtn = mouseevt.getButton();
00447 } else if (event.type == SDL_MOUSEBUTTONUP) {
00448 m_mousestate &= ~static_cast<int>(mouseevt.getButton());
00449 }
00450
00451 if (event.button.button == SDL_BUTTON_WHEELDOWN || event.button.button == SDL_BUTTON_WHEELUP) {
00452 if (event.type == SDL_MOUSEBUTTONUP) {
00453 return;
00454 }
00455 }
00456 dispatchMouseEvent(mouseevt);
00457 }
00458
00459
00460 void EventManager::fillMouseEvent(const SDL_Event& sdlevt, MouseEvent& mouseevt) {
00461 mouseevt.setX(sdlevt.button.x);
00462 mouseevt.setY(sdlevt.button.y);
00463 mouseevt.setButton(MouseEvent::EMPTY);
00464 mouseevt.setType(MouseEvent::MOVED);
00465 if ((sdlevt.type == SDL_MOUSEBUTTONUP) || (sdlevt.type == SDL_MOUSEBUTTONDOWN)) {
00466 switch (sdlevt.button.button) {
00467 case SDL_BUTTON_LEFT:
00468 mouseevt.setButton(MouseEvent::LEFT);
00469 break;
00470 case SDL_BUTTON_RIGHT:
00471 mouseevt.setButton(MouseEvent::RIGHT);
00472 break;
00473 case SDL_BUTTON_MIDDLE:
00474 mouseevt.setButton(MouseEvent::MIDDLE);
00475 break;
00476 default:
00477 mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON);
00478 break;
00479 }
00480
00481 if (sdlevt.type == SDL_MOUSEBUTTONUP ) {
00482 mouseevt.setType(MouseEvent::RELEASED);
00483 } else {
00484 mouseevt.setType(MouseEvent::PRESSED);
00485 }
00486
00487 switch (sdlevt.button.button) {
00488 case SDL_BUTTON_WHEELDOWN:
00489 mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN);
00490 break;
00491 case SDL_BUTTON_WHEELUP:
00492 mouseevt.setType(MouseEvent::WHEEL_MOVED_UP);
00493 break;
00494 default:
00495 break;
00496 }
00497 }
00498 if ((mouseevt.getType() == MouseEvent::MOVED) && m_mousestate) {
00499 mouseevt.setType(MouseEvent::DRAGGED);
00500 mouseevt.setButton(m_mostrecentbtn);
00501 }
00502 }
00503
00504 void EventManager::fillKeyEvent(const SDL_Event& sdlevt, KeyEvent& keyevt) {
00505 if (sdlevt.type == SDL_KEYDOWN) {
00506 keyevt.setType(KeyEvent::PRESSED);
00507 } else if (sdlevt.type == SDL_KEYUP) {
00508 keyevt.setType(KeyEvent::RELEASED);
00509 } else {
00510 throw EventException("Invalid event type in fillKeyEvent");
00511 }
00512 SDL_keysym keysym = sdlevt.key.keysym;
00513
00514 keyevt.setShiftPressed(keysym.mod & KMOD_SHIFT);
00515 keyevt.setControlPressed(keysym.mod & KMOD_CTRL);
00516 keyevt.setAltPressed(keysym.mod & KMOD_ALT);
00517 keyevt.setMetaPressed(keysym.mod & KMOD_META);
00518 keyevt.setNumericPad(keysym.sym >= SDLK_KP0 && keysym.sym <= SDLK_KP_EQUALS);
00519 keyevt.setKey(Key(static_cast<Key::KeyType>(keysym.sym), keysym.unicode));
00520 }
00521
00522 void EventManager::fillModifiers(InputEvent& evt) {
00523 evt.setAltPressed(m_keystatemap[Key::ALT_GR] |
00524 m_keystatemap[Key::LEFT_ALT] |
00525 m_keystatemap[Key::RIGHT_ALT]);
00526 evt.setControlPressed(m_keystatemap[Key::LEFT_CONTROL] |
00527 m_keystatemap[Key::RIGHT_CONTROL]);
00528 evt.setMetaPressed(m_keystatemap[Key::LEFT_META] |
00529 m_keystatemap[Key::RIGHT_META]);
00530 evt.setShiftPressed(m_keystatemap[Key::LEFT_SHIFT] |
00531 m_keystatemap[Key::RIGHT_SHIFT]);
00532 }
00533
00534 EventSourceType EventManager::getEventSourceType() {
00535 return ES_ENGINE;
00536 }
00537
00538 void EventManager::setKeyFilter(IKeyFilter* keyFilter) {
00539 m_keyfilter = keyFilter;
00540 }
00541 }