FIFE
2008.0
|
00001 /*************************************************************************** 00002 * Copyright (C) 2005-2008 by the FIFE team * 00003 * http://www.fifengine.de * 00004 * This file is part of FIFE. * 00005 * * 00006 * FIFE is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Lesser General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2.1 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00014 * Lesser General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with this library; if not, write to the * 00018 * Free Software Foundation, Inc., * 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 00020 ***************************************************************************/ 00021 00022 // Standard C++ library includes 00023 #include <iostream> 00024 00025 // 3rd party library includes 00026 00027 // FIFE includes 00028 // These includes are split up in two parts, separated by one empty line 00029 // First block: files included from the FIFE root src directory 00030 // Second block: files included from the same folder 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 // The double SDL_PollEvent calls don't throw away events, 00349 // but try to combine (mouse motion) events. 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 // fire scrollwheel events only once 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 }