Add initial framework for local state saving
This commit is contained in:
parent
a8959f604c
commit
8515805d52
@ -217,17 +217,25 @@ void RewindManager::update(int ticks_not_used)
|
||||
m_not_rewound_ticks.store(ticks, std::memory_order_relaxed);
|
||||
|
||||
// Clients don't save state, so they just exit.
|
||||
if (NetworkConfig::get()->isClient() ||
|
||||
ticks - m_last_saved_state < m_state_frequency)
|
||||
if (ticks - m_last_saved_state < m_state_frequency)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Save state
|
||||
saveState(/**allow_local_save*/false);
|
||||
PROFILER_PUSH_CPU_MARKER("RewindManager - send state", 0x20, 0x7F, 0x40);
|
||||
if (auto gp = GameProtocol::lock())
|
||||
gp->sendState();
|
||||
if (NetworkConfig::get()->isClient())
|
||||
{
|
||||
auto& ret = m_local_state[ticks];
|
||||
for (Rewinder* r : m_all_rewinder)
|
||||
ret[r] = r->getLocalStateRestoreFunction();
|
||||
}
|
||||
else
|
||||
{
|
||||
saveState(/**allow_local_save*/false);
|
||||
PROFILER_PUSH_CPU_MARKER("RewindManager - send state", 0x20, 0x7F, 0x40);
|
||||
if (auto gp = GameProtocol::lock())
|
||||
gp->sendState();
|
||||
}
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
m_last_saved_state = ticks;
|
||||
} // update
|
||||
@ -323,6 +331,28 @@ void RewindManager::rewindTo(int rewind_ticks, int now_ticks)
|
||||
|
||||
// Restore states from the exact rewind time
|
||||
// -----------------------------------------
|
||||
auto it = m_local_state.find(exact_rewind_ticks);
|
||||
if (it != m_local_state.end())
|
||||
{
|
||||
for (auto& local_state : it->second)
|
||||
{
|
||||
if (local_state.second)
|
||||
local_state.second();
|
||||
}
|
||||
for (auto it = m_local_state.begin(); it != m_local_state.end();)
|
||||
{
|
||||
if (it->first <= exact_rewind_ticks)
|
||||
it = m_local_state.erase(it);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("RewindManager", "Missing local state at ticks %d",
|
||||
exact_rewind_ticks);
|
||||
}
|
||||
|
||||
// A loop in case that we should split states into several smaller ones:
|
||||
while (current && current->getTicks() == exact_rewind_ticks &&
|
||||
current->isState() )
|
||||
|
@ -26,7 +26,8 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class RewindInfo;
|
||||
@ -89,6 +90,8 @@ private:
|
||||
|
||||
typedef std::vector<Rewinder *> AllRewinder;
|
||||
|
||||
std::map<int, std::map<Rewinder*, std::function<void()> > > m_local_state;
|
||||
|
||||
/** A list of all objects that can be rewound. */
|
||||
AllRewinder m_all_rewinder;
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef HEADER_REWINDER_HPP
|
||||
#define HEADER_REWINDER_HPP
|
||||
|
||||
#include <functional>
|
||||
|
||||
class BareNetworkString;
|
||||
|
||||
class Rewinder
|
||||
@ -80,7 +82,9 @@ public:
|
||||
/** True if this rewinder can be destroyed. Karts can not be destroyed,
|
||||
* cakes can. This is used by the RewindManager in reset. */
|
||||
bool canBeDestroyed() const { return m_can_be_destroyed; }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
virtual std::function<void()> getLocalStateRestoreFunction()
|
||||
{ return nullptr; }
|
||||
}; // Rewinder
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user