openMSX
StateChangeDistributor.cc
Go to the documentation of this file.
3#include "StateChange.hh"
4#include "stl.hh"
5#include <cassert>
6
7namespace openmsx {
8
10{
11 assert(listeners.empty());
12}
13
14bool StateChangeDistributor::isRegistered(StateChangeListener* listener) const
15{
16 return contains(listeners, listener);
17}
18
20{
21 assert(!isRegistered(&listener));
22 listeners.push_back(&listener);
23}
24
26{
27 move_pop_back(listeners, rfind_unguarded(listeners, &listener));
28}
29
31{
32 assert(!recorder);
33 recorder = &recorder_;
34}
35
37{
38 (void)recorder_;
39 assert(recorder == &recorder_);
40 recorder = nullptr;
41}
42
43void StateChangeDistributor::distribute(const StateChange& event)
44{
45 // Iterate over a copy because signalStateChange() may indirect call
46 // back into registerListener().
47 // e.g. signalStateChange() -> .. -> PlugCmd::execute() -> .. ->
48 // Connector::plug() -> .. -> Joystick::plugHelper() ->
49 // registerListener()
50 auto copy = listeners;
51 for (auto& l : copy) {
52 if (isRegistered(l)) {
53 // it's possible the listener unregistered itself
54 // (but is still present in the copy)
55 l->signalStateChange(event); // might throw
56 }
57 }
58}
59
60void StateChangeDistributor::stopReplay(EmuTime::param time)
61{
62 if (!isReplaying()) return;
63
64 if (recorder) recorder->stopReplay(time);
65 for (auto& l : listeners) {
66 l->stopReplay(time);
67 }
68}
69
71{
72 if (recorder) {
73 return recorder->isReplaying();
74 }
75 return false;
76}
77
78} // namespace openmsx
void stopReplay(EmuTime::param time) noexcept
void unregisterRecorder(ReverseManager &recorder)
void registerListener(StateChangeListener &listener)
(Un)registers the given object to receive state change events.
void registerRecorder(ReverseManager &recorder)
(Un)registers the given object to receive state change events.
void unregisterListener(StateChangeListener &listener)
void stopReplay(EmuTime::param time)
Explicitly stop replay.
Base class for all external MSX state changing events.
This file implemented 3 utility functions:
Definition Autofire.cc:9
void move_pop_back(VECTOR &v, typename VECTOR::iterator it)
Erase the pointed to element from the given vector.
Definition stl.hh:134
auto rfind_unguarded(RANGE &range, const VAL &val, Proj proj={})
Similar to the find(_if)_unguarded functions above, but searches from the back to front.
Definition stl.hh:109
constexpr bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
Definition stl.hh:32