From adb0b2b5da20aa418ba0b758236894d587e0c388 Mon Sep 17 00:00:00 2001 From: Nikola Petrov <nikola@petrovv.com> Date: Sat, 4 Jan 2025 20:53:34 +0100 Subject: [PATCH] Start work on saving state of the manager --- inc/sys.hpp | 1 + inc/values/Dna.hpp | 10 ++-------- inc/values/DnaManager.hpp | 1 + inc/values/mrand.hpp | 11 ++++++++--- src/App.cpp | 1 - src/canvas/BackGround.cpp | 2 -- src/canvas/Tree.cpp | 1 - src/values/Dna.cpp | 1 - src/values/DnaManager.cpp | 36 +++++++++++++++++++++++++++--------- src/values/mrand.cpp | 20 ++++++++------------ 10 files changed, 47 insertions(+), 37 deletions(-) diff --git a/inc/sys.hpp b/inc/sys.hpp index 3a6db59..3b92217 100644 --- a/inc/sys.hpp +++ b/inc/sys.hpp @@ -2,6 +2,7 @@ namespace sys { + const char *transformFilePath(const char *filename); size_t saveDataToFile(const char *filename, const char *data, size_t size); size_t loadDataFromFile(const char *filename, char *data, size_t size); bool fileExists(const char *filename); diff --git a/inc/values/Dna.hpp b/inc/values/Dna.hpp index af2ee4d..11a0f7c 100644 --- a/inc/values/Dna.hpp +++ b/inc/values/Dna.hpp @@ -4,18 +4,12 @@ #include <cinttypes> #include <array> +#include "values/mrand.hpp" + #define MAX_DEPTH 8 #define MAX_POSIBLE_DEPTH 11 static_assert(MAX_DEPTH <= MAX_POSIBLE_DEPTH); -struct uint128 -{ - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; -}; - struct Branch { uint8_t colorR; diff --git a/inc/values/DnaManager.hpp b/inc/values/DnaManager.hpp index 3d92148..2be2df1 100644 --- a/inc/values/DnaManager.hpp +++ b/inc/values/DnaManager.hpp @@ -28,6 +28,7 @@ public: private: uint128 randSeed; + uint128 id; std::vector<Dna> vector; std::list<Dna *> queued; std::list<Dna *> showed; diff --git a/inc/values/mrand.hpp b/inc/values/mrand.hpp index 32ed2b7..7832161 100644 --- a/inc/values/mrand.hpp +++ b/inc/values/mrand.hpp @@ -1,11 +1,16 @@ #include <inttypes.h> -struct uint128; +struct uint128 +{ + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; +}; namespace mrand { - void setSeed(unsigned long long seed); + uint128 getState(unsigned long long seed); float getFloat(uint128 *state); int getValue(int min, int max, uint128 *state); - uint32_t getInt(); } \ No newline at end of file diff --git a/src/App.cpp b/src/App.cpp index 0c8296f..6437890 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -3,7 +3,6 @@ #include "App.hpp" #include "Math.hpp" -#include "values/mrand.hpp" #include <raylib.h> #include <raymath.h> diff --git a/src/canvas/BackGround.cpp b/src/canvas/BackGround.cpp index ef9f32f..e057631 100644 --- a/src/canvas/BackGround.cpp +++ b/src/canvas/BackGround.cpp @@ -4,8 +4,6 @@ #include "canvas/BackGroundColors.hpp" #include "canvas/Circle.hpp" #include "Math.hpp" -#include "values/mrand.hpp" - #include "stb_perlin.h" #include <raylib.h> diff --git a/src/canvas/Tree.cpp b/src/canvas/Tree.cpp index a8431c2..0880c39 100644 --- a/src/canvas/Tree.cpp +++ b/src/canvas/Tree.cpp @@ -2,7 +2,6 @@ #include "canvas/Tree.hpp" #include "canvas/Circle.hpp" -#include "values/mrand.hpp" #include "Math.hpp" #include <raylib.h> diff --git a/src/values/Dna.cpp b/src/values/Dna.cpp index 09251ce..e2eaf25 100644 --- a/src/values/Dna.cpp +++ b/src/values/Dna.cpp @@ -2,7 +2,6 @@ #include <cstddef> #include "values/Dna.hpp" -#include "values/mrand.hpp" #include <raymath.h> diff --git a/src/values/DnaManager.cpp b/src/values/DnaManager.cpp index efe4bd2..f3bccd5 100644 --- a/src/values/DnaManager.cpp +++ b/src/values/DnaManager.cpp @@ -1,28 +1,39 @@ #include <ctime> +#include <stdio.h> +#include <unistd.h> #include "values/DnaManager.hpp" -#include "values/mrand.hpp" #include "sys.hpp" #include <raylib.h> void DnaManager::init() { - mrand::setSeed(time(nullptr)); - if (sys::fileExists("id")) { - sys::loadDataFromFile("id", (char *)&randSeed, sizeof(uint128)); + sys::loadDataFromFile("id", (char *)&id, sizeof(uint128)); } else { - randSeed.a = mrand::getInt(); - randSeed.b = mrand::getInt(); - randSeed.c = mrand::getInt(); - randSeed.d = mrand::getInt(); - sys::saveDataToFile("id", (const char *)&randSeed, sizeof(uint128)); + id = mrand::getState(time(nullptr)); + sys::saveDataToFile("id", (const char *)&id, sizeof(uint128)); } + if (sys::fileExists("data")) + { + const char *filename = sys::transformFilePath("data"); + + FILE *file = fopen(filename, "rb"); + if (file == NULL) + return; + + size_t ret = fread(&randSeed, 1, sizeof(uint128), file); + fclose(file); + } + else + { + randSeed = id; + } vector.resize(NUM_PER_GEN); for (std::size_t i = 0; i < NUM_PER_GEN; i++) { @@ -33,6 +44,13 @@ void DnaManager::init() void DnaManager::deinit() { + const char *filename = sys::transformFilePath("data"); + + FILE *file = fopen(filename, "wb"); + if (file == NULL) + return; + size_t ret = fwrite(&randSeed, 1, sizeof(uint128), file); + fclose(file); } Unit DnaManager::next() diff --git a/src/values/mrand.cpp b/src/values/mrand.cpp index ead20e1..89a1102 100644 --- a/src/values/mrand.cpp +++ b/src/values/mrand.cpp @@ -2,8 +2,6 @@ #include <algorithm> #include "values/mrand.hpp" -static uint32_t rprand_state[4] = {0}; - static inline uint32_t my_rotate_left(const uint32_t x, int k) { return (x << k) | (x >> (32 - k)); @@ -36,21 +34,19 @@ uint64_t rprand_splitmix64(uint64_t &rprand_seed) namespace mrand { - void setSeed(unsigned long long seed) + uint128 getState(unsigned long long seed) { uint64_t rprand_seed = (uint64_t)seed; // Set SplitMix64 seed for further use + uint128 rprand_state; + // To generate the Xoshiro128** state, we use SplitMix64 generator first // We generate 4 pseudo-random 64bit numbers that we combine using their LSB|MSB - rprand_state[0] = (uint32_t)(rprand_splitmix64(rprand_seed) & 0xffffffff); - rprand_state[1] = (uint32_t)((rprand_splitmix64(rprand_seed) & 0xffffffff00000000) >> 32); - rprand_state[2] = (uint32_t)(rprand_splitmix64(rprand_seed) & 0xffffffff); - rprand_state[3] = (uint32_t)((rprand_splitmix64(rprand_seed) & 0xffffffff00000000) >> 32); - } - - uint32_t getInt() - { - return my_rprand_xoshiro(rprand_state); + rprand_state.a = (uint32_t)(rprand_splitmix64(rprand_seed) & 0xffffffff); + rprand_state.b = (uint32_t)((rprand_splitmix64(rprand_seed) & 0xffffffff00000000) >> 32); + rprand_state.c = (uint32_t)(rprand_splitmix64(rprand_seed) & 0xffffffff); + rprand_state.d = (uint32_t)((rprand_splitmix64(rprand_seed) & 0xffffffff00000000) >> 32); + return rprand_state; } int getValue(int min, int max, uint128 *state)