1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

Use state struct

This commit is contained in:
Tom Lankhorst
2019-02-01 19:29:43 +01:00
parent 2ea347f15f
commit 16691b22ba
5 changed files with 34 additions and 21 deletions

View File

@@ -81,16 +81,28 @@ namespace Random
typedef FixedSeedSequence<2> Rct2Seed;
template<typename UIntType> struct RotateEngineState
{
UIntType s0;
UIntType s1;
};
/**
* RotateEngine adheres to the _Named Requirement_ `RandomNumberEngine`
* https://en.cppreference.com/w/cpp/named_req/RandomNumberEngine
*/
template<typename UIntType, UIntType __x, size_t __r1, size_t __r2> class RotateEngine
template<typename UIntType, UIntType __x, size_t __r1, size_t __r2>
class RotateEngine : protected RotateEngineState<UIntType>
{
static_assert(std::is_unsigned<UIntType>::value, "Type must be unsigned integral.");
using RotateEngineState<UIntType>::s0;
using RotateEngineState<UIntType>::s1;
public:
typedef UIntType result_type;
typedef RotateEngineState<result_type> 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 Sseq> typename std::enable_if<std::is_class<Sseq>::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<uint32_t, 0x1234567F, 7, 3> Rct2Engine;

View File

@@ -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<NetworkPacket> 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,

View File

@@ -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));

View File

@@ -477,17 +477,12 @@ static int32_t scenario_create_ducks()
return 1;
}
std::pair<uint32_t, uint32_t> 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";

View File

@@ -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<uint32_t, uint32_t> 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);