ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

events.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/events.h"
00024 
00025 #include "common/system.h"
00026 
00027 namespace Common {
00028 
00029 bool isMouseEvent(const Event &event) {
00030     return event.type == EVENT_LBUTTONDOWN
00031             || event.type == EVENT_LBUTTONUP
00032             || event.type == EVENT_RBUTTONDOWN
00033             || event.type == EVENT_RBUTTONUP
00034             || event.type == EVENT_MBUTTONDOWN
00035             || event.type == EVENT_MBUTTONUP
00036             || event.type == EVENT_X1BUTTONDOWN
00037             || event.type == EVENT_X1BUTTONUP
00038             || event.type == EVENT_X2BUTTONDOWN
00039             || event.type == EVENT_X2BUTTONUP
00040             || event.type == EVENT_WHEELDOWN
00041             || event.type == EVENT_WHEELUP
00042             || event.type == EVENT_MOUSEMOVE;
00043 }
00044 
00045 EventSource::~EventSource() {}
00046 
00047 EventObserver::~EventObserver() {}
00048 
00049 EventMapper::~EventMapper() {}
00050 
00051 EventManager::~EventManager() {}
00052 
00053 EventDispatcher::EventDispatcher() : _mapper(nullptr) {
00054 }
00055 
00056 EventDispatcher::~EventDispatcher() {
00057     for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
00058         if (i->autoFree)
00059             delete i->source;
00060     }
00061 
00062     for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
00063         if (i->autoFree)
00064             delete i->observer;
00065     }
00066 }
00067 
00068 void EventDispatcher::dispatch() {
00069     Event event;
00070 
00071     dispatchPoll();
00072 
00073     for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
00074         while (i->source->pollEvent(event)) {
00075             // We only try to process the events via the setup event mapper, when
00076             // we have a setup mapper and when the event source allows mapping.
00077             if (i->source->allowMapping()) {
00078                 assert(_mapper);
00079 
00080                 // Backends may not produce directly action event types, those are meant
00081                 // to be the output of the event mapper.
00082                 assert(event.type != EVENT_CUSTOM_BACKEND_ACTION_START);
00083                 assert(event.type != EVENT_CUSTOM_BACKEND_ACTION_END);
00084                 assert(event.type != EVENT_CUSTOM_ENGINE_ACTION_START);
00085                 assert(event.type != EVENT_CUSTOM_ENGINE_ACTION_END);
00086 
00087 
00088                 List<Event> mappedEvents = _mapper->mapEvent(event);
00089 
00090                 for (List<Event>::iterator j = mappedEvents.begin(); j != mappedEvents.end(); ++j) {
00091                     const Event mappedEvent = *j;
00092                     dispatchEvent(mappedEvent);
00093                 }
00094             } else {
00095                 dispatchEvent(event);
00096             }
00097         }
00098     }
00099 }
00100 
00101 void EventDispatcher::clearEvents() {
00102     Event event;
00103 
00104     for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
00105         while (i->source->pollEvent(event)) {}
00106     }
00107 }
00108 
00109 
00110 void EventDispatcher::registerMapper(EventMapper *mapper) {
00111     _mapper = mapper;
00112 }
00113 
00114 
00115 void EventDispatcher::registerSource(EventSource *source, bool autoFree) {
00116     SourceEntry newEntry;
00117 
00118     newEntry.source = source;
00119     newEntry.autoFree = autoFree;
00120 
00121     _sources.push_back(newEntry);
00122 }
00123 
00124 void EventDispatcher::unregisterSource(EventSource *source) {
00125     for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
00126         if (i->source == source) {
00127             if (i->autoFree)
00128                 delete source;
00129 
00130             _sources.erase(i);
00131             return;
00132         }
00133     }
00134 }
00135 
00136 void EventDispatcher::registerObserver(EventObserver *obs, uint priority, bool autoFree, bool notifyPoll) {
00137     ObserverEntry newEntry;
00138 
00139     newEntry.observer = obs;
00140     newEntry.priority = priority;
00141     newEntry.autoFree = autoFree;
00142     newEntry.poll = notifyPoll;
00143 
00144     for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
00145         if (i->priority < priority) {
00146             _observers.insert(i, newEntry);
00147             return;
00148         }
00149     }
00150 
00151     _observers.push_back(newEntry);
00152 }
00153 
00154 void EventDispatcher::unregisterObserver(EventObserver *obs) {
00155     for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
00156         if (i->observer == obs) {
00157             if (i->autoFree)
00158                 delete obs;
00159 
00160             _observers.erase(i);
00161             return;
00162         }
00163     }
00164 }
00165 
00166 void EventDispatcher::dispatchEvent(const Event &event) {
00167     for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
00168         if (i->observer->notifyEvent(event))
00169             break;
00170     }
00171 }
00172 
00173 void EventDispatcher::dispatchPoll() {
00174     for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
00175         if (i->poll)
00176             i->observer->notifyPoll();
00177     }
00178 }
00179 
00180 class KeyboardRepeatEventSourceWrapper : public Common::EventSource {
00181 public:
00182     KeyboardRepeatEventSourceWrapper(Common::EventSource *delegate) :
00183             _delegate(delegate),
00184             _keyRepeatTime(0) {
00185         assert(delegate);
00186     }
00187 
00188     // EventSource API
00189     bool pollEvent(Common::Event &event) override {
00190         uint32 time = g_system->getMillis(true);
00191         bool gotEvent = _delegate->pollEvent(event);
00192 
00193         if (gotEvent) {
00194             switch (event.type) {
00195             case Common::EVENT_KEYDOWN:
00196                 // init continuous event stream
00197                 _currentKeyDown = event.kbd;
00198                 _keyRepeatTime = time + kKeyRepeatInitialDelay;
00199                 break;
00200 
00201             case Common::EVENT_KEYUP:
00202                 if (event.kbd.keycode == _currentKeyDown.keycode) {
00203                     // Only stop firing events if it's the current key
00204                     _currentKeyDown.keycode = Common::KEYCODE_INVALID;
00205                 }
00206                 break;
00207 
00208             default:
00209                 break;
00210             }
00211 
00212             return true;
00213         } else {
00214             // Check if event should be sent again (keydown)
00215             if (_currentKeyDown.keycode != Common::KEYCODE_INVALID && _keyRepeatTime <= time) {
00216                 // fire event
00217                 event.type = Common::EVENT_KEYDOWN;
00218                 event.kbdRepeat = true;
00219                 event.kbd = _currentKeyDown;
00220                 _keyRepeatTime = time + kKeyRepeatSustainDelay;
00221 
00222                 return true;
00223             }
00224 
00225             return false;
00226         }
00227     }
00228 
00229     bool allowMapping() const override {
00230         return _delegate->allowMapping();
00231     }
00232 
00233 private:
00234     // for continuous events (keyDown)
00235     enum {
00236         kKeyRepeatInitialDelay = 400,
00237         kKeyRepeatSustainDelay = 100
00238     };
00239 
00240     Common::EventSource *_delegate;
00241 
00242     Common::KeyState _currentKeyDown;
00243     uint32 _keyRepeatTime;
00244 };
00245 
00246 EventSource *makeKeyboardRepeatingEventSource(EventSource *eventSource) {
00247     if (!eventSource) {
00248         return nullptr;
00249     }
00250 
00251     return new KeyboardRepeatEventSourceWrapper(eventSource);
00252 }
00253 
00254 } // End of namespace Common


Generated on Sat Aug 8 2020 05:01:05 for ResidualVM by doxygen 1.7.1
curved edge   curved edge