This class manages rewinding.
More...
#include <rewind_manager.hpp>
|
void | reset () |
| Frees all saved state information and all destroyable rewinder.
|
|
void | update (int ticks) |
| Determines if a new state snapshot should be taken, and if so calls all rewinder to do so. More...
|
|
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: it will replay everything before World::getTime(), but not the events at World::getTime() (or later)/. More...
|
|
void | playEventsTill (int world_ticks, bool fast_forward) |
| Replays all events from the last event played till the specified time. More...
|
|
void | addEvent (EventRewinder *event_rewinder, BareNetworkString *buffer, bool confirmed, int ticks=-1) |
| Adds an event to the rewind data. More...
|
|
void | addNetworkEvent (EventRewinder *event_rewinder, BareNetworkString *buffer, int ticks) |
| Adds an event to the list of network rewind data. More...
|
|
void | addNetworkState (BareNetworkString *buffer, int ticks) |
| Adds a state to the list of network rewind data. More...
|
|
void | saveState () |
| Saves a state using the GameProtocol function to combine several independent rewinders to write one state.
|
|
std::shared_ptr< Rewinder > | getRewinder (const std::string &name) |
|
bool | addRewinder (std::shared_ptr< Rewinder > rewinder) |
| Adds a Rewinder to the list of all rewinders. More...
|
|
bool | isRewinding () const |
| Returns true if currently a rewind is happening. More...
|
|
int | getNotRewoundWorldTicks () const |
|
int | getLatestConfirmedState () const |
| Returns the time of the latest confirmed state. More...
|
|
bool | useLocalEvent () const |
|
void | addRewindInfoEventFunction (RewindInfoEventFunction *rief) |
|
void | addNetworkRewindInfo (RewindInfo *ri) |
|
bool | shouldSaveState (int ticks) |
|
void | resetSmoothNetworkBody () |
|
void | handleResetSmoothNetworkBody () |
| Reset all smooth network body of rewinders so the rubber band effect of moveable does not exist during firstly live join.
|
|
This class manages rewinding.
It keeps track of:
- states for each rewindable object (for example a kart would have its position, rotation, linear and angular velocity etc as state) States can be confirmed (i.e. were received by the network server and are therefore confirmed to be conrrect), or not (just a snapshot on this client, which can save time in rewinding later).
- events for each rewindable object (for example any change in the kart controls, like steering, fire, ... are an event). While states can be discarded (especially unconfirmed ones), e.g. to save space, events will always be kept (in order to allow replaying). For each object that is to be rewinded an instance of Rewinder needs to be declared (usually inside of the object it can rewind). This instance is automatically registered with the RewindManager. All states and events are stored in a RewindInfo object. All RewindInfo objects are stored in a list sorted by time. When a rewind to time T is requested, the following takes place:
- Go back in time: Determine the latest time t_min < T so that each rewindable objects has at least one state before T. For each state that is skipped during this process
undoState()
is being called, and for each event undoEvent()
of the Rewinder.
- Restore state at time
t_min
For each Rewinder the state at time t_min is restored by calling rewindToState(char *)
. TODO: atm there is no guarantee that each object will have a state at a given time. We either need to work around that, or make sure to store at least an unconfirmed state whenever we receive a confirmed state.
- Rerun the simulation till the current time t_current is reached:
- Determine the time
t_next
of the next frame. This is either current_time + 1/60 (physics default time step size), or less if RewindInfo at an earlier time is available). This determines the time step size for the next frame (i.e. t_next - t_current
).
- For all RewindInfo at time t_next call:
restoreState()
if the RewindInfo is a confirmed state
discardState()
if the RewindInfo is an unconfirmed state TODO: still missing, and instead of discard perhaps store a new state??
rewindToEvent()
if the RewindInfo is an event
- Do one step of world simulation, using the updated (confirmed) states and newly set events (e.g. kart input).
◆ ~RewindManager()
RewindManager::~RewindManager |
( |
| ) |
|
|
private |
Frees all saved state information.
Note that the Rewinder data must be freed elsewhere.
◆ addEvent()
Adds an event to the rewind data.
The data to be stored must be allocated and not freed by the caller!
- Parameters
-
time | Time at which the event was recorded. If time is not specified (or set to -1), the current world time is used. |
buffer | Pointer to the event data. |
◆ addNetworkEvent()
Adds an event to the list of network rewind data.
This function is threadsafe so can be called by the network thread. The data is synched to m_rewind_info by the main thread. The data to be stored must be allocated and not freed by the caller!
- Parameters
-
time | Time at which the event was recorded. |
buffer | Pointer to the event data. |
◆ addNetworkState()
Adds a state to the list of network rewind data.
This function is threadsafe so can be called by the network thread. The data is synched to m_rewind_info by the main thread. The data to be stored must be allocated and not freed by the caller!
- Parameters
-
time | Time at which the event was recorded. |
buffer | Pointer to the event data. |
◆ addRewinder()
bool RewindManager::addRewinder |
( |
std::shared_ptr< Rewinder > |
rewinder | ) |
|
Adds a Rewinder to the list of all rewinders.
- Returns
- true If successfully added, false otherwise.
◆ create()
◆ destroy()
void RewindManager::destroy |
( |
| ) |
|
|
static |
◆ get()
Returns the singleton.
This function will not automatically create the singleton.
◆ getLatestConfirmedState()
int RewindManager::getLatestConfirmedState |
( |
| ) |
const |
|
inline |
Returns the time of the latest confirmed state.
◆ isEnabled()
static bool RewindManager::isEnabled |
( |
| ) |
|
|
inlinestatic |
Returns if rewinding is enabled or not.
◆ isRewinding()
bool RewindManager::isRewinding |
( |
| ) |
const |
|
inline |
Returns true if currently a rewind is happening.
◆ playEventsTill()
void RewindManager::playEventsTill |
( |
int |
world_ticks, |
|
|
bool |
fast_forward |
|
) |
| |
Replays all events from the last event played till the specified time.
- Parameters
-
world_ticks | Up to (and inclusive) which time events will be replayed. |
fast_forward | If true, then only rewinders in network will be updated, but not the physics. |
◆ rewindTo()
void RewindManager::rewindTo |
( |
int |
rewind_ticks, |
|
|
int |
now_ticks, |
|
|
bool |
fast_forward |
|
) |
| |
Rewinds to the specified time, then goes forward till the current World::getTime() is reached again: it will replay everything before World::getTime(), but not the events at World::getTime() (or later)/.
- Parameters
-
rewind_ticks | Time to rewind to. |
now_ticks | Up to which ticks events are replayed: up to but EXCLUDING new_ticks (the event at now_ticks are played in the calling subroutine playEventsTill). |
fast_forward | If true, then only rewinders in network will be updated, but not the physics. |
◆ setEnable()
static void RewindManager::setEnable |
( |
bool |
m | ) |
|
|
inlinestatic |
En- or disables rewinding.
◆ update()
void RewindManager::update |
( |
int |
ticks_not_used | ) |
|
Determines if a new state snapshot should be taken, and if so calls all rewinder to do so.
- Parameters
-
ticks_not_used | NUmber of physics time steps - should be 1. |
◆ m_all_rewinder
std::map<std::string, std::weak_ptr<Rewinder> > RewindManager::m_all_rewinder |
|
private |
A list of all objects that can be rewound.
◆ m_enable_rewind_manager
std::atomic_bool RewindManager::m_enable_rewind_manager |
|
staticprivate |
En- or Disable the rewind manager.
This is used to disable storing rewind data in case of local races only.
◆ m_is_rewinding
bool RewindManager::m_is_rewinding |
|
private |
Indicates if currently a rewind is happening.
◆ m_not_rewound_ticks
std::atomic<int> RewindManager::m_not_rewound_ticks |
|
private |
This stores the original World time in ticks during a rewind.
It is used to detect if a client's local time need adjustment to reduce rewinds.
◆ m_overall_state_size
unsigned int RewindManager::m_overall_state_size |
|
private |
Overall amount of memory allocated by states.
◆ m_rewind_manager
◆ m_rewind_queue
The queue that stores all rewind infos.
◆ m_state_frequency
int RewindManager::m_state_frequency |
|
private |
How much time between consecutive state saves.
The documentation for this class was generated from the following files: