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 "util/log/logger.h"
00033 #include "util/math/fife_math.h"
00034 #include "eventchannel/key/ec_key.h"
00035 #include "eventchannel/key/ec_keyevent.h"
00036 #include "eventchannel/key/ec_ikeyfilter.h"
00037 #include "eventchannel/mouse/ec_mouseevent.h"
00038 #include "eventchannel/command/ec_command.h"
00039 #include "video/renderbackend.h"
00040
00041 #include "eventmanager.h"
00042
00043 namespace FIFE {
00044 static Logger _log(LM_EVTCHANNEL);
00045
00046 EventManager::EventManager():
00047 m_commandlisteners(),
00048 m_keylisteners(),
00049 m_mouselisteners(),
00050 m_sdleventlisteners(),
00051 m_keystatemap(),
00052 m_keyfilter(0),
00053 m_mousestate(0),
00054 m_mostrecentbtn(MouseEvent::EMPTY),
00055 m_mousesensitivity(0.0),
00056 m_acceleration(false),
00057 m_warp(false),
00058 m_enter(false),
00059 m_oldx(0),
00060 m_oldy(0),
00061 m_lastticks(0),
00062 m_oldvelocity(0.0) {
00063 }
00064
00065 EventManager::~EventManager() {
00066 }
00067
00068 template<typename T>
00069 void removeListener(std::deque<T>& vec, T& listener) {
00070 vec.push_back(listener);
00071 }
00072
00073 template<typename T>
00074 void addListener(std::deque<T>& vec, T& listener) {
00075 vec.push_back(listener);
00076 }
00077
00078 void EventManager::addCommandListener(ICommandListener* listener) {
00079 addListener<ICommandListener*>(m_pending_commandlisteners, listener);
00080 }
00081
00082 void EventManager::addCommandListenerFront(ICommandListener* listener) {
00083 addListener<ICommandListener*>(m_pending_commandlisteners, listener);
00084 }
00085
00086 void EventManager::removeCommandListener(ICommandListener* listener) {
00087 removeListener<ICommandListener*>(m_pending_cldeletions, listener);
00088 }
00089
00090 void EventManager::addKeyListener(IKeyListener* listener) {
00091 addListener<IKeyListener*>(m_pending_keylisteners, listener);
00092 }
00093
00094 void EventManager::addKeyListenerFront(IKeyListener* listener) {
00095 addListener<IKeyListener*>(m_pending_keylisteners_front, listener);
00096 }
00097
00098 void EventManager::removeKeyListener(IKeyListener* listener) {
00099 removeListener<IKeyListener*>(m_pending_kldeletions, listener);
00100 }
00101
00102 void EventManager::addMouseListener(IMouseListener* listener) {
00103 addListener<IMouseListener*>(m_pending_mouselisteners, listener);
00104 }
00105
00106 void EventManager::addMouseListenerFront(IMouseListener* listener) {
00107 addListener<IMouseListener*>(m_pending_mouselisteners, listener);
00108 }
00109
00110 void EventManager::removeMouseListener(IMouseListener* listener) {
00111 removeListener<IMouseListener*>(m_pending_mldeletions, listener);
00112 }
00113
00114 void EventManager::addSdlEventListener(ISdlEventListener* listener) {
00115 addListener<ISdlEventListener*>(m_pending_sdleventlisteners, listener);
00116 }
00117
00118 void EventManager::addSdlEventListenerFront(ISdlEventListener* listener) {
00119 addListener<ISdlEventListener*>(m_pending_sdleventlisteners, listener);
00120 }
00121
00122 void EventManager::removeSdlEventListener(ISdlEventListener* listener) {
00123 removeListener<ISdlEventListener*>(m_pending_sdldeletions, listener);
00124 }
00125
00126 void EventManager::dispatchCommand(Command& command) {
00127 if(!m_pending_commandlisteners.empty()) {
00128 std::deque<ICommandListener*>::iterator i = m_pending_commandlisteners.begin();
00129 while (i != m_pending_commandlisteners.end()) {
00130 m_commandlisteners.push_back(*i);
00131 ++i;
00132 }
00133 m_pending_commandlisteners.clear();
00134 }
00135
00136 if(!m_pending_commandlisteners_front.empty()) {
00137 std::deque<ICommandListener*>::iterator i = m_pending_commandlisteners_front.begin();
00138 while (i != m_pending_commandlisteners_front.end()) {
00139 m_commandlisteners.push_front(*i);
00140 ++i;
00141 }
00142 m_pending_commandlisteners_front.clear();
00143 }
00144
00145 if (!m_pending_cldeletions.empty()) {
00146 std::deque<ICommandListener*>::iterator i = m_pending_cldeletions.begin();
00147 while (i != m_pending_cldeletions.end()) {
00148 std::deque<ICommandListener*>::iterator j = m_commandlisteners.begin();
00149 while (j != m_commandlisteners.end()) {
00150 if(*j == *i) {
00151 m_commandlisteners.erase(j);
00152 break;
00153 }
00154 ++j;
00155 }
00156 ++i;
00157 }
00158 m_pending_cldeletions.clear();
00159 }
00160
00161 std::deque<ICommandListener*>::iterator i = m_commandlisteners.begin();
00162 while (i != m_commandlisteners.end()) {
00163 (*i)->onCommand(command);
00164 if (command.isConsumed()) {
00165 break;
00166 }
00167 ++i;
00168 }
00169 }
00170
00171 void EventManager::dispatchKeyEvent(KeyEvent& evt) {
00172 if(!m_pending_keylisteners.empty()) {
00173 std::deque<IKeyListener*>::iterator i = m_pending_keylisteners.begin();
00174 while (i != m_pending_keylisteners.end()) {
00175 m_keylisteners.push_back(*i);
00176 ++i;
00177 }
00178 m_pending_keylisteners.clear();
00179 }
00180
00181 if(!m_pending_keylisteners_front.empty()) {
00182 std::deque<IKeyListener*>::iterator i = m_pending_keylisteners_front.begin();
00183 while (i != m_pending_keylisteners_front.end()) {
00184 m_keylisteners.push_front(*i);
00185 ++i;
00186 }
00187 m_pending_keylisteners_front.clear();
00188 }
00189
00190 if (!m_pending_kldeletions.empty()) {
00191 std::deque<IKeyListener*>::iterator i = m_pending_kldeletions.begin();
00192 while (i != m_pending_kldeletions.end()) {
00193 std::deque<IKeyListener*>::iterator j = m_keylisteners.begin();
00194 while (j != m_keylisteners.end()) {
00195 if(*j == *i) {
00196 m_keylisteners.erase(j);
00197 break;
00198 }
00199 ++j;
00200 }
00201 ++i;
00202 }
00203 m_pending_kldeletions.clear();
00204 }
00205
00206 std::deque<IKeyListener*>::iterator i = m_keylisteners.begin();
00207 while (i != m_keylisteners.end()) {
00208 switch (evt.getType()) {
00209 case KeyEvent::PRESSED:
00210 (*i)->keyPressed(evt);
00211 break;
00212 case KeyEvent::RELEASED:
00213 (*i)->keyReleased(evt);
00214 break;
00215 default:
00216 break;
00217 }
00218 ++i;
00219 }
00220 }
00221
00222 void EventManager::dispatchMouseEvent(MouseEvent& evt) {
00223 if(!m_pending_mouselisteners.empty()) {
00224 std::deque<IMouseListener*>::iterator i = m_pending_mouselisteners.begin();
00225 while (i != m_pending_mouselisteners.end()) {
00226 m_mouselisteners.push_back(*i);
00227 ++i;
00228 }
00229 m_pending_mouselisteners.clear();
00230 }
00231
00232 if(!m_pending_mouselisteners_front.empty()) {
00233 std::deque<IMouseListener*>::iterator i = m_pending_mouselisteners_front.begin();
00234 while (i != m_pending_mouselisteners_front.end()) {
00235 m_mouselisteners.push_front(*i);
00236 ++i;
00237 }
00238 m_pending_mouselisteners_front.clear();
00239 }
00240
00241 if (!m_pending_mldeletions.empty()) {
00242 std::deque<IMouseListener*>::iterator i = m_pending_mldeletions.begin();
00243 while (i != m_pending_mldeletions.end()) {
00244 std::deque<IMouseListener*>::iterator j = m_mouselisteners.begin();
00245 while (j != m_mouselisteners.end()) {
00246 if(*j == *i) {
00247 m_mouselisteners.erase(j);
00248 break;
00249 }
00250 ++j;
00251 }
00252 ++i;
00253 }
00254 m_pending_mldeletions.clear();
00255 }
00256
00257 std::deque<IMouseListener*>::iterator i = m_mouselisteners.begin();
00258 while (i != m_mouselisteners.end()) {
00259 switch (evt.getType()) {
00260 case MouseEvent::MOVED:
00261 (*i)->mouseMoved(evt);
00262 break;
00263 case MouseEvent::PRESSED:
00264 (*i)->mousePressed(evt);
00265 break;
00266 case MouseEvent::RELEASED:
00267 (*i)->mouseReleased(evt);
00268 break;
00269 case MouseEvent::WHEEL_MOVED_DOWN:
00270 (*i)->mouseWheelMovedDown(evt);
00271 break;
00272 case MouseEvent::WHEEL_MOVED_UP:
00273 (*i)->mouseWheelMovedUp(evt);
00274 break;
00275 case MouseEvent::CLICKED:
00276 (*i)->mouseClicked(evt);
00277 break;
00278 case MouseEvent::ENTERED:
00279 (*i)->mouseEntered(evt);
00280 break;
00281 case MouseEvent::EXITED:
00282 (*i)->mouseExited(evt);
00283 break;
00284 case MouseEvent::DRAGGED:
00285 (*i)->mouseDragged(evt);
00286 break;
00287 default:
00288 break;
00289 }
00290 if (evt.isConsumed()) {
00291 break;
00292 }
00293 ++i;
00294 }
00295 }
00296
00297 bool EventManager::dispatchSdlEvent(SDL_Event& evt) {
00298 bool ret = false;
00299 if (!m_pending_sdleventlisteners.empty()) {
00300 std::deque<ISdlEventListener*>::iterator i = m_pending_sdleventlisteners.begin();
00301 while(i != m_pending_sdleventlisteners.end()) {
00302 m_sdleventlisteners.push_back(*i);
00303 ++i;
00304 }
00305 m_pending_sdleventlisteners.clear();
00306 }
00307
00308 if (!m_pending_sdleventlisteners_front.empty()) {
00309 std::deque<ISdlEventListener*>::iterator i = m_pending_sdleventlisteners_front.begin();
00310 while(i != m_pending_sdleventlisteners_front.end()) {
00311 m_sdleventlisteners.push_front(*i);
00312 ++i;
00313 }
00314 m_pending_sdleventlisteners_front.clear();
00315 }
00316
00317 if (!m_pending_sdldeletions.empty()) {
00318 std::deque<ISdlEventListener*>::iterator i = m_pending_sdldeletions.begin();
00319 while (i != m_pending_sdldeletions.end()) {
00320 std::deque<ISdlEventListener*>::iterator j = m_sdleventlisteners.begin();
00321 while (j != m_sdleventlisteners.end()) {
00322 if(*j == *i) {
00323 m_sdleventlisteners.erase(j);
00324 break;
00325 }
00326 ++j;
00327 }
00328 ++i;
00329 }
00330 m_pending_sdldeletions.clear();
00331 }
00332
00333 std::deque<ISdlEventListener*>::iterator i = m_sdleventlisteners.begin();
00334 while (i != m_sdleventlisteners.end()) {
00335 ret = ret || (*i)->onSdlEvent(evt);
00336 ++i;
00337 }
00338 return ret;
00339 }
00340
00341 bool EventManager::combineEvents(SDL_Event& event1, const SDL_Event& event2) {
00342 if(event1.type == event2.type) {
00343 switch (event1.type) {
00344 case SDL_MOUSEMOTION:
00345 if(event1.motion.state == event2.motion.state) {
00346 event1.motion.x = event2.motion.x;
00347 event1.motion.y = event2.motion.y;
00348 event1.motion.xrel += event2.motion.xrel;
00349 event1.motion.yrel += event2.motion.yrel;
00350 return true;
00351 }
00352 return false;
00353 }
00354 }
00355 return false;
00356 }
00357
00358 void EventManager::processEvents() {
00359
00360
00361 SDL_Event event, next_event;
00362 bool has_next_event = (SDL_PollEvent(&event) != 0);
00363 while (has_next_event) {
00364 has_next_event = (SDL_PollEvent(&next_event) != 0);
00365 if(has_next_event && combineEvents(event, next_event))
00366 continue;
00367
00368 switch (event.type) {
00369 case SDL_QUIT: {
00370 Command cmd;
00371 cmd.setSource(this);
00372 cmd.setCommandType(CMD_QUIT_GAME);
00373 dispatchCommand(cmd);
00374 }
00375 break;
00376
00377 case SDL_ACTIVEEVENT:
00378 processActiveEvent(event);
00379 break;
00380
00381 case SDL_KEYDOWN:
00382 case SDL_KEYUP:
00383 processKeyEvent(event);
00384 break;
00385
00386 case SDL_MOUSEBUTTONUP:
00387 case SDL_MOUSEMOTION:
00388 case SDL_MOUSEBUTTONDOWN:
00389 processMouseEvent(event);
00390 break;
00391 }
00392 if(has_next_event)
00393 event = next_event;
00394 }
00395 }
00396
00397 void EventManager::processActiveEvent(SDL_Event event) {
00398 if (dispatchSdlEvent(event)) {
00399 return;
00400 }
00401
00402 SDL_ActiveEvent actevt = event.active;
00403 std::vector<Command*> commands;
00404
00405 if (actevt.state & SDL_APPMOUSEFOCUS) {
00406 Command* cmd = new Command();
00407 if (actevt.gain) {
00408 cmd->setCommandType(CMD_MOUSE_FOCUS_GAINED);
00409 m_enter = true;
00410 } else {
00411 cmd->setCommandType(CMD_MOUSE_FOCUS_LOST);
00412 }
00413 commands.push_back(cmd);
00414 }
00415 if (actevt.state & SDL_APPINPUTFOCUS) {
00416 Command* cmd = new Command();
00417 if (actevt.gain) {
00418 cmd->setCommandType(CMD_INPUT_FOCUS_GAINED);
00419 } else {
00420 cmd->setCommandType(CMD_INPUT_FOCUS_LOST);
00421 }
00422 commands.push_back(cmd);
00423 }
00424 if (actevt.state & SDL_APPACTIVE) {
00425 Command* cmd = new Command();
00426 if (actevt.gain) {
00427 cmd->setCommandType(CMD_APP_RESTORED);
00428 } else {
00429 cmd->setCommandType(CMD_APP_ICONIFIED);
00430 }
00431 commands.push_back(cmd);
00432 }
00433
00434 std::vector<Command*>::iterator it = commands.begin();
00435 for (; it != commands.end(); ++it) {
00436 dispatchCommand(**it);
00437 delete *it;
00438 }
00439 }
00440
00441 void EventManager::processKeyEvent(SDL_Event event) {
00442 KeyEvent keyevt;
00443 keyevt.setSource(this);
00444 fillKeyEvent(event, keyevt);
00445 m_keystatemap[keyevt.getKey().getValue()] = (keyevt.getType() == KeyEvent::PRESSED);
00446
00447 bool dispatchAsSdl = !keyevt.getKey().isFunctionKey();
00448 if( dispatchAsSdl && m_keyfilter ) {
00449 dispatchAsSdl = !m_keyfilter->isFiltered(keyevt);
00450 }
00451
00452 if( dispatchAsSdl ) {
00453 if( dispatchSdlEvent(event) )
00454 return;
00455 }
00456
00457 dispatchKeyEvent(keyevt);
00458 }
00459
00460 void EventManager::processMouseEvent(SDL_Event event) {
00461 if (event.type == SDL_MOUSEMOTION && (!Mathf::Equal(m_mousesensitivity, 0.0) || m_acceleration)) {
00462 uint16_t tmp_x = event.motion.x;
00463 uint16_t tmp_y = event.motion.y;
00464 if (m_enter) {
00465 m_oldx = tmp_x;
00466 m_oldy = tmp_y;
00467 m_oldvelocity = 0.0;
00468 m_enter = false;
00469 }
00470
00471 float modifier;
00472 if (m_acceleration) {
00473 uint32_t ticks = SDL_GetTicks();
00474 float difference = static_cast<float>((ticks - m_lastticks) + 1);
00475 m_lastticks = ticks;
00476 float dx = static_cast<float>(tmp_x - m_oldx);
00477 float dy = static_cast<float>(tmp_y - m_oldy);
00478 float distance = Mathf::Sqrt(dx * dx + dy * dy);
00479 float acceleration = static_cast<float>((distance / difference) / difference);
00480 float velocity = (m_oldvelocity + acceleration * difference)/2;
00481 if (velocity > m_mousesensitivity+1) {
00482 velocity = m_mousesensitivity+1;
00483 }
00484 m_oldvelocity = velocity;
00485 modifier = velocity;
00486 } else {
00487 modifier = m_mousesensitivity;
00488 }
00489
00490 int16_t tmp_xrel = static_cast<int16_t>(tmp_x - m_oldx);
00491 int16_t tmp_yrel = static_cast<int16_t>(tmp_y - m_oldy);
00492 if ((tmp_xrel != 0) || (tmp_yrel != 0)) {
00493 Rect screen = RenderBackend::instance()->getArea();
00494 int16_t x_fact = static_cast<int16_t>(round(static_cast<float>(tmp_xrel * modifier)));
00495 int16_t y_fact = static_cast<int16_t>(round(static_cast<float>(tmp_yrel * modifier)));
00496 if ((tmp_x + x_fact) > screen.w) {
00497 tmp_x = screen.w;
00498 } else if ((tmp_x + x_fact) < screen.x) {
00499 tmp_x = screen.x;
00500 } else {
00501 tmp_x += x_fact;
00502 }
00503
00504 if (tmp_y + y_fact > screen.h) {
00505 tmp_y = screen.h;
00506 } else if ((tmp_y + y_fact) < screen.y) {
00507 tmp_y = screen.y;
00508 } else {
00509 tmp_y += y_fact;
00510 }
00511 m_oldx = tmp_x;
00512 m_oldy = tmp_y;
00513 event.motion.x = tmp_x;
00514 event.motion.y = tmp_y;
00515 m_warp = true;
00516 SDL_WarpMouse(tmp_x, tmp_y);
00517 m_warp = false;
00518 }
00519
00520 }
00521 if (dispatchSdlEvent(event)) {
00522 return;
00523 }
00524 MouseEvent mouseevt;
00525 mouseevt.setSource(this);
00526 fillMouseEvent(event, mouseevt);
00527 fillModifiers(mouseevt);
00528 if (event.type == SDL_MOUSEBUTTONDOWN) {
00529 m_mousestate |= static_cast<int32_t>(mouseevt.getButton());
00530 m_mostrecentbtn = mouseevt.getButton();
00531 } else if (event.type == SDL_MOUSEBUTTONUP) {
00532 m_mousestate &= ~static_cast<int32_t>(mouseevt.getButton());
00533 }
00534
00535 if (event.button.button == SDL_BUTTON_WHEELDOWN || event.button.button == SDL_BUTTON_WHEELUP) {
00536 if (event.type == SDL_MOUSEBUTTONUP) {
00537 return;
00538 }
00539 }
00540 dispatchMouseEvent(mouseevt);
00541 }
00542
00543
00544 void EventManager::fillMouseEvent(const SDL_Event& sdlevt, MouseEvent& mouseevt) {
00545 if (m_warp) {
00546 return;
00547 }
00548
00549 mouseevt.setX(sdlevt.button.x);
00550 mouseevt.setY(sdlevt.button.y);
00551
00552 mouseevt.setButton(MouseEvent::EMPTY);
00553 mouseevt.setType(MouseEvent::MOVED);
00554 if ((sdlevt.type == SDL_MOUSEBUTTONUP) || (sdlevt.type == SDL_MOUSEBUTTONDOWN)) {
00555 switch (sdlevt.button.button) {
00556 case SDL_BUTTON_LEFT:
00557 mouseevt.setButton(MouseEvent::LEFT);
00558 break;
00559 case SDL_BUTTON_RIGHT:
00560 mouseevt.setButton(MouseEvent::RIGHT);
00561 break;
00562 case SDL_BUTTON_MIDDLE:
00563 mouseevt.setButton(MouseEvent::MIDDLE);
00564 break;
00565 default:
00566 mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON);
00567 break;
00568 }
00569
00570 if (sdlevt.type == SDL_MOUSEBUTTONUP ) {
00571 mouseevt.setType(MouseEvent::RELEASED);
00572 } else {
00573 mouseevt.setType(MouseEvent::PRESSED);
00574 }
00575
00576 switch (sdlevt.button.button) {
00577 case SDL_BUTTON_WHEELDOWN:
00578 mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN);
00579 break;
00580 case SDL_BUTTON_WHEELUP:
00581 mouseevt.setType(MouseEvent::WHEEL_MOVED_UP);
00582 break;
00583 default:
00584 break;
00585 }
00586 }
00587 if ((mouseevt.getType() == MouseEvent::MOVED) && m_mousestate) {
00588 mouseevt.setType(MouseEvent::DRAGGED);
00589 mouseevt.setButton(m_mostrecentbtn);
00590 }
00591 }
00592
00593 void EventManager::fillKeyEvent(const SDL_Event& sdlevt, KeyEvent& keyevt) {
00594 if (sdlevt.type == SDL_KEYDOWN) {
00595 keyevt.setType(KeyEvent::PRESSED);
00596 } else if (sdlevt.type == SDL_KEYUP) {
00597 keyevt.setType(KeyEvent::RELEASED);
00598 } else {
00599 FL_WARN(_log, LMsg("fillKeyEvent()")
00600 << " Invalid key event type of " << sdlevt.type << ". Ignoring event.");
00601 return;
00602 }
00603 SDL_keysym keysym = sdlevt.key.keysym;
00604
00605 keyevt.setShiftPressed((keysym.mod & KMOD_SHIFT) != 0);
00606 keyevt.setControlPressed((keysym.mod & KMOD_CTRL) != 0);
00607 keyevt.setAltPressed((keysym.mod & KMOD_ALT) != 0);
00608 keyevt.setMetaPressed((keysym.mod & KMOD_META) != 0);
00609 keyevt.setNumericPad(keysym.sym >= SDLK_KP0 && keysym.sym <= SDLK_KP_EQUALS);
00610 keyevt.setKey(Key(static_cast<Key::KeyType>(keysym.sym), keysym.unicode));
00611 }
00612
00613 void EventManager::fillModifiers(InputEvent& evt) {
00614 evt.setAltPressed(m_keystatemap[Key::ALT_GR] |
00615 m_keystatemap[Key::LEFT_ALT] |
00616 m_keystatemap[Key::RIGHT_ALT]);
00617 evt.setControlPressed(m_keystatemap[Key::LEFT_CONTROL] |
00618 m_keystatemap[Key::RIGHT_CONTROL]);
00619 evt.setMetaPressed(m_keystatemap[Key::LEFT_META] |
00620 m_keystatemap[Key::RIGHT_META]);
00621 evt.setShiftPressed(m_keystatemap[Key::LEFT_SHIFT] |
00622 m_keystatemap[Key::RIGHT_SHIFT]);
00623 }
00624
00625 EventSourceType EventManager::getEventSourceType() {
00626 return ES_ENGINE;
00627 }
00628
00629 void EventManager::setKeyFilter(IKeyFilter* keyFilter) {
00630 m_keyfilter = keyFilter;
00631 }
00632
00633 void EventManager::setMouseSensitivity(float sensitivity) {
00634 if (sensitivity < -0.99) {
00635 sensitivity = -0.99;
00636 } else if (sensitivity > 10.0) {
00637 sensitivity = 10.0;
00638 }
00639 m_mousesensitivity = sensitivity;
00640 }
00641
00642 float EventManager::getMouseSensitivity() const {
00643 return m_mousesensitivity;
00644 }
00645
00646 void EventManager::setMouseAcceleration(bool acceleration) {
00647 m_acceleration = acceleration;
00648 }
00649
00650 bool EventManager::getMouseAcceleration() const {
00651 return m_acceleration;
00652 }
00653 }