OXYGENHUB
◆ main openmsx / src / input / StateChangeDistributor.cc
1.8 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "StateChangeDistributor.hh"
2
3
#include "StateChange.hh"
4
#include "StateChangeListener.hh"
5
6
#include "stl.hh"
7
8
#include <cassert>
9
10
namespace openmsx {
11
12
StateChangeDistributor::~StateChangeDistributor()
13
{
14
	assert(listeners.empty());
15
}
16
17
bool StateChangeDistributor::isRegistered(StateChangeListener* listener) const
18
{
19
	return contains(listeners, listener);
20
}
21
22
void StateChangeDistributor::registerListener(StateChangeListener& listener)
23
{
24
	assert(!isRegistered(&listener));
25
	listeners.push_back(&listener);
26
}
27
28
void StateChangeDistributor::unregisterListener(StateChangeListener& listener)
29
{
30
	move_pop_back(listeners, rfind_unguarded(listeners, &listener));
31
}
32
33
void StateChangeDistributor::registerRecorder(ReverseManager& recorder_)
34
{
35
	assert(!recorder);
36
	recorder = &recorder_;
37
}
38
39
void StateChangeDistributor::unregisterRecorder(ReverseManager& recorder_)
40
{
41
	(void)recorder_;
42
	assert(recorder == &recorder_);
43
	recorder = nullptr;
44
}
45
46
void 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
63
void StateChangeDistributor::stopReplay(EmuTime 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
73
bool StateChangeDistributor::isReplaying() const
74
{
75
	if (recorder) {
76
		return recorder->isReplaying();
77
	}
78
	return false;
79
}
80
81
} // namespace openmsx