34 static constexpr std::string_view
REPLAY_DIR =
"replays";
44 eventDelay = &eventDelay_;
51 reRecordCount = count;
57 template<
typename T,
typename... Args>
61 history.events.push_back(std::make_unique<T>(time, std::forward<Args>(args)...));
62 return *history.events.back();
67 [[nodiscard]]
double getBegin()
const;
68 [[nodiscard]]
double getEnd()
const;
72 return (p.second.time - EmuTime::zero()).toDouble();
78 EmuTime time = EmuTime::zero();
79 std::vector<std::shared_ptr<DeltaBlock>> deltaBlocks;
87 using Chunks = std::map<unsigned, ReverseChunk>;
88 using Events = std::deque<std::unique_ptr<StateChange>>;
90 struct ReverseHistory {
91 void swap(ReverseHistory& other)
noexcept;
93 [[nodiscard]]
unsigned getNextSeqNum(EmuTime::param time)
const;
97 LastDeltaBlocks lastDeltaBlocks;
102 void status(TclObject& result)
const;
103 void debugInfo(TclObject& result)
const;
104 void goBack(std::span<const TclObject> tokens);
105 void goTo(std::span<const TclObject> tokens);
106 void saveReplay(Interpreter& interp,
107 std::span<const TclObject> tokens, TclObject& result);
108 void loadReplay(Interpreter& interp,
109 std::span<const TclObject> tokens, TclObject& result);
111 void signalStopReplay(EmuTime::param time);
112 [[nodiscard]] EmuTime::param getEndTime(
const ReverseHistory& history)
const;
113 void goTo(EmuTime::param targetTime,
bool noVideo);
114 void goTo(EmuTime::param targetTime,
bool noVideo,
115 ReverseHistory& history,
bool sameTimeLine);
116 void transferHistory(ReverseHistory& oldHistory,
117 unsigned oldEventCount);
118 void transferState(MSXMotherBoard& newBoard);
119 void takeSnapshot(EmuTime::param time);
120 void schedule(EmuTime::param time);
121 void replayNextEvent();
122 template<
unsigned N>
void dropOldSnapshots(
unsigned count);
126 friend class ReverseManager;
127 explicit SyncNewSnapshot(Scheduler& s) :
Schedulable(s) {}
128 void executeUntil(EmuTime::param )
override {
129 auto& rm =
OUTER(ReverseManager, syncNewSnapshot);
130 rm.execNewSnapshot();
134 friend class ReverseManager;
135 explicit SyncInputEvent(Scheduler& s) :
Schedulable(s) {}
136 void executeUntil(EmuTime::param )
override {
137 auto& rm =
OUTER(ReverseManager, syncInputEvent);
142 void execNewSnapshot();
143 void execInputEvent();
144 [[nodiscard]] EmuTime::param getCurrentTime()
const {
return syncNewSnapshot.getCurrentTime(); }
147 bool signalEvent(
const Event& event)
override;
150 MSXMotherBoard& motherBoard;
151 EventDistributor& eventDistributor;
153 struct ReverseCmd final : Command {
154 explicit ReverseCmd(CommandController& controller);
155 void execute(std::span<const TclObject> tokens, TclObject& result)
override;
156 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
157 void tabCompletion(std::vector<std::string>& tokens)
const override;
160 EventDelay* eventDelay =
nullptr;
161 ReverseHistory history;
162 unsigned replayIndex = 0;
163 bool collecting =
false;
164 bool pendingTakeSnapshot =
false;
166 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