Add fast forward in rewind to avoid android hangs

This commit is contained in:
Benau 2019-02-01 17:22:41 +08:00
parent ae92d63492
commit 52ad702d13
7 changed files with 39 additions and 24 deletions

View File

@ -303,7 +303,7 @@ void InputManager::handleStaticAction(int key, int value)
fgets(s, 256, stdin);
int t;
StringUtils::fromString(s,t);
RewindManager::get()->rewindTo(t, world->getTicksSinceStart());
RewindManager::get()->rewindTo(t, world->getTicksSinceStart(), false);
Log::info("Rewind", "Rewinding from %d to %d",
world->getTicksSinceStart(), t);
}

View File

@ -198,15 +198,17 @@ float MainLoop::getLimitedDt()
//-----------------------------------------------------------------------------
/** Updates all race related objects.
* \param ticks Number of ticks (physics steps) to simulate - should be 1.
* \param fast_forward If true, then only rewinders in network will be
* updated, but not the physics.
*/
void MainLoop::updateRace(int ticks)
void MainLoop::updateRace(int ticks, bool fast_forward)
{
if (!World::getWorld()) return; // No race on atm - i.e. we are in menu
// The race event manager will update world in case of an online race
if ( RaceEventManager::getInstance() &&
RaceEventManager::getInstance()->isRunning() )
RaceEventManager::getInstance()->update(ticks);
RaceEventManager::getInstance()->update(ticks, fast_forward);
else
World::getWorld()->updateWorld(ticks);
} // updateRace
@ -454,6 +456,11 @@ void MainLoop::run()
}
m_ticks_adjustment.unlock();
// Avoid hang when some function in world takes too long time or
// when leave / come back from android home button
bool fast_forward = NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isClient() &&
num_steps > stk_config->time2Ticks(1.0f);
for (int i = 0; i < num_steps; i++)
{
if (World::getWorld() && history->replayHistory())
@ -473,7 +480,7 @@ void MainLoop::run()
PROFILER_PUSH_CPU_MARKER("Update race", 0, 255, 255);
if (World::getWorld())
{
updateRace(1);
updateRace(1, fast_forward);
}
PROFILER_POP_CPU_MARKER();

View File

@ -48,7 +48,7 @@ private:
uint64_t m_prev_time;
unsigned m_parent_pid;
float getLimitedDt();
void updateRace(int ticks);
void updateRace(int ticks, bool fast_forward);
public:
MainLoop(unsigned parent_pid);
~MainLoop();

View File

@ -22,17 +22,20 @@ RaceEventManager::~RaceEventManager()
/** In network games this update function is called instead of
* World::updateWorld().
* \param ticks Number of physics time steps - should be 1.
* \param fast_forward If true, then only rewinders in network will be
* updated, but not the physics.
*/
void RaceEventManager::update(int ticks)
void RaceEventManager::update(int ticks, bool fast_forward)
{
// Replay all recorded events up to the current time
// This might adjust dt - if a new state is being played, the dt is
// determined from the last state till 'now'
PROFILER_PUSH_CPU_MARKER("RaceEvent:play event", 100, 100, 100);
RewindManager::get()->playEventsTill(World::getWorld()->getTicksSinceStart(),
&ticks);
fast_forward);
PROFILER_POP_CPU_MARKER();
World::getWorld()->updateWorld(ticks);
if (!fast_forward)
World::getWorld()->updateWorld(ticks);
} // update
// ----------------------------------------------------------------------------

View File

@ -49,7 +49,7 @@ private:
public:
// ------------------------------------------------------------------------
void update(int ticks);
void update(int ticks, bool fast_forward);
// ------------------------------------------------------------------------
void start(std::shared_ptr<GameEventsProtocol> gep)
{

View File

@ -216,9 +216,10 @@ void RewindManager::update(int ticks_not_used)
// ----------------------------------------------------------------------------
/** Replays all events from the last event played till the specified time.
* \param world_ticks Up to (and inclusive) which time events will be replayed.
* \param ticks Number of time steps - should be 1.
* \param fast_forward If true, then only rewinders in network will be
* updated, but not the physics.
*/
void RewindManager::playEventsTill(int world_ticks, int *ticks)
void RewindManager::playEventsTill(int world_ticks, bool fast_forward)
{
// We add the RewindInfoEventFunction to rewind queue before and after
// possible rewind, some RewindInfoEventFunction can be created during
@ -237,7 +238,7 @@ void RewindManager::playEventsTill(int world_ticks, int *ticks)
{
Log::setPrefix("Rewind");
PROFILER_PUSH_CPU_MARKER("Rewind", 128, 128, 128);
rewindTo(rewind_ticks, world_ticks);
rewindTo(rewind_ticks, world_ticks, fast_forward);
// This should replay everything up to 'now'
assert(World::getWorld()->getTicksSinceStart() == world_ticks);
PROFILER_POP_CPU_MARKER();
@ -279,8 +280,11 @@ bool RewindManager::addRewinder(std::shared_ptr<Rewinder> rewinder)
* \param 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).
* \param fast_forward If true, then only rewinders in network will be
* updated, but not the physics.
*/
void RewindManager::rewindTo(int rewind_ticks, int now_ticks)
void RewindManager::rewindTo(int rewind_ticks, int now_ticks,
bool fast_forward)
{
assert(!m_is_rewinding);
bool is_history = history->replayHistory();
@ -335,7 +339,7 @@ void RewindManager::rewindTo(int rewind_ticks, int now_ticks)
break;
}
}
else
else if (!fast_forward)
{
Log::warn("RewindManager", "Missing local state at ticks %d",
exact_rewind_ticks);
@ -356,7 +360,8 @@ void RewindManager::rewindTo(int rewind_ticks, int now_ticks)
m_rewind_queue.replayAllEvents(world->getTicksSinceStart());
// Now simulate the next time step
world->updateWorld(1);
if (!fast_forward)
world->updateWorld(1);
#undef SHOW_ROLLBACK
#ifdef SHOW_ROLLBACK
irr_driver->update(stk_config->ticks2Time(1));

View File

@ -158,8 +158,8 @@ public:
void reset();
void update(int ticks);
void rewindTo(int target_ticks, int ticks_now);
void playEventsTill(int world_ticks, int *ticks);
void rewindTo(int target_ticks, int ticks_now, bool fast_forward);
void playEventsTill(int world_ticks, bool fast_forward);
void addEvent(EventRewinder *event_rewinder, BareNetworkString *buffer,
bool confirmed, int ticks = -1);
void addNetworkEvent(EventRewinder *event_rewinder,