FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator
eventmanager.cpp
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 }