From 16691b22baaa8a9bd0e6449be8b98e567184f393 Mon Sep 17 00:00:00 2001 From: Tom Lankhorst Date: Fri, 1 Feb 2019 19:29:43 +0100 Subject: [PATCH] Use state struct --- src/openrct2/core/Random.hpp | 24 +++++++++++++++++++----- src/openrct2/network/Network.cpp | 4 ++-- src/openrct2/rct2/S6Exporter.cpp | 4 +++- src/openrct2/scenario/Scenario.cpp | 13 ++++--------- src/openrct2/scenario/Scenario.h | 10 ++++++---- 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/openrct2/core/Random.hpp b/src/openrct2/core/Random.hpp index ca0088ca55..eea44ee9bc 100644 --- a/src/openrct2/core/Random.hpp +++ b/src/openrct2/core/Random.hpp @@ -81,16 +81,28 @@ namespace Random typedef FixedSeedSequence<2> Rct2Seed; + template struct RotateEngineState + { + UIntType s0; + UIntType s1; + }; + /** * RotateEngine adheres to the _Named Requirement_ `RandomNumberEngine` * https://en.cppreference.com/w/cpp/named_req/RandomNumberEngine */ - template class RotateEngine + template + class RotateEngine : protected RotateEngineState { static_assert(std::is_unsigned::value, "Type must be unsigned integral."); + using RotateEngineState::s0; + using RotateEngineState::s1; + public: typedef UIntType result_type; + typedef RotateEngineState state_type; + static constexpr result_type x = __x; static constexpr size_t r1 = __r1; static constexpr size_t r2 = __r2; @@ -126,6 +138,7 @@ namespace Random void seed(result_type s = default_seed) { s0 = s; + s1 = s; } template typename std::enable_if::value, void>::type seed(Sseq& seed_seq) @@ -154,6 +167,11 @@ namespace Random return lhs.s0 == rhs.s0 && lhs.s1 == rhs.s1; } + const state_type& state() const + { + return *this; + } + friend std::ostream& operator<<(std::ostream& os, const RotateEngine& e) { os << e.s0 << ' ' << e.s1; @@ -166,10 +184,6 @@ namespace Random is >> e.s1; return is; } - - protected: - result_type s0; - result_type s1; }; typedef RotateEngine Rct2Engine; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index d23a648668..91df04ba10 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -960,7 +960,7 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) void Network::CheckDesynchronizaton() { // Check synchronisation - if (GetMode() == NETWORK_MODE_CLIENT && !_desynchronised && !CheckSRAND(gCurrentTicks, scenario_rand_seed().first)) + if (GetMode() == NETWORK_MODE_CLIENT && !_desynchronised && !CheckSRAND(gCurrentTicks, scenario_rand_state().s0)) { _desynchronised = true; @@ -1596,7 +1596,7 @@ void Network::Server_Send_TICK() last_tick_sent_time = ticks; std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << (uint32_t)NETWORK_COMMAND_TICK << gCurrentTicks << scenario_rand_seed().first; + *packet << (uint32_t)NETWORK_COMMAND_TICK << gCurrentTicks << scenario_rand_state().s0; uint32_t flags = 0; // Simple counter which limits how often a sprite checksum gets sent. // This can get somewhat expensive, so we don't want to push it every tick in release, diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 266608047b..a44f43f279 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -189,7 +189,9 @@ void S6Exporter::Export() _s6.current_day = gDateMonthTicks; _s6.scenario_ticks = gScenarioTicks; - std::tie(_s6.scenario_srand_0, _s6.scenario_srand_1) = scenario_rand_seed(); + auto state = scenario_rand_state(); + _s6.scenario_srand_0 = state.s0; + _s6.scenario_srand_1 = state.s1; std::memcpy(_s6.tile_elements, gTileElements, sizeof(_s6.tile_elements)); diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index b806b3ddb0..3a45ca5375 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -477,17 +477,12 @@ static int32_t scenario_create_ducks() return 1; } -std::pair scenario_rand_seed() +const random_engine_t::state_type& scenario_rand_state() { - std::stringstream ss; - ss << gScenarioRand; - uint32_t s0, s1; - ss >> s0; - ss >> s1; - return { s0, s1 }; + return gScenarioRand.state(); }; -void scenario_rand_seed(uint32_t s0, uint32_t s1) +void scenario_rand_seed(random_engine_t::result_type s0, random_engine_t::result_type s1) { Random::Rct2Seed s{ s0, s1 }; gScenarioRand.seed(s); @@ -500,7 +495,7 @@ void scenario_rand_seed(uint32_t s0, uint32_t s1) * @return eax */ #ifndef DEBUG_DESYNC -uint32_t scenario_rand() +random_engine_t::result_type scenario_rand() #else static FILE* fp = nullptr; static const char* realm = "LC"; diff --git a/src/openrct2/scenario/Scenario.h b/src/openrct2/scenario/Scenario.h index 94936e64d6..992728208c 100644 --- a/src/openrct2/scenario/Scenario.h +++ b/src/openrct2/scenario/Scenario.h @@ -24,6 +24,8 @@ #include "../world/MapAnimation.h" #include "../world/Sprite.h" +using random_engine_t = Random::Rct2Engine; + struct ParkLoadResult; #pragma pack(push, 1) @@ -367,7 +369,7 @@ enum extern const rct_string_id ScenarioCategoryStringIds[SCENARIO_CATEGORY_COUNT]; extern uint32_t gScenarioTicks; -extern Random::Rct2Engine gScenarioRand; +extern random_engine_t gScenarioRand; extern uint8_t gScenarioObjectiveType; extern uint8_t gScenarioObjectiveYear; @@ -394,15 +396,15 @@ void load_from_sc6(const char* path); void scenario_begin(); void scenario_update(); -std::pair scenario_rand_seed(); -void scenario_rand_seed(uint32_t s0, uint32_t s1); +const random_engine_t::state_type& scenario_rand_state(); +void scenario_rand_seed(random_engine_t::result_type s0, random_engine_t::result_type s1); #ifdef DEBUG_DESYNC uint32_t dbg_scenario_rand(const char* file, const char* function, const uint32_t line, const void* data); # define scenario_rand() dbg_scenario_rand(__FILE__, __FUNCTION__, __LINE__, NULL) # define scenario_rand_data(data) dbg_scenario_rand(__FILE__, __FUNCTION__, __LINE__, data) void dbg_report_desync(uint32_t tick, uint32_t srand0, uint32_t server_srand0, const char* clientHash, const char* serverHash); #else -uint32_t scenario_rand(); +random_engine_t::result_type scenario_rand(); #endif uint32_t scenario_rand_max(uint32_t max);