Reset timer after finished loading world

It avoid some clients with slower loading time than anybody else hanging
when rewinding
This commit is contained in:
Benau
2018-04-06 13:26:11 +08:00
parent 969b56844b
commit 2a3d57706a
8 changed files with 47 additions and 24 deletions

View File

@@ -30,6 +30,7 @@
#include "modes/profile_world.hpp"
#include "modes/world.hpp"
#include "network/network_config.hpp"
#include "network/protocols/lobby_protocol.hpp"
#include "network/protocol_manager.hpp"
#include "network/race_event_manager.hpp"
#include "network/rewind_manager.hpp"
@@ -299,8 +300,25 @@ void MainLoop::run()
}
#endif
while(!m_abort)
while (!m_abort)
{
bool loading_shutdown = false;
auto lb = LobbyProtocol::get<LobbyProtocol>();
if (World::getWorld() && lb &&
STKHost::existHost() && !STKHost::get()->requestedShutdown())
{
while (!lb->allPlayersReady())
{
if (STKHost::existHost() && STKHost::get()->requestedShutdown())
{
loading_shutdown = true;
break;
}
StkTime::sleep(1);
m_curr_time = irr_driver->getDevice()->getTimer()->getRealTime();
}
}
#ifdef WIN32
if (parent != 0 && parent != INVALID_HANDLE_VALUE)
{
@@ -329,7 +347,9 @@ void MainLoop::run()
float dt = stk_config->ticks2Time(1);
left_over_time -= num_steps * dt ;
if (STKHost::existHost() &&
// Shutdown next frame if shutdown request is sent while loading the
// world
if (!loading_shutdown && STKHost::existHost() &&
STKHost::get()->requestedShutdown())
{
SFXManager::get()->quickSound("anvil");

View File

@@ -29,7 +29,6 @@
#include "modes/world.hpp"
#include "network/network_config.hpp"
#include "network/protocols/client_lobby.hpp"
#include "network/protocols/server_lobby.hpp"
#include "network/rewind_manager.hpp"
#include "network/race_event_manager.hpp"
#include "tracks/track.hpp"
@@ -257,12 +256,11 @@ void WorldStatus::updateTime(int ticks)
case WAIT_FOR_SERVER_PHASE:
{
// This stage is only reached in case of a networked game.
// A client waits for a message from the server that it can
// start the race (i.e. that all clients and the server have
// loaded the world). The server waits for a confirmation from
// The server waits for a confirmation from
// each client that they have started (to guarantee that the
// server is running with a local time behind all clients).
if (m_server_is_ready.load() == false) return;
if (NetworkConfig::get()->isServer() &&
m_server_is_ready.load() == false) return;
m_phase = READY_PHASE;
auto cl = LobbyProtocol::get<ClientLobby>();

View File

@@ -104,7 +104,7 @@ void ClientLobby::setup()
clearPlayers();
TracksScreen::getInstance()->resetVote();
LobbyProtocol::setup();
m_state = NONE;
m_state.store(NONE);
} // setup
//-----------------------------------------------------------------------------
@@ -248,12 +248,12 @@ void ClientLobby::addAllPlayers(Event* event)
//-----------------------------------------------------------------------------
void ClientLobby::update(int ticks)
{
switch (m_state)
switch (m_state.load())
{
case NONE:
if (STKHost::get()->isConnectedTo(m_server_address))
{
m_state = LINKED;
m_state.store(LINKED);
}
break;
case LINKED:
@@ -308,7 +308,7 @@ void ClientLobby::update(int ticks)
sendToServer(ns);
delete ns;
m_state = REQUESTING_CONNECTION;
m_state.store(REQUESTING_CONNECTION);
}
break;
case REQUESTING_CONNECTION:
@@ -340,7 +340,7 @@ void ClientLobby::update(int ticks)
{
screen->push();
}
m_state = SELECTING_KARTS;
m_state.store(SELECTING_KARTS);
}
break;
case SELECTING_KARTS:
@@ -350,7 +350,7 @@ void ClientLobby::update(int ticks)
case RACE_FINISHED:
break;
case DONE:
m_state = EXITING;
m_state.store(EXITING);
requestTerminate();
break;
case EXITING:
@@ -507,7 +507,7 @@ void ClientLobby::connectionAccepted(Event* event)
if (!str.empty())
NetworkingLobby::getInstance()->addMoreServerInfo(str);
m_state = CONNECTED;
m_state.store(CONNECTED);
} // connectionAccepted
//-----------------------------------------------------------------------------
@@ -537,7 +537,7 @@ void ClientLobby::becomingServerOwner()
MessageQueue::add(MessageQueue::MT_GENERIC,
_("You are now the owner of server."));
STKHost::get()->setAuthorisedToControl(true);
if (m_state == CONNECTED && NetworkConfig::get()->isAutoConnect())
if (m_state.load() == CONNECTED && NetworkConfig::get()->isAutoConnect())
{
// Send a message to the server to start
NetworkString start(PROTOCOL_LOBBY_ROOM);
@@ -612,7 +612,7 @@ void ClientLobby::connectionRefused(Event* event)
*/
void ClientLobby::startGame(Event* event)
{
m_state = PLAYING;
m_state.store(PLAYING);
// Triggers the world finite state machine to go from WAIT_FOR_SERVER_PHASE
// to READY_PHASE.
World::getWorld()->setReadyToRace();
@@ -645,7 +645,7 @@ void ClientLobby::startingRaceNow()
*/
void ClientLobby::startSelection(Event* event)
{
m_state = KART_SELECTION;
m_state.store(KART_SELECTION);
const NetworkString& data = event->data();
const unsigned kart_num = data.getUInt16();
const unsigned track_num = data.getUInt16();
@@ -706,7 +706,7 @@ void ClientLobby::raceFinished(Event* event)
position++;
}
ranked_world->endSetKartPositions();
m_state = RACE_FINISHED;
m_state.store(RACE_FINISHED);
ranked_world->terminateRace();
} // raceFinished

View File

@@ -4,6 +4,8 @@
#include "network/protocols/lobby_protocol.hpp"
#include "network/transport_address.hpp"
#include "utils/cpp2011.hpp"
#include <atomic>
#include <set>
class ClientLobby : public LobbyProtocol
@@ -26,7 +28,7 @@ private:
TransportAddress m_server_address;
enum STATE
enum ClientState : unsigned int
{
NONE,
LINKED,
@@ -41,7 +43,7 @@ private:
};
/** The state of the finite state machine. */
STATE m_state;
std::atomic<ClientState> m_state;
std::set<std::string> m_available_karts;
std::set<std::string> m_available_tracks;
@@ -64,9 +66,10 @@ public:
virtual void setup() OVERRIDE;
virtual void update(int ticks) OVERRIDE;
virtual bool waitingForPlayers() const OVERRIDE
{ return m_state == CONNECTED; }
{ return m_state.load() == CONNECTED; }
virtual void asynchronousUpdate() OVERRIDE {}
virtual bool allPlayersReady() const OVERRIDE
{ return m_state.load() >= PLAYING; }
};
#endif // CLIENT_LOBBY_HPP

View File

@@ -114,6 +114,7 @@ public:
virtual void finishedLoadingWorld() = 0;
virtual void loadWorld();
virtual bool waitingForPlayers() const = 0;
virtual bool allPlayersReady() const = 0;
GameSetup* getGameSetup() const { return m_game_setup; }
}; // class LobbyProtocol

View File

@@ -402,7 +402,7 @@ void ServerLobby::update(int ticks)
case REGISTER_SELF_ADDRESS:
case ACCEPTING_CLIENTS:
case WAIT_FOR_WORLD_LOADED:
case WAIT_FOR_RACE_STARTED:
case WAIT_FOR_RACE_STARTED:
case DELAY_SERVER:
{
// Waiting for asynchronousUpdate

View File

@@ -117,6 +117,8 @@ public:
void updateBanList();
virtual bool waitingForPlayers() const OVERRIDE
{ return m_state.load() == ACCEPTING_CLIENTS; }
virtual bool allPlayersReady() const OVERRIDE
{ return m_state.load() >= WAIT_FOR_RACE_STARTED; }
}; // class ServerLobby

View File

@@ -4,7 +4,6 @@
#include "karts/controller/controller.hpp"
#include "modes/world.hpp"
#include "network/network_config.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/rewind_manager.hpp"
#include "utils/profiler.hpp"