From b1c63d62383225d5326bc119a42901846f2545dc Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 17 Mar 2024 12:42:26 +0100 Subject: [PATCH 1/2] Add a getter for block functions to IEngine --- include/scratchcpp/iengine.h | 3 +++ src/engine/internal/engine.cpp | 5 +++++ src/engine/internal/engine.h | 1 + test/engine/engine_test.cpp | 2 ++ test/mocks/enginemock.h | 1 + 5 files changed, 12 insertions(+) diff --git a/include/scratchcpp/iengine.h b/include/scratchcpp/iengine.h index 9e559420..987fba22 100644 --- a/include/scratchcpp/iengine.h +++ b/include/scratchcpp/iengine.h @@ -217,6 +217,9 @@ class LIBSCRATCHCPP_EXPORT IEngine /*! Returns the index of the given block function. */ virtual unsigned int functionIndex(BlockFunc f) = 0; + /*! Returns the list of block functions. */ + virtual const std::vector &blockFunctions() const = 0; + /*! * Call this from IBlockSection#registerBlocks() to add a compile function to a block section. * \see Block sections diff --git a/src/engine/internal/engine.cpp b/src/engine/internal/engine.cpp index ed4ce7ef..85a21727 100644 --- a/src/engine/internal/engine.cpp +++ b/src/engine/internal/engine.cpp @@ -887,6 +887,11 @@ unsigned int Engine::functionIndex(BlockFunc f) return m_functions.size() - 1; } +const std::vector &Engine::blockFunctions() const +{ + return m_functions; +} + void Engine::addCompileFunction(IBlockSection *section, const std::string &opcode, BlockComp f) { auto container = blockSectionContainer(section); diff --git a/src/engine/internal/engine.h b/src/engine/internal/engine.h index 7f48f631..44ac44fb 100644 --- a/src/engine/internal/engine.h +++ b/src/engine/internal/engine.h @@ -103,6 +103,7 @@ class Engine : public IEngine void registerSection(std::shared_ptr section) override; std::vector> registeredSections() const; unsigned int functionIndex(BlockFunc f) override; + const std::vector &blockFunctions() const override; void addCompileFunction(IBlockSection *section, const std::string &opcode, BlockComp f) override; void addHatPredicateCompileFunction(IBlockSection *section, const std::string &opcode, HatPredicateCompileFunc f) override; diff --git a/test/engine/engine_test.cpp b/test/engine/engine_test.cpp index b2d390fc..1929c7a3 100644 --- a/test/engine/engine_test.cpp +++ b/test/engine/engine_test.cpp @@ -905,6 +905,8 @@ TEST(EngineTest, Functions) ASSERT_EQ(engine.functionIndex(&testFunction2), 1); ASSERT_EQ(engine.functionIndex(&testFunction1), 0); ASSERT_EQ(engine.functionIndex(&testFunction2), 1); + + ASSERT_EQ(engine.blockFunctions(), std::vector({ &testFunction1, &testFunction2 })); } void compileTest1(Compiler *) diff --git a/test/mocks/enginemock.h b/test/mocks/enginemock.h index e0e76d5a..be7a2aa3 100644 --- a/test/mocks/enginemock.h +++ b/test/mocks/enginemock.h @@ -84,6 +84,7 @@ class EngineMock : public IEngine MOCK_METHOD(void, registerSection, (std::shared_ptr), (override)); MOCK_METHOD(unsigned int, functionIndex, (BlockFunc), (override)); + MOCK_METHOD(const std::vector &, blockFunctions, (), (const, override)); MOCK_METHOD(void, addCompileFunction, (IBlockSection *, const std::string &, BlockComp), (override)); MOCK_METHOD(void, addHatPredicateCompileFunction, (IBlockSection *, const std::string &, HatPredicateCompileFunc), (override)); From 71b2b9e23393b9ddc03288c4d06500d328604d21 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 17 Mar 2024 12:43:18 +0100 Subject: [PATCH 2/2] Get functions from engine in Script --- include/scratchcpp/script.h | 3 ++- src/engine/internal/engine.cpp | 2 -- src/engine/script.cpp | 24 +++++++++++------------- src/engine/script_p.h | 3 --- test/script/script_test.cpp | 16 ++++++++++++---- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/include/scratchcpp/script.h b/include/scratchcpp/script.h index 010906f5..fe3a44ee 100644 --- a/include/scratchcpp/script.h +++ b/include/scratchcpp/script.h @@ -38,7 +38,6 @@ class LIBSCRATCHCPP_EXPORT Script bool runHatPredicate(); void setProcedures(const std::vector &procedures); - void setFunctions(const std::vector &functions); void setConstValues(const std::vector &values); void setVariables(const std::vector &variables); void setLists(const std::vector &lists); @@ -47,6 +46,8 @@ class LIBSCRATCHCPP_EXPORT Script std::shared_ptr start(Target *target); private: + BlockFunc *getFunctions() const; + spimpl::unique_impl_ptr impl; }; diff --git a/src/engine/internal/engine.cpp b/src/engine/internal/engine.cpp index 85a21727..8edf260f 100644 --- a/src/engine/internal/engine.cpp +++ b/src/engine/internal/engine.cpp @@ -244,7 +244,6 @@ void Engine::compile() for (auto block : blocks) { if (m_scripts.count(block) == 1) { - m_scripts[block]->setFunctions(m_functions); m_scripts[block]->setProcedures(procedureBytecodes); m_scripts[block]->setConstValues(compiler.constValues()); m_scripts[block]->setVariables(compiler.variables()); @@ -293,7 +292,6 @@ void Engine::compile() compiler.end(); script->setBytecode(compiler.bytecode()); - script->setFunctions(m_functions); script->setConstValues(compiler.constValues()); script->setVariables(compiler.variables()); script->setLists(compiler.lists()); diff --git a/src/engine/script.cpp b/src/engine/script.cpp index c770a23a..d544b5b8 100644 --- a/src/engine/script.cpp +++ b/src/engine/script.cpp @@ -57,7 +57,6 @@ void Script::setHatPredicateBytecode(const std::vector &code) if (impl->engine && !code.empty()) { impl->hatPredicateVm = std::make_shared(impl->engine->stage(), impl->engine, this); impl->hatPredicateVm->setBytecode(impl->hatPredicateBytecodeVector.data()); - impl->hatPredicateVm->setFunctions(impl->functions); impl->hatPredicateVm->setConstValues(impl->constValues); } } @@ -70,6 +69,7 @@ bool Script::runHatPredicate() { if (impl->hatPredicateVm && impl->hatPredicateVm->bytecode()) { impl->hatPredicateVm->reset(); + impl->hatPredicateVm->setFunctions(getFunctions()); impl->hatPredicateVm->run(); assert(impl->hatPredicateVm->registerCount() == 1); @@ -92,14 +92,14 @@ std::shared_ptr Script::start(Target *target) auto vm = std::make_shared(target, impl->engine, this); vm->setBytecode(impl->bytecode); vm->setProcedures(impl->procedures); - vm->setFunctions(impl->functions); + vm->setFunctions(getFunctions()); vm->setConstValues(impl->constValues); Sprite *sprite = nullptr; if (target && !target->isStage()) sprite = dynamic_cast(target); - if (impl->target && sprite && sprite->isClone() && impl->engine) { + if (impl->target && sprite && sprite->isClone()) { Target *root = sprite->cloneSprite(); if (root != impl->target) { @@ -156,16 +156,6 @@ void Script::setProcedures(const std::vector &procedures) impl->procedures = impl->proceduresVector.data(); } -/*! Sets the list of functions. */ -void Script::setFunctions(const std::vector &functions) -{ - impl->functionsVector = functions; - impl->functions = impl->functionsVector.data(); - - if (impl->hatPredicateVm) - impl->hatPredicateVm->setFunctions(impl->functions); -} - /*! Sets the list of constant values. */ void Script::setConstValues(const std::vector &values) { @@ -191,3 +181,11 @@ void Script::setLists(const std::vector &lists) { impl->lists = lists; } + +BlockFunc *Script::getFunctions() const +{ + if (impl->engine) + return const_cast(impl->engine->blockFunctions().data()); + + return nullptr; +} diff --git a/src/engine/script_p.h b/src/engine/script_p.h index 3d7ca6a1..d3f991a4 100644 --- a/src/engine/script_p.h +++ b/src/engine/script_p.h @@ -33,9 +33,6 @@ struct ScriptPrivate unsigned int **procedures = nullptr; std::vector proceduresVector; - BlockFunc *functions = nullptr; - std::vector functionsVector; - const Value *constValues = nullptr; std::vector constValuesVector; diff --git a/test/script/script_test.cpp b/test/script/script_test.cpp index 4fb5bbae..9f687d53 100644 --- a/test/script/script_test.cpp +++ b/test/script/script_test.cpp @@ -12,6 +12,7 @@ using namespace libscratchcpp; using ::testing::Return; +using ::testing::ReturnRef; using ::testing::_; class ScriptTest : public testing::Test @@ -73,10 +74,13 @@ TEST_F(ScriptTest, HatPredicate) return 0; }; + std::vector functions1 = { f1 }; + std::vector functions2 = { f1, f2, f3 }; + + EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions1)); stageTest = nullptr; engineTest = nullptr; scriptTest = nullptr; - script.setFunctions({ f1 }); script.setConstValues({ "test" }); script.setHatPredicateBytecode({ vm::OP_START, vm::OP_CONST, 0, vm::OP_PRINT, vm::OP_EXEC, 0, vm::OP_HALT }); testing::internal::CaptureStdout(); @@ -86,11 +90,11 @@ TEST_F(ScriptTest, HatPredicate) ASSERT_EQ(engineTest, &m_engine); ASSERT_EQ(scriptTest, &script); + EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions2)); stageTest = nullptr; engineTest = nullptr; scriptTest = nullptr; script.setHatPredicateBytecode({ vm::OP_START, vm::OP_CONST, 0, vm::OP_PRINT, vm::OP_EXEC, 1, vm::OP_HALT }); - script.setFunctions({ f1, f2, f3 }); script.setConstValues({ 5 }); testing::internal::CaptureStdout(); ASSERT_TRUE(script.runHatPredicate()); @@ -99,6 +103,7 @@ TEST_F(ScriptTest, HatPredicate) ASSERT_EQ(engineTest, &m_engine); ASSERT_EQ(scriptTest, &script); + EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions2)); stageTest = nullptr; engineTest = nullptr; scriptTest = nullptr; @@ -119,6 +124,7 @@ TEST_F(ScriptTest, Start) static std::vector bytecode = { vm::OP_START, vm::OP_HALT }; static std::vector procedures = { bytecode.data() }; static std::vector functions = { &testFunction }; + static std::vector noFunctions; static std::vector constValues = { "test" }; std::shared_ptr var1 = std::make_unique("a", "", Value()); @@ -144,6 +150,7 @@ TEST_F(ScriptTest, Start) Script script2(&m_target, nullptr, &m_engine); + EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(noFunctions)); vm = script2.start(); ASSERT_TRUE(vm); ASSERT_EQ(vm->target(), &m_target); @@ -152,11 +159,11 @@ TEST_F(ScriptTest, Start) Script script3(&m_target, nullptr, &m_engine); script3.setBytecode(bytecode); script3.setProcedures(procedures); - script3.setFunctions(functions); script3.setConstValues(constValues); script3.setVariables(variables); script3.setLists(lists); + EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions)); vm = script3.start(); ASSERT_TRUE(vm); ASSERT_EQ(vm->bytecode()[0], bytecode[0]); @@ -166,6 +173,7 @@ TEST_F(ScriptTest, Start) ASSERT_EQ(vm->variables()[0], variables[0]->valuePtr()); ASSERT_EQ(vm->lists()[0], lists[0]); + EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions)); Target target; target.addVariable(var1); target.addList(list1); @@ -194,11 +202,11 @@ TEST_F(ScriptTest, Start) Script script4(&root, nullptr, &m_engine); script4.setBytecode(bytecode); script4.setProcedures(procedures); - script4.setFunctions(functions); script4.setConstValues(constValues); script4.setVariables(variables); script4.setLists(lists); + EXPECT_CALL(m_engine, blockFunctions()).WillOnce(ReturnRef(functions)); vm = script4.start(clone.get()); ASSERT_TRUE(vm);