Skip to content

Commit f2965e9

Browse files
authored
Merge pull request #516 from scratchcpp/script_functions_from_engine
Get block functions from engine in Script
2 parents 23b8a95 + 71b2b9e commit f2965e9

File tree

9 files changed

+37
-23
lines changed

9 files changed

+37
-23
lines changed

include/scratchcpp/iengine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
217217
/*! Returns the index of the given block function. */
218218
virtual unsigned int functionIndex(BlockFunc f) = 0;
219219

220+
/*! Returns the list of block functions. */
221+
virtual const std::vector<BlockFunc> &blockFunctions() const = 0;
222+
220223
/*!
221224
* Call this from IBlockSection#registerBlocks() to add a compile function to a block section.
222225
* \see <a href="blockSections.html">Block sections</a>

include/scratchcpp/script.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class LIBSCRATCHCPP_EXPORT Script
3838
bool runHatPredicate();
3939

4040
void setProcedures(const std::vector<unsigned int *> &procedures);
41-
void setFunctions(const std::vector<BlockFunc> &functions);
4241
void setConstValues(const std::vector<Value> &values);
4342
void setVariables(const std::vector<Variable *> &variables);
4443
void setLists(const std::vector<List *> &lists);
@@ -47,6 +46,8 @@ class LIBSCRATCHCPP_EXPORT Script
4746
std::shared_ptr<VirtualMachine> start(Target *target);
4847

4948
private:
49+
BlockFunc *getFunctions() const;
50+
5051
spimpl::unique_impl_ptr<ScriptPrivate> impl;
5152
};
5253

src/engine/internal/engine.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ void Engine::compile()
244244

245245
for (auto block : blocks) {
246246
if (m_scripts.count(block) == 1) {
247-
m_scripts[block]->setFunctions(m_functions);
248247
m_scripts[block]->setProcedures(procedureBytecodes);
249248
m_scripts[block]->setConstValues(compiler.constValues());
250249
m_scripts[block]->setVariables(compiler.variables());
@@ -293,7 +292,6 @@ void Engine::compile()
293292
compiler.end();
294293

295294
script->setBytecode(compiler.bytecode());
296-
script->setFunctions(m_functions);
297295
script->setConstValues(compiler.constValues());
298296
script->setVariables(compiler.variables());
299297
script->setLists(compiler.lists());
@@ -887,6 +885,11 @@ unsigned int Engine::functionIndex(BlockFunc f)
887885
return m_functions.size() - 1;
888886
}
889887

888+
const std::vector<BlockFunc> &Engine::blockFunctions() const
889+
{
890+
return m_functions;
891+
}
892+
890893
void Engine::addCompileFunction(IBlockSection *section, const std::string &opcode, BlockComp f)
891894
{
892895
auto container = blockSectionContainer(section);

src/engine/internal/engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class Engine : public IEngine
103103
void registerSection(std::shared_ptr<IBlockSection> section) override;
104104
std::vector<std::shared_ptr<IBlockSection>> registeredSections() const;
105105
unsigned int functionIndex(BlockFunc f) override;
106+
const std::vector<BlockFunc> &blockFunctions() const override;
106107

107108
void addCompileFunction(IBlockSection *section, const std::string &opcode, BlockComp f) override;
108109
void addHatPredicateCompileFunction(IBlockSection *section, const std::string &opcode, HatPredicateCompileFunc f) override;

src/engine/script.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ void Script::setHatPredicateBytecode(const std::vector<unsigned int> &code)
5757
if (impl->engine && !code.empty()) {
5858
impl->hatPredicateVm = std::make_shared<VirtualMachine>(impl->engine->stage(), impl->engine, this);
5959
impl->hatPredicateVm->setBytecode(impl->hatPredicateBytecodeVector.data());
60-
impl->hatPredicateVm->setFunctions(impl->functions);
6160
impl->hatPredicateVm->setConstValues(impl->constValues);
6261
}
6362
}
@@ -70,6 +69,7 @@ bool Script::runHatPredicate()
7069
{
7170
if (impl->hatPredicateVm && impl->hatPredicateVm->bytecode()) {
7271
impl->hatPredicateVm->reset();
72+
impl->hatPredicateVm->setFunctions(getFunctions());
7373
impl->hatPredicateVm->run();
7474
assert(impl->hatPredicateVm->registerCount() == 1);
7575

@@ -92,14 +92,14 @@ std::shared_ptr<VirtualMachine> Script::start(Target *target)
9292
auto vm = std::make_shared<VirtualMachine>(target, impl->engine, this);
9393
vm->setBytecode(impl->bytecode);
9494
vm->setProcedures(impl->procedures);
95-
vm->setFunctions(impl->functions);
95+
vm->setFunctions(getFunctions());
9696
vm->setConstValues(impl->constValues);
9797

9898
Sprite *sprite = nullptr;
9999
if (target && !target->isStage())
100100
sprite = dynamic_cast<Sprite *>(target);
101101

102-
if (impl->target && sprite && sprite->isClone() && impl->engine) {
102+
if (impl->target && sprite && sprite->isClone()) {
103103
Target *root = sprite->cloneSprite();
104104

105105
if (root != impl->target) {
@@ -156,16 +156,6 @@ void Script::setProcedures(const std::vector<unsigned int *> &procedures)
156156
impl->procedures = impl->proceduresVector.data();
157157
}
158158

159-
/*! Sets the list of functions. */
160-
void Script::setFunctions(const std::vector<BlockFunc> &functions)
161-
{
162-
impl->functionsVector = functions;
163-
impl->functions = impl->functionsVector.data();
164-
165-
if (impl->hatPredicateVm)
166-
impl->hatPredicateVm->setFunctions(impl->functions);
167-
}
168-
169159
/*! Sets the list of constant values. */
170160
void Script::setConstValues(const std::vector<Value> &values)
171161
{
@@ -191,3 +181,11 @@ void Script::setLists(const std::vector<List *> &lists)
191181
{
192182
impl->lists = lists;
193183
}
184+
185+
BlockFunc *Script::getFunctions() const
186+
{
187+
if (impl->engine)
188+
return const_cast<BlockFunc *>(impl->engine->blockFunctions().data());
189+
190+
return nullptr;
191+
}

src/engine/script_p.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ struct ScriptPrivate
3333
unsigned int **procedures = nullptr;
3434
std::vector<unsigned int *> proceduresVector;
3535

36-
BlockFunc *functions = nullptr;
37-
std::vector<BlockFunc> functionsVector;
38-
3936
const Value *constValues = nullptr;
4037
std::vector<Value> constValuesVector;
4138

test/engine/engine_test.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,8 @@ TEST(EngineTest, Functions)
905905
ASSERT_EQ(engine.functionIndex(&testFunction2), 1);
906906
ASSERT_EQ(engine.functionIndex(&testFunction1), 0);
907907
ASSERT_EQ(engine.functionIndex(&testFunction2), 1);
908+
909+
ASSERT_EQ(engine.blockFunctions(), std::vector<BlockFunc>({ &testFunction1, &testFunction2 }));
908910
}
909911

