Skip to content

Commit 2d4f173

Browse files
authored
Merge pull request #220 from scratchcpp/randomgenerator_class
Add RandomGenerator class
2 parents cbe32cc + 5e5410f commit 2d4f173

File tree

14 files changed

+215
-41
lines changed

14 files changed

+215
-41
lines changed

src/engine/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@ target_sources(scratchcpp
1818
internal/timer.h
1919
internal/blocksectioncontainer.cpp
2020
internal/blocksectioncontainer.h
21-
internal/global.h
21+
internal/randomgenerator.h
22+
internal/randomgenerator.cpp
23+
internal/irandomgenerator.h
2224
)

src/engine/internal/engine.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ Engine::Engine() :
2727
m_defaultTimer(std::make_unique<Timer>()),
2828
m_timer(m_defaultTimer.get())
2929
{
30-
srand(time(NULL));
3130
}
3231

3332
void Engine::clear()

src/engine/internal/global.h

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
namespace libscratchcpp
6+
{
7+
8+
class IRandomGenerator
9+
{
10+
public:
11+
virtual ~IRandomGenerator() { }
12+
13+
virtual long randint(long start, long end) const = 0;
14+
virtual double randintDouble(double start, double end) const = 0;
15+
};
16+
17+
} // namespace libscratchcpp
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#include <random>
4+
5+
#include "randomgenerator.h"
6+
7+
using namespace libscratchcpp;
8+
9+
std::shared_ptr<RandomGenerator> RandomGenerator::m_instance = std::make_shared<RandomGenerator>();
10+
11+
RandomGenerator::RandomGenerator() :
12+
m_generator(std::make_unique<std::mt19937>(m_device()))
13+
{
14+
}
15+
16+
std::shared_ptr<RandomGenerator> RandomGenerator::instance()
17+
{
18+
return m_instance;
19+
}
20+
21+
long RandomGenerator::randint(long start, long end) const
22+
{
23+
if (start > end) {
24+
long tmp = start;
25+
start = end;
26+
end = tmp;
27+
}
28+
29+
std::uniform_int_distribution<long> distribution(start, end);
30+
return distribution(*m_generator);
31+
}
32+
33+
double RandomGenerator::randintDouble(double start, double end) const
34+
{
35+
if (start > end) {
36+
double tmp = start;
37+
start = end;
38+
end = tmp;
39+
}
40+
41+
std::uniform_real_distribution<double> distribution(start, end);
42+
return distribution(*m_generator);
43+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <memory>
6+
#include <random>
7+
8+
#include "irandomgenerator.h"
9+
10+
namespace libscratchcpp
11+
{
12+
13+
class RandomGenerator : public IRandomGenerator
14+
{
15+
public:
16+
RandomGenerator();
17+
RandomGenerator(const RandomGenerator &) = delete;
18+
19+
static std::shared_ptr<RandomGenerator> instance();
20+
21+
long randint(long start, long end) const override;
22+
double randintDouble(double start, double end) const override;
23+
24+
private:
25+
static std::shared_ptr<RandomGenerator> m_instance;
26+
std::random_device m_device;
27+
std::unique_ptr<std::mt19937> m_generator;
28+
};
29+
30+
} // namespace libscratchcpp

src/engine/script_p.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
#include <vector>
66
#include <scratchcpp/value.h>
77

8-
#include "engine/internal/global.h"
9-
108
namespace libscratchcpp
119
{
1210

src/engine/virtualmachine_p.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <cassert>
99

1010
#include "virtualmachine_p.h"
11-
#include "internal/global.h"
11+
#include "internal/randomgenerator.h"
1212

1313
#define MAX_REG_COUNT 1024
1414

@@ -29,6 +29,8 @@ using namespace vm;
2929

3030
static const double pi = std::acos(-1); // TODO: Use std::numbers::pi in C++20
3131

32+
IRandomGenerator *VirtualMachinePrivate::rng = nullptr;
33+
3234
const unsigned int VirtualMachinePrivate::instruction_arg_count[] = {
3335
0, // OP_START
3436
0, // OP_HALT
@@ -106,6 +108,9 @@ VirtualMachinePrivate::VirtualMachinePrivate(VirtualMachine *vm, Target *target,
106108
regs[i] = new Value();
107109
loops.reserve(256);
108110
callTree.reserve(1024);
111+
112+
if (!rng)
113+
rng = RandomGenerator::instance().get();
109114
}
110115

111116
VirtualMachinePrivate::~VirtualMachinePrivate()
@@ -360,7 +365,7 @@ do_loop_end : {
360365
DISPATCH();
361366

362367
do_random:
363-
REPLACE_RET_VALUE(randint<long>(READ_REG(0, 2)->toDouble(), READ_REG(1, 2)->toDouble()), 2);
368+
REPLACE_RET_VALUE(rng->randint(READ_REG(0, 2)->toDouble(), READ_REG(1, 2)->toDouble()), 2);
364369
FREE_REGS(1);
365370
DISPATCH();
366371

@@ -539,7 +544,7 @@ do_list_del : {
539544
index = 0;
540545
} else if (str == "random") {
541546
size_t size = list->size();
542-
index = size == 0 ? 0 : randint<size_t>(1, size);
547+
index = size == 0 ? 0 : rng->randint(1, size);
543548
} else
544549
index = 0;
545550
} else {
@@ -567,7 +572,7 @@ do_list_insert : {
567572
index = 0;
568573
} else if (str == "random") {
569574
size_t size = list->size();
570-
index = size == 0 ? 1 : randint<size_t>(1, size);
575+
index = size == 0 ? 1 : rng->randint(1, size);
571576
} else
572577
index = 0;
573578
} else {
@@ -594,7 +599,7 @@ do_list_replace : {
594599
index = list->size();
595600
else if (str == "random") {
596601
size_t size = list->size();
597-
index = size == 0 ? 0 : randint<size_t>(1, size);
602+
index = size == 0 ? 0 : rng->randint(1, size);
598603
} else
599604
index = 0;
600605
} else {
@@ -617,7 +622,7 @@ do_list_get_item : {
617622
index = list->size();
618623
else if (str == "random") {
619624
size_t size = list->size();
620-
index = size == 0 ? 0 : randint<size_t>(1, size);
625+
index = size == 0 ? 0 : rng->randint(1, size);
621626
} else
622627
index = 0;
623628
} else {

src/engine/virtualmachine_p.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class IEngine;
1515
class Script;
1616
class Value;
1717
class List;
18+
class IRandomGenerator;
1819

1920
struct VirtualMachinePrivate
2021
{
@@ -65,6 +66,8 @@ struct VirtualMachinePrivate
6566

6667
Value **regs = nullptr;
6768
size_t regCount = 0;
69+
70+
static IRandomGenerator *rng;
6871
};
6972

7073
} // namespace libscratchcpp

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ add_subdirectory(extensions)
3030
add_subdirectory(engine)
3131
add_subdirectory(clock)
3232
add_subdirectory(timer)
33+
add_subdirectory(randomgenerator)

0 commit comments

Comments
 (0)