Skip to content

Commit

Permalink
Merge pull request #29 from goostengine/rng-singleton
Browse files Browse the repository at this point in the history
Add `Random` singleton
  • Loading branch information
Xrayez authored Oct 27, 2020
2 parents 70b9ba4 + e943272 commit 9822a07
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 0 deletions.
7 changes: 7 additions & 0 deletions core/math/random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "random.h"

Random *Random::singleton = nullptr;

void Random::_bind_methods() {
ClassDB::bind_method(D_METHOD("new_instance"), &Random::new_instance);
}
27 changes: 27 additions & 0 deletions core/math/random.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef GOOST_RANDOM_H
#define GOOST_RANDOM_H

#include "core/math/random_number_generator.h"

class Random : public RandomNumberGenerator {
GDCLASS(Random, RandomNumberGenerator);

private:
static Random *singleton;

protected:
static void _bind_methods();

public:
static Random* get_singleton() { return singleton; }

Ref<Random> new_instance() const { return memnew(Random); }

Random() {
if (!singleton) {
singleton = this;
}
}
};

#endif // GOOST_RANDOM_H
8 changes: 8 additions & 0 deletions core/math/register_math_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@

#include "2d/geometry/goost_geometry_2d.h"
#include "2d/geometry/goost_geometry_2d_bind.h"
#include "random.h"

static Ref<Random> _random;
static _GoostGeometry2D *_goost_geometry_2d = nullptr;

namespace goost {

void register_math_types() {
_random.instance();
ClassDB::register_class<Random>();
Object *random = Object::cast_to<Object>(Random::get_singleton());
Engine::get_singleton()->add_singleton(Engine::Singleton("Random", random));

_goost_geometry_2d = memnew(_GoostGeometry2D);
GoostGeometry2D::initialize();

Expand All @@ -24,6 +31,7 @@ void register_math_types() {
}

void unregister_math_types() {
_random.unref();
memdelete(_goost_geometry_2d);
GoostGeometry2D::finalize();
}
Expand Down
30 changes: 30 additions & 0 deletions doc/Random.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Random" inherits="RandomNumberGenerator" version="3.2">
<brief_description>
An instance of [RandomNumberGenerator] available at [@GlobalScope].
</brief_description>
<description>
This is a singleton which allows to use [RandomNumberGenerator] methods without instantiating a dedicated object. This means that [Random] can be used via script with methods such as [method @GDScript.randi]:
[codeblock]
Random.randomize() # Time-based.
Random.seed = hash("Goost") # Manual.
var i = Random.randi() % 100
var f = Random.randf_range(-1.0, 1.0)
[/codeblock]
The class may implement other methods other than what [RandomNumberGenerator] already provides out of the box.
It's not possible to instantiate a new [Random] instance with [code]Random.new()[/code] in GDScript. If you'd like to instantiate a local instance of [Random], use [method new_instance] instead, or [code]ClassDB.instance("Random")[/code], see [method ClassDB.instance].
</description>
<tutorials>
</tutorials>
<methods>
<method name="new_instance" qualifiers="const">
<return type="Random">
</return>
<description>
Instantiates a new local [Random] instance based on [RandomNumberGenerator]. Does not override the [Random] instance accessible at [@GlobalScope].
</description>
</method>
</methods>
<constants>
</constants>
</class>
1 change: 1 addition & 0 deletions goost.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def get_child_components(parent):
"PolyDecompParameters2D",
"PolyOffsetParameters2D",
"PolyNode2D",
"Random",
"ShapeCast2D",
"VisualShape2D",
]
Expand Down
23 changes: 23 additions & 0 deletions tests/project/goost/core/math/test_random.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
extends "res://addons/gut/test.gd"


func test_create_local_instance():
var rng = Random.new_instance()
Random.seed = hash("Goost")
rng.seed = 37
assert_ne(rng, Random, "The new local instance should not override the global one")
assert_ne(rng.seed, Random.seed)
assert_lt(rng.randf(), 1.0)


func test_singleton():
Random.randomize()
Random.seed = 37
for x in 100:
var f = Random.randf()
assert_lt(f, 1.0)
assert_gt(f, 0.0)
for x in 100:
var i = Random.randi() % 100
assert_lt(i, 99)
assert_gt(i, 0)

0 comments on commit 9822a07

Please sign in to comment.