From 71be79791f8623b50c8d68333415e212c3dc5e02 Mon Sep 17 00:00:00 2001 From: vyordan Date: Fri, 26 Jun 2026 22:04:27 -0600 Subject: [PATCH] Use turn_id_t (int32_t) for turn-count across simulation, network and replay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSimulation2 used , CSimulation2Impl mixed /, and CTurnManager used for the same turn-count concept, forcing a static_cast at the one place these types already met (rejoin-test comparison). Add (alias for std::int32_t) in SimulationCommand.h and use it consistently for every turn counter in CSimulation2/Impl, CTurnManager and its subclasses (CLocalTurnManager, CReplayTurnManager), CNetServerTurnManager/CNetClientTurnManager, and the network wire format (m_Turn in CEndCommandBatchMessage, CSimulationMessage, CSyncCheckMessage, CSyncErrorMessage, and m_CurrentTurn in CLoadedGameMessage). Turn *duration* fields (m_TurnLength, m_CommandDelay, DEFAULT_TURN_LENGTH, COMMAND_DELAY_SP/MP, SetTurnLength, GetSavedTurnLength return type) are left as u32 — they're milliseconds, not a counter, and out of scope here. Remaining turn_id_t vs size_t comparisons use std::cmp_equal or explicit casts, matching the existing pattern in Simulation2.cpp. Fixes #8718 --- source/network/NetClientTurnManager.cpp | 8 +++---- source/network/NetClientTurnManager.h | 6 ++--- source/network/NetMessage.h | 2 +- source/network/NetMessageSim.cpp | 6 ++--- source/network/NetMessages.h | 12 +++++----- source/network/NetServer.cpp | 15 ++++++------ source/network/NetServerTurnManager.cpp | 19 ++++++++------- source/network/NetServerTurnManager.h | 21 ++++++++-------- source/simulation2/Simulation2.cpp | 20 ++++++++-------- source/simulation2/Simulation2.h | 3 ++- .../simulation2/helpers/SimulationCommand.h | 8 ++++++- .../simulation2/system/LocalTurnManager.cpp | 4 ++-- source/simulation2/system/LocalTurnManager.h | 4 ++-- .../simulation2/system/ReplayTurnManager.cpp | 16 ++++++------- source/simulation2/system/ReplayTurnManager.h | 18 +++++++------- source/simulation2/system/TurnManager.cpp | 14 +++++------ source/simulation2/system/TurnManager.h | 24 +++++++++---------- 17 files changed, 105 insertions(+), 95 deletions(-) diff --git a/source/network/NetClientTurnManager.cpp b/source/network/NetClientTurnManager.cpp index 34c540b4c3..f46357003f 100644 --- a/source/network/NetClientTurnManager.cpp +++ b/source/network/NetClientTurnManager.cpp @@ -63,7 +63,7 @@ void CNetClientTurnManager::PostCommand(JS::HandleValue data) // TODO: we should do this when the server stops sending our commands back to us } -void CNetClientTurnManager::NotifyFinishedOwnCommands(u32 turn) +void CNetClientTurnManager::NotifyFinishedOwnCommands(turn_id_t turn) { NETCLIENTTURN_LOG("NotifyFinishedOwnCommands(%d)\n", turn); @@ -79,7 +79,7 @@ void CNetClientTurnManager::NotifyFinishedOwnCommands(u32 turn) m_NetClient.SendMessage(&msg); } -void CNetClientTurnManager::NotifyFinishedUpdate(u32 turn, const UpdateCallback&) +void CNetClientTurnManager::NotifyFinishedUpdate(turn_id_t turn, const UpdateCallback&) { bool quick = !TurnNeedsFullHash(turn); std::string hash; @@ -110,10 +110,10 @@ void CNetClientTurnManager::OnDestroyConnection() void CNetClientTurnManager::OnSimulationMessage(CSimulationMessage* msg) { // Command received from the server - store it for later execution - AddCommand(msg->m_Client, msg->m_Player, msg->m_Data, msg->m_Turn); + AddCommand(msg->m_Client, msg->m_Player, msg->m_Data, static_cast(msg->m_Turn)); } -void CNetClientTurnManager::OnSyncError(u32 turn, const CStr& expectedHash, const std::vector& playerNames) +void CNetClientTurnManager::OnSyncError(turn_id_t turn, const CStr& expectedHash, const std::vector& playerNames) { CStr expectedHashHex(Hexify(expectedHash)); NETCLIENTTURN_LOG("OnSyncError(%d, %hs)\n", turn, expectedHashHex.c_str()); diff --git a/source/network/NetClientTurnManager.h b/source/network/NetClientTurnManager.h index 9dc15a8b1c..06742c2d40 100644 --- a/source/network/NetClientTurnManager.h +++ b/source/network/NetClientTurnManager.h @@ -49,12 +49,12 @@ public: */ void OnDestroyConnection(); - void OnSyncError(u32 turn, const CStr& expectedHash, const std::vector& playerNames); + void OnSyncError(turn_id_t turn, const CStr& expectedHash, const std::vector& playerNames); private: - void NotifyFinishedOwnCommands(u32 turn) override; + void NotifyFinishedOwnCommands(turn_id_t turn) override; - void NotifyFinishedUpdate(u32 turn, const UpdateCallback& sendEventToAll) override; + void NotifyFinishedUpdate(turn_id_t turn, const UpdateCallback& sendEventToAll) override; CNetClient& m_NetClient; }; diff --git a/source/network/NetMessage.h b/source/network/NetMessage.h index effb0bfb7e..34bd81243e 100644 --- a/source/network/NetMessage.h +++ b/source/network/NetMessage.h @@ -139,7 +139,7 @@ public: u32 m_Client; i32 m_Player; - u32 m_Turn; + i32 m_Turn; JS::PersistentRooted m_Data; private: const Script::Interface& m_ScriptInterface; diff --git a/source/network/NetMessageSim.cpp b/source/network/NetMessageSim.cpp index 76d1d5e836..a57f24ee5e 100644 --- a/source/network/NetMessageSim.cpp +++ b/source/network/NetMessageSim.cpp @@ -150,7 +150,7 @@ u8* CSimulationMessage::Serialize(u8* pBuffer) const CBufferBinarySerializer serializer(m_ScriptInterface, pos); serializer.NumberU32_Unbounded("client", m_Client); serializer.NumberI32_Unbounded("player", m_Player); - serializer.NumberU32_Unbounded("turn", m_Turn); + serializer.NumberI32_Unbounded("turn", m_Turn); serializer.ScriptVal("command", const_cast(&m_Data)); return serializer.GetBuffer(); @@ -165,7 +165,7 @@ const u8* CSimulationMessage::Deserialize(const u8* pStart, const u8* pEnd) CStdDeserializer deserializer(m_ScriptInterface, stream); deserializer.NumberU32_Unbounded("client", m_Client); deserializer.NumberI32_Unbounded("player", m_Player); - deserializer.NumberU32_Unbounded("turn", m_Turn); + deserializer.NumberI32_Unbounded("turn", m_Turn); deserializer.ScriptVal("command", &m_Data); return pEnd; } @@ -177,7 +177,7 @@ size_t CSimulationMessage::GetSerializedLength() const CLengthBinarySerializer serializer(m_ScriptInterface); serializer.NumberU32_Unbounded("client", m_Client); serializer.NumberI32_Unbounded("player", m_Player); - serializer.NumberU32_Unbounded("turn", m_Turn); + serializer.NumberI32_Unbounded("turn", m_Turn); // TODO: The cast can probably be removed if and when ScriptVal can take a JS::HandleValue instead of // a JS::MutableHandleValue (relies on JSAPI change). Also search for other casts like this one in that case. diff --git a/source/network/NetMessages.h b/source/network/NetMessages.h index ad0c940fad..88c9292307 100644 --- a/source/network/NetMessages.h +++ b/source/network/NetMessages.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -27,7 +27,7 @@ #define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?' #define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!' -#define PS_PROTOCOL_VERSION 0x01010019 // Arbitrary protocol +#define PS_PROTOCOL_VERSION 0x0101001A // Arbitrary protocol #define PS_DEFAULT_PORT 0x5073 // 'P', 's' // Set when lobby authentication is required. Used in the SrvHandshakeResponseMessage. @@ -231,7 +231,7 @@ START_NMT_CLASS_(ClientPaused, NMT_CLIENT_PAUSED) END_NMT_CLASS() START_NMT_CLASS_(LoadedGame, NMT_LOADED_GAME) - NMT_FIELD_INT(m_CurrentTurn, u32, 4) + NMT_FIELD_INT(m_CurrentTurn, i32, 4) END_NMT_CLASS() START_NMT_CLASS_(GameStart, NMT_GAME_START) @@ -243,17 +243,17 @@ START_NMT_CLASS_(GameSavedStart, NMT_SAVED_GAME_START) END_NMT_CLASS() START_NMT_CLASS_(EndCommandBatch, NMT_END_COMMAND_BATCH) - NMT_FIELD_INT(m_Turn, u32, 4) + NMT_FIELD_INT(m_Turn, i32, 4) NMT_FIELD_INT(m_TurnLength, u32, 2) END_NMT_CLASS() START_NMT_CLASS_(SyncCheck, NMT_SYNC_CHECK) - NMT_FIELD_INT(m_Turn, u32, 4) + NMT_FIELD_INT(m_Turn, i32, 4) NMT_FIELD(CStr, m_Hash) END_NMT_CLASS() START_NMT_CLASS_(SyncError, NMT_SYNC_ERROR) - NMT_FIELD_INT(m_Turn, u32, 4) + NMT_FIELD_INT(m_Turn, i32, 4) NMT_FIELD(CStr, m_HashExpected) NMT_START_ARRAY(m_PlayerNames) NMT_FIELD(CStrW, m_Name) diff --git a/source/network/NetServer.cpp b/source/network/NetServer.cpp index dba9c3e9a8..932c58ed36 100644 --- a/source/network/NetServer.cpp +++ b/source/network/NetServer.cpp @@ -49,6 +49,7 @@ #include "scriptinterface/Context.h" #include "scriptinterface/Interface.h" #include "scriptinterface/Request.h" +#include "simulation2/helpers/SimulationCommand.h" #include "simulation2/system/TurnManager.h" #include @@ -1172,9 +1173,9 @@ bool CNetServerWorker::OnSimulationCommand(CNetServerSession* session, CFsmEvent server.Multicast(message, { NSS_INGAME }); // Save all the received commands - if (server.m_SavedCommands.size() < message->m_Turn + 1) - server.m_SavedCommands.resize(message->m_Turn + 1); - server.m_SavedCommands[message->m_Turn].push_back(*message); + if (server.m_SavedCommands.size() < static_cast(message->m_Turn) + 1) + server.m_SavedCommands.resize(static_cast(message->m_Turn) + 1); + server.m_SavedCommands[static_cast(message->m_Turn)].push_back(*message); // TODO: we shouldn't send the message back to the client that first sent it return true; @@ -1396,14 +1397,14 @@ bool CNetServerWorker::OnJoinSyncingLoadedGame(CNetServerSession* session, CFsmE CLoadedGameMessage* message = (CLoadedGameMessage*)event->GetParamRef(); - u32 turn = message->m_CurrentTurn; - u32 readyTurn = server.m_ServerTurnManager->GetReadyTurn(); + turn_id_t turn = message->m_CurrentTurn; + turn_id_t readyTurn = server.m_ServerTurnManager->GetReadyTurn(); // Send them all commands received since their saved state, // and turn-ended messages for any turns that have already been processed - for (size_t i = turn + 1; i < std::max(readyTurn+1, (u32)server.m_SavedCommands.size()); ++i) + for (turn_id_t i = turn + 1; i < std::max(readyTurn + 1, static_cast(server.m_SavedCommands.size())); ++i) { - if (i < server.m_SavedCommands.size()) + if (static_cast(i) < server.m_SavedCommands.size()) for (size_t j = 0; j < server.m_SavedCommands[i].size(); ++j) session->SendMessage(&server.m_SavedCommands[i][j]); diff --git a/source/network/NetServerTurnManager.cpp b/source/network/NetServerTurnManager.cpp index eba3ef722c..2a90ec1d1f 100644 --- a/source/network/NetServerTurnManager.cpp +++ b/source/network/NetServerTurnManager.cpp @@ -27,6 +27,7 @@ #include "network/NetServerSession.h" #include "ps/CLogger.h" #include "ps/ConfigDB.h" +#include "simulation2/helpers/SimulationCommand.h" #include "simulation2/system/TurnManager.h" #include @@ -50,7 +51,7 @@ CNetServerTurnManager::CNetServerTurnManager(CNetServerWorker& server) m_SavedTurnLengths.push_back(m_TurnLength); } -void CNetServerTurnManager::NotifyFinishedClientCommands(CNetServerSession& session, u32 turn) +void CNetServerTurnManager::NotifyFinishedClientCommands(CNetServerSession& session, turn_id_t turn) { int client = session.GetHostID(); @@ -105,11 +106,11 @@ void CNetServerTurnManager::CheckClientsReady() msg.m_Turn = m_ReadyTurn; m_NetServer.Multicast(&msg, { NSS_INGAME }); - ENSURE(m_SavedTurnLengths.size() == m_ReadyTurn); + ENSURE(std::cmp_equal(m_SavedTurnLengths.size(), m_ReadyTurn)); m_SavedTurnLengths.push_back(m_TurnLength); } -void CNetServerTurnManager::NotifyFinishedClientUpdate(CNetServerSession& session, u32 turn, const CStr& hash) +void CNetServerTurnManager::NotifyFinishedClientUpdate(CNetServerSession& session, turn_id_t turn, const CStr& hash) { int client = session.GetHostID(); @@ -138,13 +139,13 @@ void CNetServerTurnManager::NotifyFinishedClientUpdate(CNetServerSession& sessio m_ClientStateHashes[turn][client] = hash; // Find the newest turn which we know all clients have simulated - u32 newest = std::numeric_limits::max(); + turn_id_t newest = std::numeric_limits::max(); for (const std::pair& clientData : m_ClientsData) if (clientData.second.simulatedTurn < newest) newest = clientData.second.simulatedTurn; // For every set of state hashes that all clients have simulated, check for OOS - for (const std::pair>& clientStateHash : m_ClientStateHashes) + for (const std::pair>& clientStateHash : m_ClientStateHashes) { if (clientStateHash.first > newest) break; @@ -187,7 +188,7 @@ void CNetServerTurnManager::NotifyFinishedClientUpdate(CNetServerSession& sessio m_ClientStateHashes.erase(m_ClientStateHashes.begin(), m_ClientStateHashes.lower_bound(newest+1)); } -void CNetServerTurnManager::InitialiseClient(int client, u32 turn, bool observer) +void CNetServerTurnManager::InitialiseClient(int client, turn_id_t turn, bool observer) { NETSERVERTURN_LOG("InitialiseClient(client=%d, turn=%d)\n", client, turn); @@ -206,7 +207,7 @@ void CNetServerTurnManager::UninitialiseClient(int client) bool checkOOS = m_ClientsData[client].isOOS; m_ClientsData.erase(client); - for (std::pair>& clientStateHash : m_ClientStateHashes) + for (std::pair>& clientStateHash : m_ClientStateHashes) clientStateHash.second.erase(client); // Check whether we're ready for the next turn now that we're not @@ -228,8 +229,8 @@ void CNetServerTurnManager::SetTurnLength(u32 msecs) m_TurnLength = msecs; } -u32 CNetServerTurnManager::GetSavedTurnLength(u32 turn) +u32 CNetServerTurnManager::GetSavedTurnLength(turn_id_t turn) { ENSURE(turn <= m_ReadyTurn); - return m_SavedTurnLengths.at(turn); + return m_SavedTurnLengths.at(static_cast(turn)); } diff --git a/source/network/NetServerTurnManager.h b/source/network/NetServerTurnManager.h index 73e5034bd4..a686781dbe 100644 --- a/source/network/NetServerTurnManager.h +++ b/source/network/NetServerTurnManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -21,6 +21,7 @@ #include "lib/code_annotation.h" #include "lib/types.h" #include "ps/CStr.h" +#include "simulation2/helpers/SimulationCommand.h" #include #include @@ -44,15 +45,15 @@ class CNetServerTurnManager public: CNetServerTurnManager(CNetServerWorker& server); - void NotifyFinishedClientCommands(CNetServerSession& session, u32 turn); + void NotifyFinishedClientCommands(CNetServerSession& session, turn_id_t turn); - void NotifyFinishedClientUpdate(CNetServerSession& session, u32 turn, const CStr& hash); + void NotifyFinishedClientUpdate(CNetServerSession& session, turn_id_t turn, const CStr& hash); /** * Inform the turn manager of a new client * @param observer - whether this client is an observer. */ - void InitialiseClient(int client, u32 turn, bool observer); + void InitialiseClient(int client, turn_id_t turn, bool observer); /** * Inform the turn manager that a previously-initialised client has left the game. @@ -65,13 +66,13 @@ public: * Returns the latest turn for which all clients are ready; * they will have already been told to execute this turn. */ - u32 GetReadyTurn() { return m_ReadyTurn; } + turn_id_t GetReadyTurn() { return m_ReadyTurn; } /** * Returns the turn length that was used for the given turn. * Requires turn <= GetReadyTurn(). */ - u32 GetSavedTurnLength(u32 turn); + u32 GetSavedTurnLength(turn_id_t turn); private: void CheckClientsReady(); @@ -80,9 +81,9 @@ private: { CStrW playerName; // Latest turn for which all commands have been received. - u32 readyTurn; + turn_id_t readyTurn; // Last known simulated turn. - u32 simulatedTurn; + turn_id_t simulatedTurn; bool isObserver; bool isOOS = false; }; @@ -93,10 +94,10 @@ private: bool m_HasSyncError = false; // Map of turn -> {Client ID -> state hash}; old indexes <= min(m_ClientsSimulated) are deleted - std::map> m_ClientStateHashes; + std::map> m_ClientStateHashes; /// The latest turn for which we have received all commands from all clients - u32 m_ReadyTurn; + turn_id_t m_ReadyTurn; // Current turn length u32 m_TurnLength; diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index 6acebfbb89..ea36a5ab8f 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -92,13 +92,13 @@ public: return serializationTestOption ? serializationTestOption->turn : std::max(CConfigDB::GetIfInitialised("serializationtest", -1), -1); }()}, - m_RejoinTestTurn{[&]() -> std::optional + m_RejoinTestTurn{[&]() -> std::optional { const auto* rejoinTestOption{ std::get_if(&debugOptions.test)}; if (rejoinTestOption) return rejoinTestOption->turn; - const int configVal{CConfigDB::GetIfInitialised("rejointest", -1)}; + const turn_id_t configVal{CConfigDB::GetIfInitialised("rejointest", -1)}; if (configVal >= 0) return configVal; return std::nullopt; @@ -163,17 +163,17 @@ public: std::set m_LoadedScripts; - uint32_t m_TurnNumber; + turn_id_t m_TurnNumber; bool m_EnableOOSLog{false}; OsPath m_OOSLogPath; // Functions and data for the serialization test mode: (see Update() for relevant comments) - std::optional m_SerializationTestTurn; + std::optional m_SerializationTestTurn; bool m_TestingSerialization{false}; bool m_EnableSerializationTest{false}; - std::optional m_RejoinTestTurn; + std::optional m_RejoinTestTurn; bool m_TestingRejoin{false}; // Secondary simulation (NB: order matters for destruction). @@ -383,7 +383,7 @@ void CSimulation2Impl::InitRNGSeedAI() void CSimulation2Impl::Update(int turnLength, const std::vector& commands) { PROFILE3("sim update"); - PROFILE2_ATTR("turn %d", (int)m_TurnNumber); + PROFILE2_ATTR("turn %d", m_TurnNumber); fixed turnLengthFixed = fixed::FromInt(turnLength) / 1000; @@ -408,11 +408,11 @@ void CSimulation2Impl::Update(int turnLength, const std::vector(m_RejoinTestTurn.value()) == m_TurnNumber; + m_RejoinTestTurn.value() == m_TurnNumber; if (startRejoinTest) m_TestingRejoin = true; @@ -891,11 +891,11 @@ bool CSimulation2::DeserializeState(std::istream& stream) return m->m_ComponentManager.DeserializeState(stream); } -void CSimulation2::ActivateRejoinTest(int turn) +void CSimulation2::ActivateRejoinTest(turn_id_t turn) { if (m->m_RejoinTestTurn.has_value()) return; - LOGMESSAGERENDER("Rejoin test will activate in %i turns", turn - m->m_TurnNumber); + LOGMESSAGERENDER("Rejoin test will activate in %d turns", turn - m->m_TurnNumber); m->m_RejoinTestTurn = turn; } diff --git a/source/simulation2/Simulation2.h b/source/simulation2/Simulation2.h index 2c326b0629..cb3339c42c 100644 --- a/source/simulation2/Simulation2.h +++ b/source/simulation2/Simulation2.h @@ -22,6 +22,7 @@ #include "lib/file/vfs/vfs_path.h" #include "lib/status.h" #include "ps/Loader.h" +#include "simulation2/helpers/SimulationCommand.h" #include "simulation2/system/DebugOptions.h" #include "simulation2/system/Entity.h" @@ -240,7 +241,7 @@ public: /** * Activate the rejoin-test feature for turn @param turn. */ - void ActivateRejoinTest(int turn); + void ActivateRejoinTest(turn_id_t turn); std::string GenerateSchema(); diff --git a/source/simulation2/helpers/SimulationCommand.h b/source/simulation2/helpers/SimulationCommand.h index 6596f40315..351a512528 100644 --- a/source/simulation2/helpers/SimulationCommand.h +++ b/source/simulation2/helpers/SimulationCommand.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,6 +24,12 @@ #include #include +/** + * At 1000 turns/second, a 32-bit counter would overflow in ~49 days. + * No overflow checks are needed. + */ +using turn_id_t = std::int32_t; + struct JSContext; /** diff --git a/source/simulation2/system/LocalTurnManager.cpp b/source/simulation2/system/LocalTurnManager.cpp index 321106912e..a86abfa5aa 100644 --- a/source/simulation2/system/LocalTurnManager.cpp +++ b/source/simulation2/system/LocalTurnManager.cpp @@ -42,12 +42,12 @@ void CLocalTurnManager::PostCommand(JS::HandleValue data) AddCommand(m_ClientId, m_PlayerId, data, m_CurrentTurn + m_CommandDelay); } -void CLocalTurnManager::NotifyFinishedOwnCommands(u32 turn) +void CLocalTurnManager::NotifyFinishedOwnCommands(turn_id_t turn) { FinishedAllCommands(turn, m_TurnLength); } -void CLocalTurnManager::NotifyFinishedUpdate(u32 /*turn*/, const UpdateCallback&) +void CLocalTurnManager::NotifyFinishedUpdate(turn_id_t /*turn*/, const UpdateCallback&) { #if 0 // this hurts performance and is only useful for verifying log replays std::string hash; diff --git a/source/simulation2/system/LocalTurnManager.h b/source/simulation2/system/LocalTurnManager.h index 35ad4382c5..578f93ac9b 100644 --- a/source/simulation2/system/LocalTurnManager.h +++ b/source/simulation2/system/LocalTurnManager.h @@ -41,9 +41,9 @@ public: void PostCommand(player_id_t playerid, JS::HandleValue data); protected: - void NotifyFinishedOwnCommands(u32 turn) override; + void NotifyFinishedOwnCommands(turn_id_t turn) override; - void NotifyFinishedUpdate(u32 turn, const UpdateCallback& sendEventToAll) override; + void NotifyFinishedUpdate(turn_id_t turn, const UpdateCallback& sendEventToAll) override; }; #endif // INCLUDED_LOCALTURNMANAGER diff --git a/source/simulation2/system/ReplayTurnManager.cpp b/source/simulation2/system/ReplayTurnManager.cpp index 512ebc24f5..d2fed32a40 100644 --- a/source/simulation2/system/ReplayTurnManager.cpp +++ b/source/simulation2/system/ReplayTurnManager.cpp @@ -47,18 +47,18 @@ CReplayTurnManager::CReplayTurnManager(CSimulation2& simulation, IReplayLogger& { } -void CReplayTurnManager::StoreReplayCommand(u32 turn, int player, const std::string& command) +void CReplayTurnManager::StoreReplayCommand(turn_id_t turn, int player, const std::string& command) { // Using the pair we make sure that commands per turn will be processed in the correct order m_ReplayCommands[turn].emplace_back(player, command); } -void CReplayTurnManager::StoreReplayHash(u32 turn, const std::string& hash, bool quick) +void CReplayTurnManager::StoreReplayHash(turn_id_t turn, const std::string& hash, bool quick) { m_ReplayHash[turn] = std::make_pair(hash, quick); } -void CReplayTurnManager::StoreReplayTurnLength(u32 turn, u32 turnLength) +void CReplayTurnManager::StoreReplayTurnLength(turn_id_t turn, u32 turnLength) { m_ReplayTurnLengths[turn] = turnLength; @@ -67,12 +67,12 @@ void CReplayTurnManager::StoreReplayTurnLength(u32 turn, u32 turnLength) m_TurnLength = m_ReplayTurnLengths[0]; } -void CReplayTurnManager::StoreFinalReplayTurn(u32 turn) +void CReplayTurnManager::StoreFinalReplayTurn(turn_id_t turn) { m_FinalTurn = turn; } -void CReplayTurnManager::NotifyFinishedUpdate(u32 turn, const UpdateCallback& sendEventToAll) +void CReplayTurnManager::NotifyFinishedUpdate(turn_id_t turn, const UpdateCallback& sendEventToAll) { if (turn == 1 && m_FinalTurn == 0) sendEventToAll(EventNameReplayFinished, std::nullopt); @@ -83,7 +83,7 @@ void CReplayTurnManager::NotifyFinishedUpdate(u32 turn, const UpdateCallback& se DoTurn(turn, sendEventToAll); // Compare hash if it exists in the replay and if we didn't have an OOS already - std::map>::iterator turnHashIt = m_ReplayHash.find(turn); + std::map>::iterator turnHashIt = m_ReplayHash.find(turn); if (m_HasSyncError || turnHashIt == m_ReplayHash.end()) return; @@ -119,9 +119,9 @@ void CReplayTurnManager::NotifyFinishedUpdate(u32 turn, const UpdateCallback& se sendEventToAll(EventNameReplayOutOfSync, paramData); } -void CReplayTurnManager::DoTurn(u32 turn, const UpdateCallback& sendEventToAll) +void CReplayTurnManager::DoTurn(turn_id_t turn, const UpdateCallback& sendEventToAll) { - debug_printf("Executing turn %u of %u\n", turn, m_FinalTurn); + debug_printf("Executing turn %d of %d\n", turn, m_FinalTurn); m_TurnLength = m_ReplayTurnLengths[turn]; diff --git a/source/simulation2/system/ReplayTurnManager.h b/source/simulation2/system/ReplayTurnManager.h index 7335b7c540..4c3500b5fb 100644 --- a/source/simulation2/system/ReplayTurnManager.h +++ b/source/simulation2/system/ReplayTurnManager.h @@ -40,18 +40,18 @@ class CReplayTurnManager : public CLocalTurnManager public: CReplayTurnManager(CSimulation2& simulation, IReplayLogger& replay); - void StoreReplayCommand(u32 turn, int player, const std::string& command); + void StoreReplayCommand(turn_id_t turn, int player, const std::string& command); - void StoreReplayTurnLength(u32 turn, u32 turnLength); + void StoreReplayTurnLength(turn_id_t turn, u32 turnLength); - void StoreReplayHash(u32 turn, const std::string& hash, bool quick); + void StoreReplayHash(turn_id_t turn, const std::string& hash, bool quick); - void StoreFinalReplayTurn(u32 turn); + void StoreFinalReplayTurn(turn_id_t turn); private: - void NotifyFinishedUpdate(u32 turn, const UpdateCallback& sendEventToAll) override; + void NotifyFinishedUpdate(turn_id_t turn, const UpdateCallback& sendEventToAll) override; - void DoTurn(u32 turn, const UpdateCallback& sendEventToAll); + void DoTurn(turn_id_t turn, const UpdateCallback& sendEventToAll); static const CStr EventNameReplayFinished; static const CStr EventNameReplayOutOfSync; @@ -59,13 +59,13 @@ private: bool m_HasSyncError = false; // Contains the commands of every player on each turn - std::map>> m_ReplayCommands; + std::map>> m_ReplayCommands; // Contains the length of every turn - std::map m_ReplayTurnLengths; + std::map m_ReplayTurnLengths; // Contains all replay hash values and weather or not the quick hash method was used - std::map> m_ReplayHash; + std::map> m_ReplayHash; }; #endif // INCLUDED_REPLAYTURNMANAGER diff --git a/source/simulation2/system/TurnManager.cpp b/source/simulation2/system/TurnManager.cpp index 73e3586ac7..60c8e72df3 100644 --- a/source/simulation2/system/TurnManager.cpp +++ b/source/simulation2/system/TurnManager.cpp @@ -48,14 +48,14 @@ const CStr CTurnManager::EventNameSavegameLoaded = "SavegameLoaded"; CTurnManager::CTurnManager(CSimulation2& simulation, u32 defaultTurnLength, u32 commandDelay, int clientId, IReplayLogger& replay) : m_Simulation2(simulation), m_CurrentTurn(0), m_CommandDelay(commandDelay), m_ReadyTurn(commandDelay - 1), m_TurnLength(defaultTurnLength), m_PlayerId(-1), m_ClientId(clientId), m_DeltaSimTime(0), m_Replay(replay), - m_FinalTurn(std::numeric_limits::max()), m_TimeWarpNumTurns(0) + m_FinalTurn(std::numeric_limits::max()), m_TimeWarpNumTurns(0) { Script::Request rq(m_Simulation2.GetScriptInterface()); m_QuickSaveMetadata.init(rq.cx); m_QueuedCommands.resize(1); } -void CTurnManager::ResetState(u32 newCurrentTurn, u32 newReadyTurn) +void CTurnManager::ResetState(turn_id_t newCurrentTurn, turn_id_t newReadyTurn) { m_CurrentTurn = newCurrentTurn; m_ReadyTurn = newReadyTurn; @@ -141,7 +141,7 @@ bool CTurnManager::Update(float simFrameLength, size_t maxTurns, const UpdateCal // Put all the client commands into a single list, in a globally consistent order std::vector commands; - for (std::pair>& p : m_QueuedCommands[0]) + for (std::pair>& p : m_QueuedCommands[0]) commands.insert(commands.end(), std::make_move_iterator(p.second.begin()), std::make_move_iterator(p.second.end())); m_QueuedCommands.pop_front(); @@ -184,7 +184,7 @@ bool CTurnManager::UpdateFastForward() // Put all the client commands into a single list, in a globally consistent order std::vector commands; - for (std::pair>& p : m_QueuedCommands[0]) + for (std::pair>& p : m_QueuedCommands[0]) commands.insert(commands.end(), std::make_move_iterator(p.second.begin()), std::make_move_iterator(p.second.end())); m_QueuedCommands.pop_front(); @@ -214,7 +214,7 @@ void CTurnManager::Interpolate(float simFrameLength, float realFrameLength) m_Simulation2.Interpolate(simFrameLength, offset, realFrameLength); } -void CTurnManager::AddCommand(int client, int player, JS::HandleValue data, u32 turn) +void CTurnManager::AddCommand(int client, int player, JS::HandleValue data, turn_id_t turn) { NETTURN_LOG("AddCommand(client=%d player=%d turn=%d current=%d, ready=%d)\n", client, player, turn, m_CurrentTurn, m_ReadyTurn); @@ -239,7 +239,7 @@ void CTurnManager::AddCommand(int client, int player, JS::HandleValue data, u32 m_QueuedCommands[turn - (m_CurrentTurn+1)][client].emplace_back(player, rq.cx, data); } -void CTurnManager::FinishedAllCommands(u32 turn, u32 turnLength) +void CTurnManager::FinishedAllCommands(turn_id_t turn, u32 turnLength) { NETTURN_LOG("FinishedAllCommands(%d, %d)\n", turn, turnLength); @@ -248,7 +248,7 @@ void CTurnManager::FinishedAllCommands(u32 turn, u32 turnLength) m_TurnLength = turnLength; } -bool CTurnManager::TurnNeedsFullHash(u32 turn) const +bool CTurnManager::TurnNeedsFullHash(turn_id_t turn) const { // Check immediately for errors caused by e.g. inconsistent game versions // (The hash is computed after the first sim update, so we start at turn == 1) diff --git a/source/simulation2/system/TurnManager.h b/source/simulation2/system/TurnManager.h index 4168568bbd..8e1c50dc7f 100644 --- a/source/simulation2/system/TurnManager.h +++ b/source/simulation2/system/TurnManager.h @@ -101,7 +101,7 @@ public: virtual ~CTurnManager() { } - void ResetState(u32 newCurrentTurn, u32 newReadyTurn); + void ResetState(turn_id_t newCurrentTurn, turn_id_t newReadyTurn); /** * Set the current user's player ID, which will be added into command messages. @@ -146,7 +146,7 @@ public: * Called when all commands for a given turn have been received. * This allows Update to progress to that turn. */ - void FinishedAllCommands(u32 turn, u32 turnLength); + void FinishedAllCommands(turn_id_t turn, u32 turnLength); /** * Enables the recording of state snapshots every @p numTurns, @@ -163,52 +163,52 @@ public: void QuickSave(JS::HandleValue GUIMetadata); std::optional TryQuickLoad(); - u32 GetCurrentTurn() const { return m_CurrentTurn; } + turn_id_t GetCurrentTurn() const { return m_CurrentTurn; } /** * @return how many turns are ready to be computed. * (used to detect players/observers that fall behind the live game. */ - u32 GetPendingTurns() const { return m_ReadyTurn - m_CurrentTurn; } + turn_id_t GetPendingTurns() const { return m_ReadyTurn - m_CurrentTurn; } protected: /** * Store a command to be executed at a given turn. */ - void AddCommand(int client, int player, JS::HandleValue data, u32 turn); + void AddCommand(int client, int player, JS::HandleValue data, turn_id_t turn); /** * Called when this client has finished sending all its commands scheduled for the given turn. */ - virtual void NotifyFinishedOwnCommands(u32 turn) = 0; + virtual void NotifyFinishedOwnCommands(turn_id_t turn) = 0; /** * Called when this client has finished a simulation update. */ - virtual void NotifyFinishedUpdate(u32 turn, const UpdateCallback& sendEventToAll) = 0; + virtual void NotifyFinishedUpdate(turn_id_t turn, const UpdateCallback& sendEventToAll) = 0; /** * Returns whether we should compute a complete state hash for the given turn, * instead of a quick less-complete hash. */ - bool TurnNeedsFullHash(u32 turn) const; + bool TurnNeedsFullHash(turn_id_t turn) const; CSimulation2& m_Simulation2; /// The turn that we have most recently executed - u32 m_CurrentTurn; + turn_id_t m_CurrentTurn; // Current command delay (commands are scheduled for m_CurrentTurn + m_CommandDelay) u32 m_CommandDelay; /// The latest turn for which we have received all commands from all clients - u32 m_ReadyTurn; + turn_id_t m_ReadyTurn; // Current turn length u32 m_TurnLength; /// Commands queued at each turn (index 0 is for m_CurrentTurn+1) - std::deque>> m_QueuedCommands; + std::deque>> m_QueuedCommands; int m_PlayerId; uint m_ClientId; @@ -220,7 +220,7 @@ protected: IReplayLogger& m_Replay; // The number of the last turn that is allowed to be executed (used for replays) - u32 m_FinalTurn; + turn_id_t m_FinalTurn; private: size_t m_TimeWarpNumTurns; // 0 if disabled