SuperTuxKart
rewind_manager.hpp
1 //
2 // SuperTuxKart - a fun racing game with go-kart
3 // Copyright (C) 2013 Joerg Henrichs
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 3
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 #ifndef HEADER_REWIND_MANAGER_HPP
20 #define HEADER_REWIND_MANAGER_HPP
21 
22 #include "network/rewind_queue.hpp"
23 #include "utils/stk_process.hpp"
24 
25 #include <assert.h>
26 #include <atomic>
27 #include <functional>
28 #include <memory>
29 #include <map>
30 #include <set>
31 #include <string>
32 #include <vector>
33 
34 class Rewinder;
35 class RewindInfo;
37 class EventRewinder;
38 
85 {
86 private:
88  static RewindManager *m_rewind_manager[PT_COUNT];
89 
92  static std::atomic_bool m_enable_rewind_manager;
93 
94  std::map<int, std::vector<std::function<void()> > > m_local_state;
95 
97  std::map<std::string, std::weak_ptr<Rewinder> > m_all_rewinder;
98 
101 
103  unsigned int m_overall_state_size;
104 
107 
110 
114  std::atomic<int> m_not_rewound_ticks;
115 
116  std::vector<RewindInfoEventFunction*> m_pending_rief;
117 
118  bool m_schedule_reset_network_body;
119 
120  std::set<std::string> m_missing_rewinders;
121 
122  RewindManager();
123  ~RewindManager();
124  // ------------------------------------------------------------------------
125  void clearExpiredRewinder()
126  {
127  for (auto it = m_all_rewinder.begin(); it != m_all_rewinder.end();)
128  {
129  if (it->second.expired())
130  {
131  it = m_all_rewinder.erase(it);
132  continue;
133  }
134  it++;
135  }
136  }
137  // ------------------------------------------------------------------------
138  void mergeRewindInfoEventFunction();
139 
140 public:
141  // First static functions to manage rewinding.
142  // ===========================================
143  static RewindManager *create();
144  static void destroy();
145  // ------------------------------------------------------------------------
147  static void setEnable(bool m) { m_enable_rewind_manager = m; }
148  // ------------------------------------------------------------------------
150  static bool isEnabled() { return m_enable_rewind_manager; }
151  // ------------------------------------------------------------------------
152  static bool exists()
153  {
154  ProcessType pt = STKProcess::getType();
155  return m_rewind_manager[pt] != NULL;
156  } // exists
157  // ------------------------------------------------------------------------
160  static RewindManager *get()
161  {
162  ProcessType pt = STKProcess::getType();
163  assert(m_rewind_manager[pt]);
164  return m_rewind_manager[pt];
165  } // get
166 
167  // Non-static function declarations:
168 
169  void reset();
170  void update(int ticks);
171  void rewindTo(int target_ticks, int ticks_now, bool fast_forward);
172  void playEventsTill(int world_ticks, bool fast_forward);
173  void addEvent(EventRewinder *event_rewinder, BareNetworkString *buffer,
174  bool confirmed, int ticks = -1);
175  void addNetworkEvent(EventRewinder *event_rewinder,
176  BareNetworkString *buffer, int ticks);
177  void addNetworkState(BareNetworkString *buffer, int ticks);
178  void saveState();
179  // ------------------------------------------------------------------------
180  std::shared_ptr<Rewinder> getRewinder(const std::string& name)
181  {
182  auto it = m_all_rewinder.find(name);
183  if (it != m_all_rewinder.end())
184  {
185  if (auto r = it->second.lock())
186  return r;
187  }
188  return nullptr;
189  }
190  // ------------------------------------------------------------------------
191  bool addRewinder(std::shared_ptr<Rewinder> rewinder);
192  // ------------------------------------------------------------------------
194  bool isRewinding() const { return m_is_rewinding; }
195 
196  // ------------------------------------------------------------------------
197  int getNotRewoundWorldTicks() const
198  {
199  return m_not_rewound_ticks.load(std::memory_order_relaxed);
200  } // getNotRewoundWorldTicks
201  // ------------------------------------------------------------------------
204  {
206  } // getLatestConfirmedState
207  // ------------------------------------------------------------------------
208  bool useLocalEvent() const;
209  // ------------------------------------------------------------------------
210  void addRewindInfoEventFunction(RewindInfoEventFunction* rief)
211  { m_pending_rief.push_back(rief); }
212  // ------------------------------------------------------------------------
213  void addNetworkRewindInfo(RewindInfo* ri)
214  { m_rewind_queue.addNetworkRewindInfo(ri); }
215  // ------------------------------------------------------------------------
216  bool shouldSaveState(int ticks)
217  {
218  int a = ticks - m_state_frequency + 1;
219  return ticks != 0 && a >= 0 && a % m_state_frequency == 0;
220  }
221  // ------------------------------------------------------------------------
222  void resetSmoothNetworkBody() { m_schedule_reset_network_body = true; }
223  // ------------------------------------------------------------------------
225  // ------------------------------------------------------------------------
226  void addMissingRewinder(const std::string& name)
227  { m_missing_rewinders.insert(name); }
228  // ------------------------------------------------------------------------
229  bool hasMissingRewinder(const std::string& name) const
230  { return m_missing_rewinders.find(name) != m_missing_rewinders.end(); }
231 
232 }; // RewindManager
233 
234 
235 #endif
236 
Describes a chain of 8-bit unsigned integers.
Definition: network_string.hpp:53
A simple class that defines an interface to event rewinding: an undo() function when going back in ti...
Definition: event_rewinder.hpp:29
Definition: rewind_info.hpp:182
Used to store rewind information for a given time for all rewind instances.
Definition: rewind_info.hpp:45
This class manages rewinding.
Definition: rewind_manager.hpp:85
void handleResetSmoothNetworkBody()
Reset all smooth network body of rewinders so the rubber band effect of moveable does not exist durin...
Definition: rewind_manager.cpp:429
std::map< std::string, std::weak_ptr< Rewinder > > m_all_rewinder
A list of all objects that can be rewound.
Definition: rewind_manager.hpp:97
bool m_is_rewinding
Indicates if currently a rewind is happening.
Definition: rewind_manager.hpp:106
static RewindManager * m_rewind_manager[PT_COUNT]
Singleton pointer.
Definition: rewind_manager.hpp:88
int getLatestConfirmedState() const
Returns the time of the latest confirmed state.
Definition: rewind_manager.hpp:203
static std::atomic_bool m_enable_rewind_manager
En- or Disable the rewind manager.
Definition: rewind_manager.hpp:92
static RewindManager * get()
Returns the singleton.
Definition: rewind_manager.hpp:160
void rewindTo(int target_ticks, int ticks_now, bool fast_forward)
Rewinds to the specified time, then goes forward till the current World::getTime() is reached again: ...
Definition: rewind_manager.cpp:294
void saveState()
Saves a state using the GameProtocol function to combine several independent rewinders to write one s...
Definition: rewind_manager.cpp:155
void addNetworkState(BareNetworkString *buffer, int ticks)
Adds a state to the list of network rewind data.
Definition: rewind_manager.cpp:145
unsigned int m_overall_state_size
Overall amount of memory allocated by states.
Definition: rewind_manager.hpp:103
RewindManager()
The constructor.
Definition: rewind_manager.cpp:65
void update(int ticks)
Determines if a new state snapshot should be taken, and if so calls all rewinder to do so.
Definition: rewind_manager.cpp:189
static void setEnable(bool m)
En- or disables rewinding.
Definition: rewind_manager.hpp:147
int m_state_frequency
How much time between consecutive state saves.
Definition: rewind_manager.hpp:109
void addNetworkEvent(EventRewinder *event_rewinder, BareNetworkString *buffer, int ticks)
Adds an event to the list of network rewind data.
Definition: rewind_manager.cpp:131
static RewindManager * create()
Creates the singleton.
Definition: rewind_manager.cpp:44
void playEventsTill(int world_ticks, bool fast_forward)
Replays all events from the last event played till the specified time.
Definition: rewind_manager.cpp:230
static void destroy()
Destroys the singleton.
Definition: rewind_manager.cpp:54
~RewindManager()
Frees all saved state information.
Definition: rewind_manager.cpp:74
static bool isEnabled()
Returns if rewinding is enabled or not.
Definition: rewind_manager.hpp:150
std::atomic< int > m_not_rewound_ticks
This stores the original World time in ticks during a rewind.
Definition: rewind_manager.hpp:114
bool addRewinder(std::shared_ptr< Rewinder > rewinder)
Adds a Rewinder to the list of all rewinders.
Definition: rewind_manager.cpp:273
bool isRewinding() const
Returns true if currently a rewind is happening.
Definition: rewind_manager.hpp:194
void reset()
Frees all saved state information and all destroyable rewinder.
Definition: rewind_manager.cpp:84
void addEvent(EventRewinder *event_rewinder, BareNetworkString *buffer, bool confirmed, int ticks=-1)
Adds an event to the rewind data.
Definition: rewind_manager.cpp:107
RewindQueue m_rewind_queue
The queue that stores all rewind infos.
Definition: rewind_manager.hpp:100
Definition: rewind_queue.hpp:37
int getLatestConfirmedState() const
Returns the time of the latest confirmed state.
Definition: rewind_queue.hpp:89
Definition: rewinder.hpp:44