Add ability to restore RandomNumberGenerator state

- added `state` as a property to restore internal state of RNG;
- `get_seed()` returns last seed used to initialize the state rather than the current state.

Co-authored-by: MidZik <matt.idzik1@gmail.com>
This commit is contained in:
Andrii Doroshenko (Xrayez) 2020-12-05 22:48:26 +02:00
parent 3dc8aaaccc
commit b5107715f1
4 changed files with 33 additions and 11 deletions

View file

@ -34,6 +34,9 @@ void RandomNumberGenerator::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &RandomNumberGenerator::set_seed);
ClassDB::bind_method(D_METHOD("get_seed"), &RandomNumberGenerator::get_seed);
ClassDB::bind_method(D_METHOD("set_state", "state"), &RandomNumberGenerator::set_state);
ClassDB::bind_method(D_METHOD("get_state"), &RandomNumberGenerator::get_state);
ClassDB::bind_method(D_METHOD("randi"), &RandomNumberGenerator::randi);
ClassDB::bind_method(D_METHOD("randf"), &RandomNumberGenerator::randf);
ClassDB::bind_method(D_METHOD("randfn", "mean", "deviation"), &RandomNumberGenerator::randfn, DEFVAL(0.0), DEFVAL(1.0));
@ -42,6 +45,8 @@ void RandomNumberGenerator::_bind_methods() {
ClassDB::bind_method(D_METHOD("randomize"), &RandomNumberGenerator::randomize);
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
// Default value is non-deterministic, override it for doc generation purposes.
ADD_PROPERTY(PropertyInfo(Variant::INT, "state"), "set_state", "get_state");
// Default values are non-deterministic, override for doc generation purposes.
ADD_PROPERTY_DEFAULT("seed", 0);
ADD_PROPERTY_DEFAULT("state", 0);
}

View file

@ -44,19 +44,17 @@ protected:
public:
_FORCE_INLINE_ void set_seed(uint64_t p_seed) { randbase.seed(p_seed); }
_FORCE_INLINE_ uint64_t get_seed() { return randbase.get_seed(); }
_FORCE_INLINE_ void set_state(uint64_t p_state) { randbase.set_state(p_state); }
_FORCE_INLINE_ uint64_t get_state() const { return randbase.get_state(); }
_FORCE_INLINE_ void randomize() { randbase.randomize(); }
_FORCE_INLINE_ uint32_t randi() { return randbase.rand(); }
_FORCE_INLINE_ real_t randf() { return randbase.randf(); }
_FORCE_INLINE_ real_t randf_range(real_t p_from, real_t p_to) { return randbase.random(p_from, p_to); }
_FORCE_INLINE_ real_t randfn(real_t p_mean = 0.0, real_t p_deviation = 1.0) { return randbase.randfn(p_mean, p_deviation); }
_FORCE_INLINE_ int randi_range(int p_from, int p_to) { return randbase.random(p_from, p_to); }
RandomNumberGenerator() {}

View file

@ -61,7 +61,7 @@ static int __bsr_clz32(uint32_t x) {
class RandomPCG {
pcg32_random_t pcg;
uint64_t current_seed; // seed with this to get the same state
uint64_t current_seed; // The seed the current generator state started from.
uint64_t current_inc;
public:
@ -76,13 +76,14 @@ public:
}
_FORCE_INLINE_ uint64_t get_seed() { return current_seed; }
_FORCE_INLINE_ void set_state(uint64_t p_state) { pcg.state = p_state; }
_FORCE_INLINE_ uint64_t get_state() const { return pcg.state; }
void randomize();
_FORCE_INLINE_ uint32_t rand() {
current_seed = pcg.state;
return pcg32_random_r(&pcg);
}
_FORCE_INLINE_ uint32_t rand(uint32_t bounds) {
current_seed = pcg.state;
return pcg32_boundedrand_r(&pcg, bounds);
}