openMSX
ReverseManager.hh
Go to the documentation of this file.
1 #ifndef REVERSEMANGER_HH
2 #define REVERSEMANGER_HH
3 
4 #include "Schedulable.hh"
5 #include "EventListener.hh"
6 #include "StateChangeListener.hh"
7 #include "EmuTime.hh"
8 #include "MemBuffer.hh"
9 #include "array_ref.hh"
10 #include <vector>
11 #include <map>
12 #include <memory>
13 #include <cstdint>
14 
15 namespace openmsx {
16 
17 class MSXMotherBoard;
18 class Keyboard;
19 class EventDelay;
20 class EventDistributor;
21 class ReverseCmd;
22 class TclObject;
23 class Interpreter;
24 
25 class ReverseManager final : private Schedulable, private EventListener
26  , private StateChangeRecorder
27 {
28 public:
29  ReverseManager(MSXMotherBoard& motherBoard);
31 
32  // Keyboard is special because we need to transfer the host keyboard
33  // state on 'reverse goto' to be able to resynchronize when replay
34  // stops. See Keyboard::transferHostKeyMatrix() for more info.
35  void registerKeyboard(Keyboard& keyboard_) {
36  keyboard = &keyboard_;
37  }
38 
39  // To not loose any events we need to flush delayed events before
40  // switching machine. See comments in goTo() for more info.
41  void registerEventDelay(EventDelay& eventDelay_) {
42  eventDelay = &eventDelay_;
43  }
44 
45  // Should only be used by MSXMotherBoard to be able to transfer
46  // reRecordCount to ReverseManager for version 2 of MSXMotherBoard
47  // serializers.
48  void setReRecordCount(unsigned count) {
49  reRecordCount = count;
50  }
51 
52 private:
53  struct ReverseChunk {
54  ReverseChunk();
55  ReverseChunk(ReverseChunk&& rhs);
56  ReverseChunk& operator=(ReverseChunk&& rhs);
57 
58  EmuTime time;
59  MemBuffer<uint8_t> savestate;
60 
61  // Number of recorded events (or replay index) when this
62  // snapshot was created. So when going back replay should
63  // start at this index.
64  unsigned eventCount;
65  };
66  typedef std::map<unsigned, ReverseChunk> Chunks;
67  typedef std::vector<std::shared_ptr<StateChange>> Events;
68 
69  struct ReverseHistory {
70  void swap(ReverseHistory& other);
71  void clear();
72  unsigned getNextSeqNum(EmuTime::param time) const;
73 
74  Chunks chunks;
75  Events events;
76  };
77 
78  bool isCollecting() const { return collecting; }
79 
80  void start();
81  void stop();
82  void status(TclObject& result) const;
83  void debugInfo(TclObject& result) const;
84  void goBack(array_ref<TclObject> tokens);
85  void goTo(array_ref<TclObject> tokens);
86  void saveReplay(array_ref<TclObject> tokens, TclObject& result);
87  void loadReplay(Interpreter& interp,
88  array_ref<TclObject> tokens, TclObject& result);
89 
90  void signalStopReplay(EmuTime::param time);
91  EmuTime::param getEndTime(const ReverseHistory& history) const;
92  void goTo(EmuTime::param targetTime, bool novideo);
93  void goTo(EmuTime::param targetTime, bool novideo,
94  ReverseHistory& history, bool sameTimeLine);
95  void transferHistory(ReverseHistory& oldHistory,
96  unsigned oldEventCount);
97  void transferState(MSXMotherBoard& newBoard);
98  void takeSnapshot(EmuTime::param time);
99  void schedule(EmuTime::param time);
100  void replayNextEvent();
101  template<unsigned N> void dropOldSnapshots(unsigned count);
102 
103  // Schedulable
104  void executeUntil(EmuTime::param time, int userData) override;
105 
106  // EventListener
107  int signalEvent(const std::shared_ptr<const Event>& event) override;
108 
109  // StateChangeRecorder
110  void signalStateChange(const std::shared_ptr<StateChange>& event) override;
111  void stopReplay(EmuTime::param time) override;
112  bool isReplaying() const override;
113 
114  MSXMotherBoard& motherBoard;
115  EventDistributor& eventDistributor;
116  const std::unique_ptr<ReverseCmd> reverseCmd;
117  Keyboard* keyboard;
118  EventDelay* eventDelay;
119  ReverseHistory history;
120  unsigned replayIndex;
121  bool collecting;
122  bool pendingTakeSnapshot;
123 
124  unsigned reRecordCount;
125 
126  friend class ReverseCmd;
127  friend struct Replay;
128 };
129 
130 } // namespace openmsx
131 
132 #endif
This class is responsible for translating host events into MSX events.
Definition: EventDelay.hh:27
void registerEventDelay(EventDelay &eventDelay_)
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:16
void registerKeyboard(Keyboard &keyboard_)
This class implements a subset of the proposal for std::array_ref (proposed for the next c++ standard...
Definition: array_ref.hh:19
ReverseManager(MSXMotherBoard &motherBoard)
void setReRecordCount(unsigned count)
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:7
const EmuTime & param
Definition: EmuTime.hh:20