openMSX
StateChangeDistributor.cc
Go to the documentation of this file.
2 #include "StateChangeListener.hh"
3 #include "StateChange.hh"
4 #include "stl.hh"
5 #include <cassert>
6 
7 namespace openmsx {
8 
10 {
11  assert(listeners.empty());
12 }
13 
14 bool 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 
43 void 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 
60 void 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.
Definition: StateChange.hh:20
This file implemented 3 utility functions:
Definition: Autofire.cc:9
auto copy(InputRange &&range, OutputIter out)
Definition: ranges.hh:178
void move_pop_back(VECTOR &v, typename VECTOR::iterator it)
Erase the pointed to element from the given vector.
Definition: stl.hh:133
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:108
constexpr bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
Definition: stl.hh:31