openMSX
StateChangeDistributor.cc
Go to the documentation of this file.
2
4#include "StateChange.hh"
5
6#include "stl.hh"
7
8#include <cassert>
9
10namespace openmsx {
11
13{
14 assert(listeners.empty());
15}
16
17bool StateChangeDistributor::isRegistered(StateChangeListener* listener) const
18{
19 return contains(listeners, listener);
20}
21
23{
24 assert(!isRegistered(&listener));
25 listeners.push_back(&listener);
26}
27
29{
30 move_pop_back(listeners, rfind_unguarded(listeners, &listener));
31}
32
34{
35 assert(!recorder);
36 recorder = &recorder_;
37}
38
40{
41 (void)recorder_;
42 assert(recorder == &recorder_);
43 recorder = nullptr;
44}
45
46void StateChangeDistributor::distribute(const StateChange& event) const
47{
48 // Iterate over a copy because signalStateChange() may indirect call
49 // back into registerListener().
50 // e.g. signalStateChange() -> .. -> PlugCmd::execute() -> .. ->
51 // Connector::plug() -> .. -> Joystick::plugHelper() ->
52 // registerListener()
53 auto copy = listeners;
54 for (auto& l : copy) {
55 if (isRegistered(l)) {
56 // it's possible the listener unregistered itself
57 // (but is still present in the copy)
58 l->signalStateChange(event); // might throw
59 }
60 }
61}
62
63void StateChangeDistributor::stopReplay(EmuTime::param time)
64{
65 if (!isReplaying()) return;
66
67 if (recorder) recorder->stopReplay(time);
68 for (auto& l : listeners) {
69 l->stopReplay(time);
70 }
71}
72
74{
75 if (recorder) {
76 return recorder->isReplaying();
77 }
78 return false;
79}
80
81} // 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:11
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