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,18 +132,38 @@ 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() )
{ {
while (m_event_index < m_all_input_events.size() &&
m_all_input_events[m_event_index].m_time <= world_time+dt)
{
const InputEvent &ie = m_all_input_events[m_event_index];
AbstractKart *kart = world->getKart(ie.m_kart_index);
Log::verbose("history", "time %f event-time %f action %d %d",
world->getTime(), ie.m_time, ie.m_action, ie.m_value);
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++; 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()) if (m_current >= (int)m_all_deltas.size())
{ {
Log::info("History", "Replay finished"); Log::info("History", "Replay finished");
@ -169,8 +190,8 @@ float History::updateReplayAndGetDT(float world_time, float dt)
unsigned int index = m_current*num_karts + k; unsigned int index = m_current*num_karts + k;
kart->setXYZ(m_all_xyz[index]); kart->setXYZ(m_all_xyz[index]);
kart->setRotation(m_all_rotations[index]); kart->setRotation(m_all_rotations[index]);
} } // for k < karts
} } // if HISTORY_POSITION
else // HISTORY_PHYSICS else // HISTORY_PHYSICS
{ {
while (m_event_index < m_all_input_events.size() && while (m_event_index < m_all_input_events.size() &&
@ -178,25 +199,18 @@ float History::updateReplayAndGetDT(float world_time, float dt)
{ {
const InputEvent &ie = m_all_input_events[m_event_index]; const InputEvent &ie = m_all_input_events[m_event_index];
AbstractKart *kart = world->getKart(ie.m_kart_index); AbstractKart *kart = world->getKart(ie.m_kart_index);
Log::verbose("history", "time %f event-time %f action %d %d",
world->getTime(), ie.m_time, ie.m_action, ie.m_value);
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. */