910912
void compileTest1(Compiler *)

test/mocks/enginemock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class EngineMock : public IEngine
8484

8585
MOCK_METHOD(void, registerSection, (std::shared_ptr<IBlockSection>), (override));
8686
MOCK_METHOD(unsigned int, functionIndex, (BlockFunc), (override));
87+
MOCK_METHOD(const std::vector<BlockFunc> &, blockFunctions, (), (const, override));
8788

8889
MOCK_METHOD(void, addCompileFunction, (IBlockSection *, const std::string &, BlockComp), (override));
8990
MOCK_METHOD(void, addHatPredicateCompileFunction, (IBlockSection *, const std::string &, HatPredicateCompileFunc), (override));

test/script/script_test.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using namespace libscratchcpp;
1313

1414
using ::testing::Return;
15+
using ::testing::ReturnRef;
1516
using ::testing::_;
1617

1718
class ScriptTest : public testing::Test
@@ -73,10 +74,13 @@ TEST_F(ScriptTest, HatPredicate)
7374
return 0;
7475
};
7576

77+
std::vector<BlockFunc> functions1 = { f1 };
78+
std::vector<BlockFunc> functions2 = { f1, f2, f3 };
79+
80+
EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions1));
7681
stageTest = nullptr;
7782
engineTest = nullptr;
7883
scriptTest = nullptr;
79-
script.setFunctions({ f1 });
8084
script.setConstValues({ "test" });
8185
script.setHatPredicateBytecode({ vm::OP_START, vm::OP_CONST, 0, vm::OP_PRINT, vm::OP_EXEC, 0, vm::OP_HALT });
8286
testing::internal::CaptureStdout();
@@ -86,11 +90,11 @@ TEST_F(ScriptTest, HatPredicate)
8690
ASSERT_EQ(engineTest, &m_engine);
8791
ASSERT_EQ(scriptTest, &script);
8892

