OXYGENHUB
◆ main openmsx / src / Schedulable.hh
2.8 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef SCHEDULABLE_HH
2
#define SCHEDULABLE_HH
3
4
#include "EmuTime.hh"
5
#include "serialize.hh"
6
#include "serialize_meta.hh"
7
#include "serialize_stl.hh"
8
9
#include <cassert>
10
#include <optional>
11
#include <vector>
12
13
namespace openmsx {
14
15
class Scheduler;
16
17
// For backwards-compatible savestates
18
struct SyncPointBW
19
{
20
	template<typename Archive>
21
	void serialize(Archive& ar, unsigned /*version*/) {
22
		assert(Archive::IS_LOADER);
23
		ar.serialize("time", time,
24
		             "type", userData);
25
	}
26
27
	EmuTime time = EmuTime::zero();
28
	int userData = 0;
29
};
30
31
/**
32
 * Every class that wants to get scheduled at some point must inherit from
33
 * this class.
34
 */
35
class Schedulable
36
{
37
public:
38
	Schedulable(const Schedulable&) = delete;
39
	Schedulable(Schedulable&&) = delete;
40
	Schedulable& operator=(const Schedulable&) = delete;
41
	Schedulable& operator=(Schedulable&&) = delete;
42
43
	/**
44
	 * When the previously registered syncPoint is reached, this
45
	 * method gets called.
46
	 */
47
	virtual void executeUntil(EmuTime time) = 0;
48
49
	/**
50
	 * Just before the the Scheduler is deleted, it calls this method of
51
	 * all the Schedulables that are still registered.
52
	 * If you override this method you should unregister this Schedulable
53
	 * in the implementation. The default implementation just prints a
54
	 * diagnostic (and soon after the Scheduler will trigger an assert that
55
	 * there are still registered Schedulables.
56
	 * Normally there are easier ways to unregister a Schedulable. ATM this
57
	 * method is only used in AfterCommand (because it's not part of the
58
	 * MSX machine).
59
	 */
60
	virtual void schedulerDeleted();
61
62
	[[nodiscard]] Scheduler& getScheduler() const { return scheduler; }
63
64
	/** Convenience method:
65
	  * This is the same as getScheduler().getCurrentTime(). */
66
	[[nodiscard]] EmuTime getCurrentTime() const;
67
68
	[[nodiscard]] std::optional<EmuTime> isPending() const;
69
70
	template<typename Archive>
71
	void serialize(Archive& ar, unsigned version);
72
73
	template<typename Archive>
74
	static std::vector<SyncPointBW> serializeBW(Archive& ar) {
75
		assert(Archive::IS_LOADER);
76
		ar.beginTag("Schedulable");
77
		std::vector<SyncPointBW> result;
78
		ar.serialize("syncPoints", result);
79
		ar.endTag("Schedulable");
80
		return result;
81
	}
82
	template<typename Archive>
83
	static void restoreOld(Archive& ar, std::vector<Schedulable*> schedulables) {
84
		assert(Archive::IS_LOADER);
85
		for (auto* s : schedulables) {
86
			s->removeSyncPoints();
87
		}
88
		for (auto& old : serializeBW(ar)) {
89
			unsigned i = old.userData;
90
			if (i < schedulables.size()) {
91
				schedulables[i]->setSyncPoint(old.time);
92
			}
93
		}
94
	}
95
96
protected:
97
	explicit Schedulable(Scheduler& scheduler);
98
	~Schedulable();
99
100
	void setSyncPoint(EmuTime timestamp);
101
	bool removeSyncPoint();
102
	void removeSyncPoints();
103
104
private:
105
	Scheduler& scheduler;
106
};
107
REGISTER_BASE_CLASS(Schedulable, "Schedulable");
108
109
} // namespace openmsx
110
111
#endif