Store event time explicitly, which makes network replay much easier.

Simplified update updateReplayAndGetDT function.
This commit is contained in:
hiker 2018-01-16 08:43:59 +11:00
parent 7b21bb16e6
commit 8d7ff2a948
2 changed files with 70 additions and 54 deletions

View File

@ -87,6 +87,7 @@ void History::addEvent(int kart_id, PlayerAction pa, int value)
// The event is added before m_current is increased. So in order to // The event is added before m_current is increased. So in order to
// save the right index for this event, we need to use m_current+1. // save the right index for this event, we need to use m_current+1.
ie.m_index = m_current+1; ie.m_index = m_current+1;
ie.m_time = World::getWorld()->getTime();
ie.m_action = pa; ie.m_action = pa;
ie.m_value = value; ie.m_value = value;
ie.m_kart_index = kart_id; ie.m_kart_index = kart_id;
@ -131,72 +132,85 @@ void History::updateSaving(float dt)
*/ */
float History::updateReplayAndGetDT(float world_time, float dt) float History::updateReplayAndGetDT(float world_time, float dt)
{ {
if (m_history_time > world_time && NetworkConfig::get()->isNetworking())
return dt;
World *world = World::getWorld(); World *world = World::getWorld();
// Networking
// In non-networked history races, we need to do at least one timestep // ----------
// to get the right DT. The while loop is exited at the bottom in this // Networking is handled differently, it only uses the events,
// case/ // not the recorded time steps.
while (m_history_time < world_time + dt || if (NetworkConfig::get()->isNetworking())
!NetworkConfig::get()->isNetworking() )
{ {
m_current++; while (m_event_index < m_all_input_events.size() &&
if (m_current >= (int)m_all_deltas.size()) m_all_input_events[m_event_index].m_time <= world_time+dt)
{ {
Log::info("History", "Replay finished"); const InputEvent &ie = m_all_input_events[m_event_index];
m_current = 0; AbstractKart *kart = world->getKart(ie.m_kart_index);
m_history_time = 0; Log::verbose("history", "time %f event-time %f action %d %d",
// This is useful to use a reproducable rewind problem: world->getTime(), ie.m_time, ie.m_action, ie.m_value);
// replay it with history, for debugging only kart->getController()->action(ie.m_action, ie.m_value);
m_event_index++;
}
return dt;
}
// Now handle the non-networking case
// ----------------------------------
Log::verbose("history", "Begin %f %f %f %f current %d event %d",
m_history_time, world_time, dt, world_time + dt,
m_current, m_event_index);
m_current++;
Log::verbose("history", "Inner %f %f %f %f current %d event %d",
m_history_time, world_time, dt, world_time + dt,
m_current, m_event_index);
// Check if we have reached the end of the buffer
if (m_current >= (int)m_all_deltas.size())
{
Log::info("History", "Replay finished");
m_current = 0;
m_history_time = 0;
// This is useful to use a reproducable rewind problem:
// replay it with history, for debugging only
#undef DO_REWIND_AT_END_OF_HISTORY #undef DO_REWIND_AT_END_OF_HISTORY
#ifdef DO_REWIND_AT_END_OF_HISTORY #ifdef DO_REWIND_AT_END_OF_HISTORY
RewindManager::get()->rewindTo(5.0f); RewindManager::get()->rewindTo(5.0f);
exit(-1); exit(-1);
#else #else
// Note that for physics replay all physics parameters // Note that for physics replay all physics parameters
// need to be reset, e.g. velocity, ... // need to be reset, e.g. velocity, ...
world->reset(); world->reset();
#endif #endif
} }
if (m_replay_mode == HISTORY_POSITION) if (m_replay_mode == HISTORY_POSITION)
{
unsigned int num_karts = world->getNumKarts();
for (unsigned k = 0; k < num_karts; k++)
{ {
unsigned int num_karts = world->getNumKarts(); AbstractKart *kart = world->getKart(k);
for (unsigned k = 0; k < num_karts; k++) unsigned int index = m_current*num_karts + k;
{ kart->setXYZ(m_all_xyz[index]);
AbstractKart *kart = world->getKart(k); kart->setRotation(m_all_rotations[index]);
unsigned int index = m_current*num_karts + k; } // for k < karts
kart->setXYZ(m_all_xyz[index]); } // if HISTORY_POSITION
kart->setRotation(m_all_rotations[index]); else // HISTORY_PHYSICS
} {
} while (m_event_index < m_all_input_events.size() &&
else // HISTORY_PHYSICS m_all_input_events[m_event_index].m_index == m_current)
{ {
while (m_event_index < m_all_input_events.size() && const InputEvent &ie = m_all_input_events[m_event_index];
m_all_input_events[m_event_index].m_index == m_current) AbstractKart *kart = world->getKart(ie.m_kart_index);
{ Log::verbose("history", "time %f event-time %f action %d %d",
const InputEvent &ie = m_all_input_events[m_event_index]; world->getTime(), ie.m_time, ie.m_action, ie.m_value);
AbstractKart *kart = world->getKart(ie.m_kart_index); kart->getController()->action(ie.m_action, ie.m_value);
kart->getController()->action(ie.m_action, ie.m_value); m_event_index++;
m_event_index++; }
}
//kart->getControls().set(m_all_controls[index]);
} // if HISTORY_PHYSICS
if (World::getWorld()->isRacePhase()) if (World::getWorld()->isRacePhase())
m_history_time += m_all_deltas[m_current]; m_history_time += m_all_deltas[m_current];
// If this is not networked, exit the loop after one iteration
// and return the new dt
if(!NetworkConfig::get()->isNetworking())
return m_all_deltas[m_current];
} }
return m_all_deltas[m_current];
// In network mode, don't adjust dt, just return the input value
return dt;
} // updateReplayAndGetDT } // updateReplayAndGetDT
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -277,10 +291,11 @@ void History::Save()
fprintf(fd, "%d\n", count); fprintf(fd, "%d\n", count);
for (int k = 0; k < count; k++) for (int k = 0; k < count; k++)
{ {
fprintf(fd, "%d %d %d\n", fprintf(fd, "%d %d %d %12.9f\n",
m_all_input_events[event_index].m_kart_index, m_all_input_events[event_index].m_kart_index,
m_all_input_events[event_index].m_action, m_all_input_events[event_index].m_action,
m_all_input_events[event_index].m_value); m_all_input_events[event_index].m_value,
m_all_input_events[event_index].m_time);
event_index++; event_index++;
} }
index=(index+1)%m_size; index=(index+1)%m_size;
@ -421,8 +436,8 @@ void History::Load()
fgets(s, 1023, fd); fgets(s, 1023, fd);
InputEvent ie; InputEvent ie;
ie.m_index = i; ie.m_index = i;
if (sscanf(s, "%d %d %d\n", &ie.m_kart_index, &ie.m_action, if (sscanf(s, "%d %d %d %f\n", &ie.m_kart_index, &ie.m_action,
&ie.m_value) != 3) &ie.m_value, &ie.m_time) != 4)
{ {
Log::warn("History", "Problems reading event: '%s'", s); Log::warn("History", "Problems reading event: '%s'", s);
} }
@ -431,7 +446,6 @@ void History::Load()
} // for i } // for i
RewindManager::setEnable(rewind_manager_was_enabled); RewindManager::setEnable(rewind_manager_was_enabled);
fprintf(fd, "History file end.\n");
fclose(fd); fclose(fd);
} // Load } // Load

View File

@ -89,6 +89,8 @@ private:
{ {
/** Index at which the even happened. */ /** Index at which the even happened. */
int m_index; int m_index;
/* Time at which this event occurred. */
float m_time;
/** For which kart the event was. */ /** For which kart the event was. */
int m_kart_index; int m_kart_index;
/** Which action it was. */ /** Which action it was. */