|
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.
|
|
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)/.
|
|
void | playEventsTill (int world_ticks, bool fast_forward) |
| Replays all events from the last event played till the specified time.
|
|
void | addEvent (EventRewinder *event_rewinder, BareNetworkString *buffer, bool confirmed, int ticks=-1) |
| Adds an event to the rewind data.
|
|
void | addNetworkEvent (EventRewinder *event_rewinder, BareNetworkString *buffer, int ticks) |
| Adds an event to the list of network rewind data.
|
|
void | addNetworkState (BareNetworkString *buffer, int ticks) |
| Adds a state to the list of network rewind data.
|
|
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.
|
|
bool | isRewinding () const |
| Returns true if currently a rewind is happening.
|
|
int | getNotRewoundWorldTicks () const |
|
int | getLatestConfirmedState () const |
| Returns the time of the latest confirmed state.
|
|
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.
|
|
void | addMissingRewinder (const std::string &name) |
|
bool | hasMissingRewinder (const std::string &name) const |
|
|
std::map< int, std::vector< std::function< void()> > > | m_local_state |
|
std::map< std::string, std::weak_ptr< Rewinder > > | m_all_rewinder |
| A list of all objects that can be rewound.
|
|
RewindQueue | m_rewind_queue |
| The queue that stores all rewind infos.
|
|
unsigned int | m_overall_state_size |
| Overall amount of memory allocated by states.
|
|
bool | m_is_rewinding |
| Indicates if currently a rewind is happening.
|
|
int | m_state_frequency |
| How much time between consecutive state saves.
|
|
std::atomic< int > | m_not_rewound_ticks |
| This stores the original World time in ticks during a rewind.
|
|
std::vector< RewindInfoEventFunction * > | m_pending_rief |
|
bool | m_schedule_reset_network_body |
|
std::set< std::string > | m_missing_rewinders |
|
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).