Progressively adjust time with slow down functionality
This commit is contained in:
parent
e28fbdd019
commit
7926ad9ba0
@ -62,7 +62,7 @@ WorldStatus::WorldStatus()
|
|||||||
void WorldStatus::reset()
|
void WorldStatus::reset()
|
||||||
{
|
{
|
||||||
m_time = 0.0f;
|
m_time = 0.0f;
|
||||||
m_adjust_time_by = 0.0f;
|
m_adjust_time_by.store(0);
|
||||||
m_time_ticks = 0;
|
m_time_ticks = 0;
|
||||||
m_auxiliary_ticks = 0;
|
m_auxiliary_ticks = 0;
|
||||||
m_count_up_ticks = 0;
|
m_count_up_ticks = 0;
|
||||||
@ -480,30 +480,55 @@ void WorldStatus::updateTime(int ticks)
|
|||||||
*/
|
*/
|
||||||
float WorldStatus::adjustDT(float dt)
|
float WorldStatus::adjustDT(float dt)
|
||||||
{
|
{
|
||||||
|
int adjust_time = m_adjust_time_by.load();
|
||||||
|
if (adjust_time == 0)
|
||||||
|
return dt;
|
||||||
|
|
||||||
// If request, adjust world time to go ahead (adjust>0) or
|
// If request, adjust world time to go ahead (adjust>0) or
|
||||||
// slow down (<0). This is done in 5% of dt steps so that the
|
// slow down (<0). This is done in 5% of dt steps so that the
|
||||||
// user will not notice this.
|
// user will not notice this.
|
||||||
const float FRACTION = 0.10f; // fraction of dt to be adjusted
|
const float FRACTION = 0.10f; // fraction of dt to be adjusted
|
||||||
|
float adjust_time_by = adjust_time / 1000.0f;
|
||||||
float time_adjust;
|
float time_adjust;
|
||||||
if (m_adjust_time_by >= 0) // make it run faster
|
if (adjust_time_by > 0.0f) // make it run faster
|
||||||
{
|
{
|
||||||
time_adjust = dt * FRACTION;
|
time_adjust = dt * FRACTION;
|
||||||
if (time_adjust > m_adjust_time_by) time_adjust = m_adjust_time_by;
|
|
||||||
if (m_adjust_time_by > 0)
|
if (time_adjust > adjust_time_by)
|
||||||
Log::verbose("info", "At %f %f adjusting time by %f dt %f to dt %f for %f",
|
{
|
||||||
World::getWorld()->getTime(), StkTime::getRealTime(),
|
m_adjust_time_by.fetch_sub(int(adjust_time_by * 1000.f));
|
||||||
time_adjust, dt, dt - time_adjust, m_adjust_time_by);
|
time_adjust = adjust_time_by;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_adjust_time_by.fetch_sub(int(time_adjust * 1000.f));
|
||||||
|
|
||||||
|
Log::verbose("WorldStatus",
|
||||||
|
"At %f %f adjusting time (speed up) by %f dt %f to dt %f for %f",
|
||||||
|
World::getWorld()->getTime(), StkTime::getRealTime(),
|
||||||
|
time_adjust, dt, dt + time_adjust, adjust_time_by);
|
||||||
}
|
}
|
||||||
else // m_adjust_time negative, i.e. will go slower
|
else // adjust_time_by negative, i.e. will go slower
|
||||||
{
|
{
|
||||||
time_adjust = -dt * FRACTION;
|
time_adjust = -dt * FRACTION;
|
||||||
if (time_adjust < m_adjust_time_by) time_adjust = m_adjust_time_by;
|
|
||||||
Log::verbose("info", "At %f %f adjusting time by %f dt %f to dt %f for %f",
|
if (time_adjust < adjust_time_by)
|
||||||
|
{
|
||||||
|
m_adjust_time_by.fetch_sub(int(adjust_time_by * 1000.f));
|
||||||
|
time_adjust = adjust_time_by;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_adjust_time_by.fetch_sub(int(time_adjust * 1000.f));
|
||||||
|
|
||||||
|
Log::verbose("WorldStatus",
|
||||||
|
"At %f %f adjusting time (slow down) by %f dt %f to dt %f for %f",
|
||||||
World::getWorld()->getTime(), StkTime::getRealTime(),
|
World::getWorld()->getTime(), StkTime::getRealTime(),
|
||||||
time_adjust, dt, dt - time_adjust, m_adjust_time_by);
|
time_adjust, dt, dt + time_adjust, adjust_time_by);
|
||||||
}
|
}
|
||||||
m_adjust_time_by -= time_adjust;
|
dt += time_adjust;
|
||||||
dt -= time_adjust;
|
// No negative or tends to zero dt
|
||||||
|
const float min_dt = stk_config->ticks2Time(1);
|
||||||
|
if (dt < min_dt)
|
||||||
|
dt = min_dt;
|
||||||
return dt;
|
return dt;
|
||||||
} // adjustDT
|
} // adjustDT
|
||||||
|
|
||||||
|
@ -110,10 +110,11 @@ private:
|
|||||||
/** In networked game the world clock might be adjusted (without the
|
/** In networked game the world clock might be adjusted (without the
|
||||||
* player noticing), e.g. if a client causes rewinds in the server,
|
* player noticing), e.g. if a client causes rewinds in the server,
|
||||||
* that client needs to speed up to be further ahead of the server
|
* that client needs to speed up to be further ahead of the server
|
||||||
* and so reduce the number of rollbacks. This is the amount of time
|
* or slow down if time in client goes too far from server time
|
||||||
|
* to reduce the number of rollbacks. This is the amount of time
|
||||||
* by which the client's clock needs to be adjusted (positive or
|
* by which the client's clock needs to be adjusted (positive or
|
||||||
* negative). */
|
* negative). */
|
||||||
float m_adjust_time_by;
|
std::atomic<int> m_adjust_time_by;
|
||||||
|
|
||||||
/** The clock mode: normal counting forwards, or countdown */
|
/** The clock mode: normal counting forwards, or countdown */
|
||||||
ClockType m_clock_mode;
|
ClockType m_clock_mode;
|
||||||
@ -221,7 +222,7 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets a time by which the clock should be adjusted. Used by networking
|
/** Sets a time by which the clock should be adjusted. Used by networking
|
||||||
* if too many rewinds are detected. */
|
* if too many rewinds are detected. */
|
||||||
void setAdjustTime(float t) { m_adjust_time_by = t; }
|
void setAdjustTime(int t) { m_adjust_time_by.fetch_add(t); }
|
||||||
}; // WorldStatus
|
}; // WorldStatus
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
|
|
||||||
#include "network/protocols/game_protocol.hpp"
|
#include "network/protocols/game_protocol.hpp"
|
||||||
|
|
||||||
#include "modes/world.hpp"
|
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
#include "karts/controller/player_controller.hpp"
|
#include "karts/controller/player_controller.hpp"
|
||||||
|
#include "modes/world.hpp"
|
||||||
#include "network/event.hpp"
|
#include "network/event.hpp"
|
||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
#include "network/game_setup.hpp"
|
#include "network/game_setup.hpp"
|
||||||
@ -160,20 +160,19 @@ void GameProtocol::handleControllerAction(Event *event)
|
|||||||
uint8_t count = data.getUInt8();
|
uint8_t count = data.getUInt8();
|
||||||
bool will_trigger_rewind = false;
|
bool will_trigger_rewind = false;
|
||||||
int rewind_delta = 0;
|
int rewind_delta = 0;
|
||||||
|
int cur_ticks = 0;
|
||||||
|
const int not_rewound = RewindManager::get()->getNotRewoundWorldTicks();
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
int ticks = data.getUInt32();
|
cur_ticks = data.getUInt32();
|
||||||
|
|
||||||
// Since this is running in a thread, it might be called during
|
// Since this is running in a thread, it might be called during
|
||||||
// a rewind, i.e. with an incorrect world time. So the event
|
// a rewind, i.e. with an incorrect world time. So the event
|
||||||
// time needs to be compared with the World time independent
|
// time needs to be compared with the World time independent
|
||||||
// of any rewinding.
|
// of any rewinding.
|
||||||
if (ticks < RewindManager::get()->getNotRewoundWorldTicks() &&
|
if (cur_ticks < not_rewound && !will_trigger_rewind)
|
||||||
!will_trigger_rewind )
|
|
||||||
{
|
{
|
||||||
will_trigger_rewind = true;
|
will_trigger_rewind = true;
|
||||||
rewind_delta = ticks
|
rewind_delta = not_rewound - cur_ticks;
|
||||||
- RewindManager::get()->getNotRewoundWorldTicks();
|
|
||||||
}
|
}
|
||||||
uint8_t kart_id = data.getUInt8();
|
uint8_t kart_id = data.getUInt8();
|
||||||
assert(kart_id < World::getWorld()->getNumKarts());
|
assert(kart_id < World::getWorld()->getNumKarts());
|
||||||
@ -183,11 +182,11 @@ void GameProtocol::handleControllerAction(Event *event)
|
|||||||
int value_l = data.getUInt32();
|
int value_l = data.getUInt32();
|
||||||
int value_r = data.getUInt32();
|
int value_r = data.getUInt32();
|
||||||
Log::info("GameProtocol", "Action at %d: %d %d %d %d %d",
|
Log::info("GameProtocol", "Action at %d: %d %d %d %d %d",
|
||||||
ticks, kart_id, action, value, value_l, value_r);
|
cur_ticks, kart_id, action, value, value_l, value_r);
|
||||||
BareNetworkString *s = new BareNetworkString(3);
|
BareNetworkString *s = new BareNetworkString(3);
|
||||||
s->addUInt8(kart_id).addUInt8(action).addUInt32(value)
|
s->addUInt8(kart_id).addUInt8(action).addUInt32(value)
|
||||||
.addUInt32(value_l).addUInt32(value_r);
|
.addUInt32(value_l).addUInt32(value_r);
|
||||||
RewindManager::get()->addNetworkEvent(this, s, ticks);
|
RewindManager::get()->addNetworkEvent(this, s, cur_ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.size() > 0)
|
if (data.size() > 0)
|
||||||
@ -200,16 +199,37 @@ void GameProtocol::handleControllerAction(Event *event)
|
|||||||
// Send update to all clients except the original sender.
|
// Send update to all clients except the original sender.
|
||||||
STKHost::get()->sendPacketExcept(event->getPeer(),
|
STKHost::get()->sendPacketExcept(event->getPeer(),
|
||||||
&data, false);
|
&data, false);
|
||||||
|
|
||||||
|
if (not_rewound == 0 ||
|
||||||
|
m_initial_ticks.find(event->getPeer()) == m_initial_ticks.end())
|
||||||
|
return;
|
||||||
|
int cur_diff = cur_ticks - not_rewound;
|
||||||
|
const int max_adjustment = 12;
|
||||||
|
const int ticks_difference = m_initial_ticks.at(event->getPeer());
|
||||||
if (will_trigger_rewind)
|
if (will_trigger_rewind)
|
||||||
{
|
{
|
||||||
Log::info("GameProtocol",
|
if (rewind_delta > max_adjustment)
|
||||||
"At %d %f %d requesting time adjust of %d for host %d",
|
rewind_delta = max_adjustment;
|
||||||
|
Log::info("GameProtocol", "At %d %f %d requesting time adjust"
|
||||||
|
" (speed up) of %d for host %d",
|
||||||
World::getWorld()->getTimeTicks(), StkTime::getRealTime(),
|
World::getWorld()->getTimeTicks(), StkTime::getRealTime(),
|
||||||
RewindManager::get()->getNotRewoundWorldTicks(),
|
not_rewound, rewind_delta, event->getPeer()->getHostId());
|
||||||
rewind_delta, event->getPeer()->getHostId());
|
|
||||||
// This message from a client triggered a rewind in the server.
|
// This message from a client triggered a rewind in the server.
|
||||||
// To avoid this, signal to the client that it should slow down.
|
// To avoid this, signal to the client that it should speed up.
|
||||||
adjustTimeForClient(event->getPeer(), rewind_delta);
|
adjustTimeForClient(event->getPeer(), rewind_delta);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur_diff > 0 &&
|
||||||
|
cur_diff - ticks_difference > max_adjustment)
|
||||||
|
{
|
||||||
|
// 80% slow down
|
||||||
|
const int adjustment = -max_adjustment * 8 / 10;
|
||||||
|
Log::info("GameProtocol", "At %d %f %d requesting time adjust"
|
||||||
|
" (slow down) of %d for host %d",
|
||||||
|
World::getWorld()->getTimeTicks(), StkTime::getRealTime(),
|
||||||
|
not_rewound, adjustment, event->getPeer()->getHostId());
|
||||||
|
adjustTimeForClient(event->getPeer(), adjustment);
|
||||||
}
|
}
|
||||||
} // if server
|
} // if server
|
||||||
|
|
||||||
@ -220,7 +240,7 @@ void GameProtocol::handleControllerAction(Event *event)
|
|||||||
* reduce rewinds). This function sends a a (unreliable) message to the
|
* reduce rewinds). This function sends a a (unreliable) message to the
|
||||||
* client.
|
* client.
|
||||||
* \param peer The peer that triggered the rewind.
|
* \param peer The peer that triggered the rewind.
|
||||||
* \param t Time that the peer needs to slowdown (<0) or sped up(>0).
|
* \param t Time that the peer needs to slowdown (<0) or speed up(>0).
|
||||||
*/
|
*/
|
||||||
void GameProtocol::adjustTimeForClient(STKPeer *peer, int ticks)
|
void GameProtocol::adjustTimeForClient(STKPeer *peer, int ticks)
|
||||||
{
|
{
|
||||||
@ -240,8 +260,10 @@ void GameProtocol::adjustTimeForClient(STKPeer *peer, int ticks)
|
|||||||
void GameProtocol::handleAdjustTime(Event *event)
|
void GameProtocol::handleAdjustTime(Event *event)
|
||||||
{
|
{
|
||||||
int ticks = event->data().getUInt32();
|
int ticks = event->data().getUInt32();
|
||||||
World::getWorld()->setAdjustTime(stk_config->ticks2Time(ticks));
|
World::getWorld()->setAdjustTime(
|
||||||
|
int(stk_config->ticks2Time(ticks) * 1000.0f));
|
||||||
} // handleAdjustTime
|
} // handleAdjustTime
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Called by the server before assembling a new message containing the full
|
/** Called by the server before assembling a new message containing the full
|
||||||
* state of the race to be sent to a client.
|
* state of the race to be sent to a client.
|
||||||
@ -338,3 +360,11 @@ void GameProtocol::rewind(BareNetworkString *buffer)
|
|||||||
if (pc)
|
if (pc)
|
||||||
pc->actionFromNetwork(action, value, value_l, value_r);
|
pc->actionFromNetwork(action, value, value_l, value_r);
|
||||||
} // rewind
|
} // rewind
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void GameProtocol::addInitialTicks(STKPeer* p, int ticks)
|
||||||
|
{
|
||||||
|
Log::verbose("GameProtocol", "Host %d with ticks difference %d",
|
||||||
|
p->getHostId(), ticks);
|
||||||
|
m_initial_ticks[p] = ticks;
|
||||||
|
} // addInitialTicks
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "utils/cpp2011.hpp"
|
#include "utils/cpp2011.hpp"
|
||||||
#include "utils/singleton.hpp"
|
#include "utils/singleton.hpp"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class BareNetworkString;
|
class BareNetworkString;
|
||||||
@ -69,6 +70,8 @@ private:
|
|||||||
void handleState(Event *event);
|
void handleState(Event *event);
|
||||||
void handleAdjustTime(Event *event);
|
void handleAdjustTime(Event *event);
|
||||||
static std::weak_ptr<GameProtocol> m_game_protocol;
|
static std::weak_ptr<GameProtocol> m_game_protocol;
|
||||||
|
std::map<STKPeer*, int> m_initial_ticks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameProtocol();
|
GameProtocol();
|
||||||
virtual ~GameProtocol();
|
virtual ~GameProtocol();
|
||||||
@ -104,6 +107,8 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the NetworkString in which a state was saved. */
|
/** Returns the NetworkString in which a state was saved. */
|
||||||
NetworkString* getState() const { return m_data_to_send; }
|
NetworkString* getState() const { return m_data_to_send; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void addInitialTicks(STKPeer* p, int ticks);
|
||||||
|
|
||||||
}; // class GameProtocol
|
}; // class GameProtocol
|
||||||
|
|
||||||
|
@ -1024,7 +1024,7 @@ void ServerLobby::connectionRequested(Event* event)
|
|||||||
peer->sendPacket(server_info);
|
peer->sendPacket(server_info);
|
||||||
delete server_info;
|
delete server_info;
|
||||||
|
|
||||||
m_peers_ready[peer] = false;
|
m_peers_ready[peer] = std::make_pair(false, 0.0);
|
||||||
for (std::shared_ptr<NetworkPlayerProfile> npp : peer->getPlayerProfiles())
|
for (std::shared_ptr<NetworkPlayerProfile> npp : peer->getPlayerProfiles())
|
||||||
{
|
{
|
||||||
m_game_setup->addPlayer(npp);
|
m_game_setup->addPlayer(npp);
|
||||||
@ -1307,7 +1307,7 @@ void ServerLobby::finishedLoadingWorld()
|
|||||||
void ServerLobby::finishedLoadingWorldClient(Event *event)
|
void ServerLobby::finishedLoadingWorldClient(Event *event)
|
||||||
{
|
{
|
||||||
std::shared_ptr<STKPeer> peer = event->getPeerSP();
|
std::shared_ptr<STKPeer> peer = event->getPeerSP();
|
||||||
m_peers_ready.at(peer) = true;
|
m_peers_ready.at(peer) = std::make_pair(true, StkTime::getRealTime());
|
||||||
Log::info("ServerLobby", "Peer %d has finished loading world at %lf",
|
Log::info("ServerLobby", "Peer %d has finished loading world at %lf",
|
||||||
peer->getHostId(), StkTime::getRealTime());
|
peer->getHostId(), StkTime::getRealTime());
|
||||||
} // finishedLoadingWorldClient
|
} // finishedLoadingWorldClient
|
||||||
@ -1324,12 +1324,40 @@ void ServerLobby::finishedLoadingWorldClient(Event *event)
|
|||||||
void ServerLobby::startedRaceOnClient(Event *event)
|
void ServerLobby::startedRaceOnClient(Event *event)
|
||||||
{
|
{
|
||||||
std::shared_ptr<STKPeer> peer = event->getPeerSP();
|
std::shared_ptr<STKPeer> peer = event->getPeerSP();
|
||||||
m_peers_ready.at(peer) = true;
|
m_peers_ready.at(peer) = std::make_pair(true, StkTime::getRealTime());
|
||||||
Log::info("ServerLobby", "Peer %d has started race at %lf",
|
Log::info("ServerLobby", "Peer %d has started race at %lf",
|
||||||
peer->getHostId(), StkTime::getRealTime());
|
peer->getHostId(), StkTime::getRealTime());
|
||||||
|
|
||||||
if (checkPeersReady())
|
if (checkPeersReady())
|
||||||
{
|
{
|
||||||
|
std::vector<std::pair<STKPeer*, double> > mapping;
|
||||||
|
for (auto p : m_peers_ready)
|
||||||
|
{
|
||||||
|
auto peer = p.first.lock();
|
||||||
|
if (!peer)
|
||||||
|
continue;
|
||||||
|
mapping.emplace_back(peer.get(), p.second.second);
|
||||||
|
}
|
||||||
|
std::sort(mapping.begin(), mapping.end(),
|
||||||
|
[](const std::pair<STKPeer*, double>& a,
|
||||||
|
const std::pair<STKPeer*, double>& b)->bool
|
||||||
|
{
|
||||||
|
return a.second > b.second;
|
||||||
|
});
|
||||||
|
for (unsigned i = 0; i < mapping.size(); i++)
|
||||||
|
{
|
||||||
|
// Server delay is 0.1, so it's around 12 ticks
|
||||||
|
// (0.1 * 120 (physics fps)) for the highest ping client
|
||||||
|
if (i == 0)
|
||||||
|
GameProtocol::lock()->addInitialTicks(mapping[0].first, 12);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const double diff = mapping[0].second - mapping[i].second;
|
||||||
|
assert(diff >= 0.0);
|
||||||
|
GameProtocol::lock()->addInitialTicks(mapping[i].first,
|
||||||
|
12 + stk_config->time2Ticks((float)diff));
|
||||||
|
}
|
||||||
|
}
|
||||||
m_state = DELAY_SERVER;
|
m_state = DELAY_SERVER;
|
||||||
m_server_delay = StkTime::getRealTime() + 0.1;
|
m_server_delay = StkTime::getRealTime() + 0.1;
|
||||||
Log::verbose("ServerLobby", "Started delay at %lf set delay to %lf",
|
Log::verbose("ServerLobby", "Started delay at %lf set delay to %lf",
|
||||||
@ -1346,7 +1374,7 @@ void ServerLobby::playerFinishedResult(Event *event)
|
|||||||
if (m_state.load() != RESULT_DISPLAY)
|
if (m_state.load() != RESULT_DISPLAY)
|
||||||
return;
|
return;
|
||||||
std::shared_ptr<STKPeer> peer = event->getPeerSP();
|
std::shared_ptr<STKPeer> peer = event->getPeerSP();
|
||||||
m_peers_ready.at(peer) = true;
|
m_peers_ready.at(peer) = std::make_pair(true, StkTime::getRealTime());
|
||||||
} // playerFinishedResult
|
} // playerFinishedResult
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -48,7 +48,7 @@ private:
|
|||||||
std::atomic_bool m_server_has_loaded_world;
|
std::atomic_bool m_server_has_loaded_world;
|
||||||
|
|
||||||
/** Counts how many peers have finished loading the world. */
|
/** Counts how many peers have finished loading the world. */
|
||||||
std::map<std::weak_ptr<STKPeer>, bool,
|
std::map<std::weak_ptr<STKPeer>, std::pair<bool, double>,
|
||||||
std::owner_less<std::weak_ptr<STKPeer> > > m_peers_ready;
|
std::owner_less<std::weak_ptr<STKPeer> > > m_peers_ready;
|
||||||
|
|
||||||
/** Vote from each peer. */
|
/** Vote from each peer. */
|
||||||
@ -102,7 +102,7 @@ private:
|
|||||||
{
|
{
|
||||||
if (p.first.expired())
|
if (p.first.expired())
|
||||||
continue;
|
continue;
|
||||||
all_ready = all_ready && p.second;
|
all_ready = all_ready && p.second.first;
|
||||||
if (!all_ready)
|
if (!all_ready)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -118,7 +118,8 @@ private:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
it->second = false;
|
it->second.first = false;
|
||||||
|
it->second.second = 0.0;
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ RewindManager::~RewindManager()
|
|||||||
void RewindManager::reset()
|
void RewindManager::reset()
|
||||||
{
|
{
|
||||||
m_is_rewinding = false;
|
m_is_rewinding = false;
|
||||||
m_not_rewound_ticks = 0;
|
m_not_rewound_ticks.store(0);
|
||||||
m_overall_state_size = 0;
|
m_overall_state_size = 0;
|
||||||
m_last_saved_state = -1; // forces initial state save
|
m_last_saved_state = -1; // forces initial state save
|
||||||
m_state_frequency =
|
m_state_frequency =
|
||||||
@ -249,7 +249,7 @@ void RewindManager::update(int ticks_not_used)
|
|||||||
float time = World::getWorld()->getTime();
|
float time = World::getWorld()->getTime();
|
||||||
int ticks = World::getWorld()->getTimeTicks();
|
int ticks = World::getWorld()->getTimeTicks();
|
||||||
|
|
||||||
m_not_rewound_ticks = ticks;
|
m_not_rewound_ticks.store(ticks, std::memory_order_relaxed);
|
||||||
|
|
||||||
// Clients don't save state, so they just exit.
|
// Clients don't save state, so they just exit.
|
||||||
if (NetworkConfig::get()->isClient() ||
|
if (NetworkConfig::get()->isClient() ||
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "utils/synchronised.hpp"
|
#include "utils/synchronised.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <atomic>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ private:
|
|||||||
/** This stores the original World time in ticks during a rewind. It is
|
/** This stores the original World time in ticks during a rewind. It is
|
||||||
* used to detect if a client's local time need adjustment to reduce
|
* used to detect if a client's local time need adjustment to reduce
|
||||||
* rewinds. */
|
* rewinds. */
|
||||||
int m_not_rewound_ticks;
|
std::atomic<int> m_not_rewound_ticks;
|
||||||
|
|
||||||
RewindManager();
|
RewindManager();
|
||||||
~RewindManager();
|
~RewindManager();
|
||||||
@ -163,7 +164,8 @@ public:
|
|||||||
/** Returns true if currently a rewind is happening. */
|
/** Returns true if currently a rewind is happening. */
|
||||||
bool isRewinding() const { return m_is_rewinding; }
|
bool isRewinding() const { return m_is_rewinding; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
int getNotRewoundWorldTicks() const { return m_not_rewound_ticks; }
|
int getNotRewoundWorldTicks() const
|
||||||
|
{ return m_not_rewound_ticks.load(std::memory_order_relaxed); }
|
||||||
}; // RewindManager
|
}; // RewindManager
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user