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;
88 using Chunks = std::map<unsigned, ReverseChunk>;
89 using Events = std::deque<std::unique_ptr<StateChange>>;
91 struct ReverseHistory {
92 void swap(ReverseHistory& other)
noexcept;
94 [[nodiscard]]
unsigned getNextSeqNum(EmuTime::param time)
const;
98 LastDeltaBlocks lastDeltaBlocks;
103 void status(TclObject& result)
const;
104 void debugInfo(TclObject& result)
const;
105 void goBack(std::span<const TclObject> tokens);
106 void goTo(std::span<const TclObject> tokens);
107 void saveReplay(Interpreter& interp,
108 std::span<const TclObject> tokens, TclObject& result);
109 void loadReplay(Interpreter& interp,
110 std::span<const TclObject> tokens, TclObject& result);
112 void signalStopReplay(EmuTime::param time);
113 [[nodiscard]] EmuTime::param getEndTime(
const ReverseHistory& history)
const;
114 void goTo(EmuTime::param targetTime,
bool noVideo);
115 void goTo(EmuTime::param targetTime,
bool noVideo,
116 ReverseHistory& history,
bool sameTimeLine);
117 void transferHistory(ReverseHistory& oldHistory,
118 unsigned oldEventCount);
119 void transferState(MSXMotherBoard& newBoard);
120 void takeSnapshot(EmuTime::param time);
121 void schedule(EmuTime::param time);
122 void replayNextEvent();
123 template<
unsigned N>
void dropOldSnapshots(
unsigned count);
127 friend class ReverseManager;
128 explicit SyncNewSnapshot(Scheduler& s) :
Schedulable(s) {}
129 void executeUntil(EmuTime::param )
override {
130 auto& rm =
OUTER(ReverseManager, syncNewSnapshot);
131 rm.execNewSnapshot();
135 friend class ReverseManager;
136 explicit SyncInputEvent(Scheduler& s) :
Schedulable(s) {}
137 void executeUntil(EmuTime::param )
override {
138 auto& rm =
OUTER(ReverseManager, syncInputEvent);
143 void execNewSnapshot();
144 void execInputEvent();
145 [[nodiscard]] EmuTime::param getCurrentTime()
const {
return syncNewSnapshot.getCurrentTime(); }
148 bool signalEvent(
const Event& event)
override;
151 MSXMotherBoard& motherBoard;
152 EventDistributor& eventDistributor;
154 struct ReverseCmd final : Command {
155 explicit ReverseCmd(CommandController& controller);
156 void execute(std::span<const TclObject> tokens, TclObject& result)
override;
157 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
158 void tabCompletion(std::vector<std::string>& tokens)
const override;
161 EventDelay* eventDelay =
nullptr;
162 ReverseHistory history;
163 unsigned replayIndex = 0;
164 bool collecting =
false;
165 bool pendingTakeSnapshot =
false;
167 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