93+
EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions2));
8994
stageTest = nullptr;
9095
engineTest = nullptr;
9196
scriptTest = nullptr;
9297
script.setHatPredicateBytecode({ vm::OP_START, vm::OP_CONST, 0, vm::OP_PRINT, vm::OP_EXEC, 1, vm::OP_HALT });
93-
script.setFunctions({ f1, f2, f3 });
9498
script.setConstValues({ 5 });
9599
testing::internal::CaptureStdout();
96100
ASSERT_TRUE(script.runHatPredicate());
@@ -99,6 +103,7 @@ TEST_F(ScriptTest, HatPredicate)
99103
ASSERT_EQ(engineTest, &m_engine);
100104
ASSERT_EQ(scriptTest, &script);
101105

106+
EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions2));
102107
stageTest = nullptr;
103108
engineTest = nullptr;
104109
scriptTest = nullptr;
@@ -119,6 +124,7 @@ TEST_F(ScriptTest, Start)
119124
static std::vector<unsigned int> bytecode = { vm::OP_START, vm::OP_HALT };
120125
static std::vector<unsigned int *> procedures = { bytecode.data() };
121126
static std::vector<BlockFunc> functions = { &testFunction };
127+
static std::vector<BlockFunc> noFunctions;
122128
static std::vector<Value> constValues = { "test" };
123129

124130
std::shared_ptr<Variable> var1 = std::make_unique<Variable>("a", "", Value());
@@ -144,6 +150,7 @@ TEST_F(ScriptTest, Start)
144150

145151
Script script2(&m_target, nullptr, &m_engine);
146152

153+
EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(noFunctions));
147154
vm = script2.start();
148155
ASSERT_TRUE(vm);
149156
ASSERT_EQ(vm->target(), &m_target);
@@ -152,11 +159,11 @@ TEST_F(ScriptTest, Start)
152159
Script script3(&m_target, nullptr, &m_engine);
153160
script3.setBytecode(bytecode);
154161
script3.setProcedures(procedures);
155-
script3.setFunctions(functions);
156162
script3.setConstValues(constValues);
157163
script3.setVariables(variables);
158164
script3.setLists(lists);
159165

166+
EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions));
160167
vm = script3.start();
161168
ASSERT_TRUE(vm);
162169
ASSERT_EQ(vm->bytecode()[0], bytecode[0]);
@@ -166,6 +173,7 @@ TEST_F(ScriptTest, Start)
166173
ASSERT_EQ(vm->variables()[0], variables[0]->valuePtr());
167174
ASSERT_EQ(vm->lists()[0], lists[0]);
168175

176+
EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions));
169177
Target target;
170178
target.addVariable(var1);
171179
target.addList(list1);
@@ -194,11 +202,11 @@ TEST_F(ScriptTest, Start)
194202
Script script4(&root, nullptr, &m_engine);
195203
script4.setBytecode(bytecode);
196204
script4.setProcedures(procedures);
197-
script4.setFunctions(functions);
198205
script4.setConstValues(constValues);
199206
script4.setVariables(variables);
200207
script4.setLists(lists);
201208

209+
EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions));
202210
vm = script4.start(clone.get());
203211

204212
ASSERT_TRUE(vm);

0 commit comments

Comments
 (0)