ScummVM API documentation
events.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef MEDIASTATION_EVENTS_H
23 #define MEDIASTATION_EVENTS_H
24 
25 #include "common/events.h"
26 #include "common/hash-ptr.h"
27 #include "common/ptr.h"
28 #include "common/str.h"
29 #include "common/queue.h"
30 
31 #include "mediastation/mediascript/scriptconstants.h"
32 #include "mediastation/mediascript/scriptvalue.h"
33 
34 namespace MediaStation {
35 
36 enum EventClass {
37  kEventClassInvalid = 0x00,
38  kEventClassSystem = 0x01,
39  kEventClassMouse = 0x02,
40  kEventClassKeyboard = 0x04,
41  kEventClassDisplay = 0x08,
42  kEventClassTimerService = 0x10,
43  kEventClassScriptTimer = 0x20,
44  kEventClassActor = 0x40
45 };
46 const char *eventClassToStr(EventClass eventClass);
47 
48 // This reimplementation doesn't use these values because
49 // there isn't the indirection of event handler classes. We
50 // just use the event class directly when deciding where to route an
51 // event. However, this is still included for completeness .
52 enum EventClassHandlerType {
53  kNoEventClassHandler = 0x00,
54  kStageDirectorEventClassHandler = 0x06,
55  kDisplayUpdateEventClassHandler = 0x08,
56  kTimerServiceClassHandler = 0x10,
57  kActorEventClassHandler = 0x40,
58 };
59 
60 struct Event {
61  EventClass eventClass = kEventClassInvalid;
62  EventType type = kEventTypeInvalid;
63 
64  Event(EventClass eventClass_, EventType eventType_)
65  : eventClass(eventClass_), type(eventType_) {}
66  virtual ~Event() {}
67  virtual Event *clone() const = 0;
68  virtual Common::String debugString() const;
69 };
70 
71 struct DisplayEvent : public Event {
72  uint disableScreenAutoUpdateToken = 0;
73 
74  DisplayEvent(EventType eventType_, uint token_)
75  : Event(kEventClassDisplay, eventType_), disableScreenAutoUpdateToken(token_) {}
76  Event *clone() const override { return new DisplayEvent(*this); }
77  Common::String debugString() const override;
78 };
79 
80 // This is an event queued to tell the timer service that a timer has expired. When this event is processed,
81 // an actual timer event will get sent to the actual timer event handler (actors and such).
82 class TimerEntry;
83 struct TimerServiceAlarmEvent : public Event {
84  uint32 triggerTime = 0;
85  TimerEntry *entry = nullptr;
86 
87  TimerServiceAlarmEvent(TimerEntry *entry_, uint32 triggerTime_)
88  : Event(kEventClassTimerService, kTimerServiceAlarmEvent), triggerTime(triggerTime_), entry(entry_) {}
89  Event *clone() const override { return new TimerServiceAlarmEvent(*this); }
90  Common::String debugString() const override;
91 };
92 
93 // This is actually sent to timer event handlers (actors and such).
94 struct TimerEvent : public Event {
95  TimerEntry *entry = nullptr;
96 
97  TimerEvent(TimerEntry *entry_)
98  : Event(kEventClassScriptTimer, kTimerScriptEvent), entry(entry_) {}
99  Event *clone() const override { return new TimerEvent(*this); }
100  Common::String debugString() const override;
101 };
102 
103 struct ActorEvent : public Event {
104  uint actorId = 0;
105  ScriptValue arg;
106 
107  ActorEvent(uint16 actorId_, EventType eventType_)
108  : Event(kEventClassActor, eventType_), actorId(actorId_) {}
109  ActorEvent(uint16 actorId_, EventType eventType_, ScriptValue arg_)
110  : Event(kEventClassActor, eventType_), actorId(actorId_), arg(arg_) {}
111  Event *clone() const override { return new ActorEvent(*this); }
112  Common::String debugString() const override;
113 };
114 
115 struct ScreenBranchEvent : public ActorEvent {
116  uint screenId = 0;
117  bool disableScreenAutoUpdate = false;
118 
119  ScreenBranchEvent(uint16 actorId_, uint16 screenId_, bool disableScreenAutoUpdate_)
120  : ActorEvent(actorId_, kScreenBranchEvent), screenId(screenId_), disableScreenAutoUpdate(disableScreenAutoUpdate_) {}
121  Event *clone() const override { return new ScreenBranchEvent(*this); }
122  Common::String debugString() const override;
123 };
124 
125 struct MouseEvent : public Event {
126  Common::Point position;
127 
128  MouseEvent(EventType eventType_, const Common::Point &position_)
129  : Event(kEventClassMouse, eventType_), position(position_) {}
130  Event *clone() const override { return new MouseEvent(*this); }
131  Common::String debugString() const override;
132 };
133 
134 struct KeyboardEvent : public Event {
135  uint16 keyCode = 0;
136 
137  KeyboardEvent(EventType eventType_, uint16 keyCode_)
138  : Event(kEventClassKeyboard, eventType_), keyCode(keyCode_) {}
139  Event *clone() const override { return new KeyboardEvent(*this); }
140  Common::String debugString() const override;
141 };
142 
143 enum PreDisplaySyncState {
144  kPreDisplaySyncForceScreenUpdate = 0,
145  kPreDisplaySyncNoScreenUpdateRequested = 1,
146  kPreDisplaySyncStateBlockScreenUpdate = 2
147 };
148 
149 // Interface for clients that need to update during the pre-display sync phase.
150 // Only stream movie actors seem to actually use this.
152 public:
153  virtual ~PreDisplaySyncClient() {}
154  virtual PreDisplaySyncState preDisplaySync() = 0;
155 
156  void registerForSyncCalls();
157  void unregisterForSyncCalls();
158 };
159 
160 // The main event loop. In the original, much of the functionality lived in a separate
161 // EventLoopSupport class (implemented by MAC_App or WIN_App), but in ScummVM there
162 // is no need for that extra indirection.
163 class EventLoop {
164 public:
165  void run();
166  void queueEvent(const Event &event);
167 
168  void registerForPreDisplaySyncCalls(PreDisplaySyncClient *client);
169  void unregisterForPreDisplaySyncCalls(PreDisplaySyncClient *client);
170 
171 private:
174  Common::Event _queuedSystemEvent;
176 
177  void dispatchImtEvents();
178  PreDisplaySyncState preDisplaySync();
179  void updateDisplay();
180 
181  // The original had a separate EventDispatcher, but things are much simpler by not using
182  // the polymorphism that required this intermediate class.
183  void dispatchImtEvent(const Event &event);
184 };
185 
187 public:
188  virtual ~TimerEventReceiver() {};
189 
190  uint32 currentReceiverTime();
191  virtual void timerEvent(const TimerEvent &event) = 0;
192 };
193 
194 class TimerEntry {
195 public:
196  TimerEntry() = default;
197  TimerEntry(TimerEventReceiver *receiver) : _receiver(receiver) {}
198  ~TimerEntry();
199 
200  void setDuration(uint32 duration) { _duration = duration; }
201  uint32 calculateFirstExpirationTime(uint32 currentTime);
202  uint32 calculateNextExpirationTime(uint32 currentTime);
203  uint32 deltaTimeAtExpiration() const;
204  uint32 expirationTime() const { return _expirationTime; }
205  bool shouldReschedule() const { return _shouldRepeat; }
206  TimerEventReceiver *getReceiver() const { return _receiver; }
207 
208  bool operator==(const TimerEntry &other) const;
209  bool operator<(const TimerEntry &other) const;
210  bool operator>(const TimerEntry &other) const;
211 
212 private:
213  TimerEventReceiver *_receiver = nullptr;
214  uint32 _expirationTime = 0;
215  uint32 _actualExpirationTime = 0;
216  uint32 _duration = 0;
217  bool _shouldRepeat = false;
218 };
219 
221 public:
222  // This is called to actually dispatch a timer event to the event receiver.
223  void handleEvent(const TimerServiceAlarmEvent &event);
224 
225  void startTimer(TimerEntry &entry, uint32 duration);
226  void startTimer(TimerEntry &entry, double duration);
227  void stopTimer(TimerEntry &entry);
228  void queueExpiredTimerEvents();
229 
230 private:
232 
233  void rescheduleTimerEntry(TimerEntry &entry);
234 };
235 
236 } // End of namespace MediaStation
237 
238 #endif
Definition: str.h:59
Definition: actor.h:34
Definition: events.h:71
Definition: events.h:186
Definition: events.h:60
Definition: events.h:220
Definition: queue.h:42
Definition: events.h:115
Definition: events.h:103
Definition: events.h:94
Definition: events.h:194
Definition: hashmap.h:85
Definition: events.h:134
Definition: events.h:210
Definition: rect.h:144
Definition: events.h:151
Definition: events.h:125
Definition: events.h:163
Definition: scriptvalue.h:35