OXYGENHUB
◆ main openmsx / src / fdc / DiskChanger.hh
3.3 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef DISKCHANGER_HH
2
#define DISKCHANGER_HH
3
4
#include "DiskContainer.hh"
5
6
#include "RecordedCommand.hh"
7
#include "StateChangeListener.hh"
8
#include "serialize_meta.hh"
9
10
#include <functional>
11
#include <memory>
12
#include <optional>
13
#include <span>
14
#include <string>
15
16
namespace openmsx {
17
18
class CommandController;
19
class StateChangeDistributor;
20
class Scheduler;
21
class MSXMotherBoard;
22
class Reactor;
23
class Disk;
24
class DiskChanger;
25
class TclObject;
26
class DiskName;
27
28
class DiskCommand final : public Command // TODO RecordedCommand
29
{
30
public:
31
	DiskCommand(CommandController& commandController,
32
	            DiskChanger& diskChanger);
33
	void execute(std::span<const TclObject> tokens,
34
	             TclObject& result) override;
35
	[[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
36
	void tabCompletion(std::vector<std::string>& tokens) const override;
37
	[[nodiscard]] bool needRecord(std::span<const TclObject> tokens) const /*override*/;
38
private:
39
	DiskChanger& diskChanger;
40
};
41
42
class DiskChanger final : public DiskContainer, private StateChangeListener
43
{
44
public:
45
	DiskChanger(MSXMotherBoard& board,
46
	            std::string driveName,
47
	            bool createCmd = true,
48
	            bool doubleSidedDrive = true,
49
	            unsigned nominalTracks = 80,
50
	            std::function<void()> preChangeCallback = {});
51
	DiskChanger(Reactor& reactor,
52
	            std::string driveName); // for virtual_drive
53
	~DiskChanger() override;
54
55
	void createCommand();
56
57
	[[nodiscard]] const std::string& getDriveName() const { return driveName; }
58
	[[nodiscard]] const DiskName& getDiskName() const;
59
	[[nodiscard]] bool peekDiskChanged() const { return diskChangedFlag; }
60
	void forceDiskChange() { diskChangedFlag = true; }
61
	[[nodiscard]]       Disk& getDisk()       { return *disk; }
62
	[[nodiscard]] const Disk& getDisk() const { return *disk; }
63
64
	// DiskContainer
65
	[[nodiscard]] SectorAccessibleDisk* getSectorAccessibleDisk() override;
66
	[[nodiscard]] std::string_view getContainerName() const override;
67
	bool diskChanged() override;
68
	int insertDisk(const std::string& filename) override;
69
70
	// for NowindCommand
71
	void changeDisk(std::unique_ptr<Disk> newDisk);
72
73
	// for DirAsDSK
74
	[[nodiscard]] Scheduler* getScheduler() const { return scheduler; }
75
	[[nodiscard]] bool isDoubleSidedDrive() const { return doubleSidedDrive; }
76
	[[nodiscard]] unsigned getNominalTracks() const { return nominalTracks; }
77
78
	template<typename Archive>
79
	void serialize(Archive& ar, unsigned version);
80
81
private:
82
	void init(std::string_view prefix, bool createCmd);
83
	void execute(std::span<const TclObject> tokens);
84
	void insertDisk(std::span<const TclObject> args);
85
	void ejectDisk();
86
	void sendChangeDiskEvent(std::span<const TclObject> args);
87
88
	// StateChangeListener
89
	void signalStateChange(const StateChange& event) override;
90
	void stopReplay(EmuTime time) noexcept override;
91
92
private:
93
	Reactor& reactor;
94
	CommandController& controller;
95
	StateChangeDistributor* stateChangeDistributor;
96
	Scheduler* scheduler;
97
	std::function<void()> preChangeCallback;
98
99
	const std::string driveName;
100
	std::unique_ptr<Disk> disk;
101
102
	friend class DiskCommand;
103
	std::optional<DiskCommand> diskCommand; // must come after driveName
104
	const bool doubleSidedDrive; // for DirAsDSK
105
	const unsigned nominalTracks; // for DirAsDSK (40 or 80)
106
107
	bool diskChangedFlag;
108
109
	friend class RealDrive;
110
};
111
SERIALIZE_CLASS_VERSION(DiskChanger, 2);
112
113
} // namespace openmsx
114
115
#endif