35 static constexpr std::string_view
REPLAY_DIR =
"replays";
46 keyboard = &keyboard_;
52 eventDelay = &eventDelay_;
59 reRecordCount = count;
65 template<
typename T,
typename... Args>
69 history.events.push_back(std::make_unique<T>(time, std::forward<Args>(args)...));
70 return *history.events.back();
75 [[nodiscard]]
double getBegin()
const;
76 [[nodiscard]]
double getEnd()
const;
80 return (p.second.time - EmuTime::zero()).toDouble();
86 EmuTime time = EmuTime::zero();
87 std::vector<std::shared_ptr<DeltaBlock>> deltaBlocks;
96 using Chunks = std::map<unsigned, ReverseChunk>;
97 using Events = std::deque<std::unique_ptr<StateChange>>;
99 struct ReverseHistory {
100 void swap(ReverseHistory& other)
noexcept;
102 [[nodiscard]]
unsigned getNextSeqNum(EmuTime::param time)
const;
106 LastDeltaBlocks lastDeltaBlocks;
111 void status(TclObject& result)
const;
112 void debugInfo(TclObject& result)
const;
113 void goBack(std::span<const TclObject> tokens);
114 void goTo(std::span<const TclObject> tokens);
115 void saveReplay(Interpreter& interp,
116 std::span<const TclObject> tokens, TclObject& result);
117 void loadReplay(Interpreter& interp,
118 std::span<const TclObject> tokens, TclObject& result);
120 void signalStopReplay(EmuTime::param time);
121 [[nodiscard]] EmuTime::param getEndTime(
const ReverseHistory& history)
const;
122 void goTo(EmuTime::param targetTime,
bool noVideo);
123 void goTo(EmuTime::param targetTime,
bool noVideo,
124 ReverseHistory& history,
bool sameTimeLine);
125 void transferHistory(ReverseHistory& oldHistory,
126 unsigned oldEventCount);
127 void transferState(MSXMotherBoard& newBoard);
128 void takeSnapshot(EmuTime::param time);
129 void schedule(EmuTime::param time);
130 void replayNextEvent();
131 template<
unsigned N>
void dropOldSnapshots(
unsigned count);
135 friend class ReverseManager;
136 explicit SyncNewSnapshot(Scheduler& s) :
Schedulable(s) {}
137 void executeUntil(EmuTime::param )
override {
138 auto& rm =
OUTER(ReverseManager, syncNewSnapshot);
139 rm.execNewSnapshot();
143 friend class ReverseManager;
144 explicit SyncInputEvent(Scheduler& s) :
Schedulable(s) {}
145 void executeUntil(EmuTime::param )
override {
146 auto& rm =
OUTER(ReverseManager, syncInputEvent);
151 void execNewSnapshot();
152 void execInputEvent();
153 [[nodiscard]] EmuTime::param getCurrentTime()
const {
return syncNewSnapshot.getCurrentTime(); }
156 bool signalEvent(
const Event& event)
override;
159 MSXMotherBoard& motherBoard;
160 EventDistributor& eventDistributor;
162 struct ReverseCmd final : Command {
163 explicit ReverseCmd(CommandController& controller);
164 void execute(std::span<const TclObject> tokens, TclObject& result)
override;
165 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
166 void tabCompletion(std::vector<std::string>& tokens)
const override;
170 EventDelay* eventDelay =
nullptr;
171 ReverseHistory history;
172 unsigned replayIndex = 0;
173 bool collecting =
false;
174 bool pendingTakeSnapshot =
false;
176 unsigned reRecordCount = 0;
std::variant< KeyUpEvent, KeyDownEvent, MouseMotionEvent, MouseButtonUpEvent, MouseButtonDownEvent, MouseWheelEvent, JoystickAxisMotionEvent, JoystickHatEvent, JoystickButtonUpEvent, JoystickButtonDownEvent, OsdControlReleaseEvent, OsdControlPressEvent, WindowEvent, TextEvent, FileDropEvent, QuitEvent, FinishFrameEvent, CliCommandEvent, GroupEvent, BootEvent, FrameDrawnEvent, BreakEvent, SwitchRendererEvent, TakeReverseSnapshotEvent, AfterTimedEvent, MachineLoadedEvent, MachineActivatedEvent, MachineDeactivatedEvent, MidiInReaderEvent, MidiInWindowsEvent, MidiInCoreMidiEvent, MidiInCoreMidiVirtualEvent, MidiInALSAEvent, Rs232TesterEvent, Rs232NetEvent, ImGuiDelayedActionEvent, ImGuiActiveEvent > Event