32 static constexpr std::string_view
REPLAY_DIR =
"replays";
43 keyboard = &keyboard_;
49 eventDelay = &eventDelay_;
56 reRecordCount = count;
62 template<
typename T,
typename... Args>
66 history.events.push_back(std::make_unique<T>(time, std::forward<Args>(args)...));
67 return *history.events.back();
72 [[nodiscard]]
double getBegin()
const;
73 [[nodiscard]]
double getEnd()
const;
79 EmuTime time = EmuTime::zero();
80 std::vector<std::shared_ptr<DeltaBlock>> deltaBlocks;
89 using Chunks = std::map<unsigned, ReverseChunk>;
90 using Events = std::deque<std::unique_ptr<StateChange>>;
92 struct ReverseHistory {
93 void swap(ReverseHistory& other)
noexcept;
95 [[nodiscard]]
unsigned getNextSeqNum(EmuTime::param time)
const;
99 LastDeltaBlocks lastDeltaBlocks;
104 void status(TclObject& result)
const;
105 void debugInfo(TclObject& result)
const;
106 void goBack(std::span<const TclObject> tokens);
107 void goTo(std::span<const TclObject> tokens);
108 void saveReplay(Interpreter& interp,
109 std::span<const TclObject> tokens, TclObject& result);
110 void loadReplay(Interpreter& interp,
111 std::span<const TclObject> tokens, TclObject& result);
113 void signalStopReplay(EmuTime::param time);
114 [[nodiscard]] EmuTime::param getEndTime(
const ReverseHistory& history)
const;
115 void goTo(EmuTime::param targetTime,
bool noVideo);
116 void goTo(EmuTime::param targetTime,
bool noVideo,
117 ReverseHistory& history,
bool sameTimeLine);
118 void transferHistory(ReverseHistory& oldHistory,
119 unsigned oldEventCount);
120 void transferState(MSXMotherBoard& newBoard);
121 void takeSnapshot(EmuTime::param time);
122 void schedule(EmuTime::param time);
123 void replayNextEvent();
124 template<
unsigned N>
void dropOldSnapshots(
unsigned count);
128 friend class ReverseManager;
129 explicit SyncNewSnapshot(Scheduler& s) :
Schedulable(s) {}
130 void executeUntil(EmuTime::param )
override {
131 auto& rm =
OUTER(ReverseManager, syncNewSnapshot);
132 rm.execNewSnapshot();
136 friend class ReverseManager;
137 explicit SyncInputEvent(Scheduler& s) :
Schedulable(s) {}
138 void executeUntil(EmuTime::param )
override {
139 auto& rm =
OUTER(ReverseManager, syncInputEvent);
144 void execNewSnapshot();
145 void execInputEvent();
146 [[nodiscard]] EmuTime::param getCurrentTime()
const {
return syncNewSnapshot.getCurrentTime(); }
149 int signalEvent(
const Event& event)
override;
152 MSXMotherBoard& motherBoard;
153 EventDistributor& eventDistributor;
155 struct ReverseCmd final : Command {
156 explicit ReverseCmd(CommandController& controller);
157 void execute(std::span<const TclObject> tokens, TclObject& result)
override;
158 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
159 void tabCompletion(std::vector<std::string>& tokens)
const override;
163 EventDelay* eventDelay =
nullptr;
164 ReverseHistory history;
165 unsigned replayIndex = 0;
166 bool collecting =
false;
167 bool pendingTakeSnapshot =
false;
169 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