From c9e4f1e9484ef9778ba1142e08ac2a57c234510f Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 10:14:22 +0100 Subject: [PATCH 01/18] ScriptBuilder: Add currentBlock() method --- include/scratchcpp/dev/test/scriptbuilder.h | 2 + src/dev/test/scriptbuilder.cpp | 6 ++ test/dev/test_api/scriptbuilder_test.cpp | 63 ++++++++++++++++++++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/include/scratchcpp/dev/test/scriptbuilder.h b/include/scratchcpp/dev/test/scriptbuilder.h index 532f5a67..36c254ce 100644 --- a/include/scratchcpp/dev/test/scriptbuilder.h +++ b/include/scratchcpp/dev/test/scriptbuilder.h @@ -44,6 +44,8 @@ class LIBSCRATCHCPP_EXPORT ScriptBuilder void addDropdownInput(const std::string &name, const std::string &selectedValue); void addDropdownField(const std::string &name, const std::string &selectedValue); + std::shared_ptr currentBlock() const; + void build(); void run(); diff --git a/src/dev/test/scriptbuilder.cpp b/src/dev/test/scriptbuilder.cpp index 8cd1e037..b11889f0 100644 --- a/src/dev/test/scriptbuilder.cpp +++ b/src/dev/test/scriptbuilder.cpp @@ -153,6 +153,12 @@ void ScriptBuilder::addDropdownField(const std::string &name, const std::string impl->blocks.back()->addField(field); } +/*! Returns the current block (can be used e. g. with a custom Compiler instance). */ +std::shared_ptr ScriptBuilder::currentBlock() const +{ + return impl->lastBlock; +} + /*! Builds and compiles the script. */ void ScriptBuilder::build() { diff --git a/test/dev/test_api/scriptbuilder_test.cpp b/test/dev/test_api/scriptbuilder_test.cpp index c8ea801a..414467b7 100644 --- a/test/dev/test_api/scriptbuilder_test.cpp +++ b/test/dev/test_api/scriptbuilder_test.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include "../../common.h" @@ -32,7 +34,13 @@ class ScriptBuilderTest : public testing::Test TEST_F(ScriptBuilderTest, AddBlock) { + ASSERT_EQ(m_builder->currentBlock(), nullptr); + m_builder->addBlock("test_simple"); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_simple"); + m_builder->build(); testing::internal::CaptureStdout(); @@ -44,8 +52,20 @@ TEST_F(ScriptBuilderTest, AddValueInput) { m_builder->addBlock("test_print"); m_builder->addValueInput("STRING", 10); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_print"); + ASSERT_EQ(block->inputs().size(), 1); + ASSERT_EQ(block->inputAt(0)->name(), "STRING"); + m_builder->addBlock("test_print"); m_builder->addValueInput("STRING", "Hello world"); + block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_print"); + ASSERT_EQ(block->inputs().size(), 1); + ASSERT_EQ(block->inputAt(0)->name(), "STRING"); + m_builder->build(); testing::internal::CaptureStdout(); @@ -57,6 +77,12 @@ TEST_F(ScriptBuilderTest, AddNullInput) { m_builder->addBlock("test_print"); m_builder->addNullInput("STRING"); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_print"); + ASSERT_EQ(block->inputs().size(), 1); + ASSERT_EQ(block->inputAt(0)->name(), "STRING"); + m_builder->build(); testing::internal::CaptureStdout(); @@ -67,8 +93,14 @@ TEST_F(ScriptBuilderTest, AddNullInput) TEST_F(ScriptBuilderTest, AddObscuredInput) { m_builder->addBlock("test_print"); - auto block = std::make_shared("", "test_teststr"); - m_builder->addObscuredInput("STRING", block); + auto valueBlock = std::make_shared("", "test_teststr"); + m_builder->addObscuredInput("STRING", valueBlock); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_print"); + ASSERT_EQ(block->inputs().size(), 1); + ASSERT_EQ(block->inputAt(0)->name(), "STRING"); + m_builder->build(); testing::internal::CaptureStdout(); @@ -80,6 +112,12 @@ TEST_F(ScriptBuilderTest, AddNullObscuredInput) { m_builder->addBlock("test_print"); m_builder->addNullObscuredInput("STRING"); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_print"); + ASSERT_EQ(block->inputs().size(), 1); + ASSERT_EQ(block->inputAt(0)->name(), "STRING"); + m_builder->build(); testing::internal::CaptureStdout(); @@ -91,6 +129,12 @@ TEST_F(ScriptBuilderTest, AddDropdownInput) { m_builder->addBlock("test_print_dropdown"); m_builder->addDropdownInput("STRING", "hello"); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_print_dropdown"); + ASSERT_EQ(block->inputs().size(), 1); + ASSERT_EQ(block->inputAt(0)->name(), "STRING"); + m_builder->build(); testing::internal::CaptureStdout(); @@ -102,6 +146,13 @@ TEST_F(ScriptBuilderTest, AddDropdownField) { m_builder->addBlock("test_print_field"); m_builder->addDropdownField("STRING", "hello"); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_print_field"); + ASSERT_TRUE(block->inputs().empty()); + ASSERT_EQ(block->fields().size(), 1); + ASSERT_EQ(block->fieldAt(0)->name(), "STRING"); + m_builder->build(); testing::internal::CaptureStdout(); @@ -112,10 +163,18 @@ TEST_F(ScriptBuilderTest, AddDropdownField) TEST_F(ScriptBuilderTest, ReporterBlocks) { m_builder->addReporterBlock("test_teststr"); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_teststr"); m_builder->captureBlockReturnValue(); m_builder->addReporterBlock("test_input"); m_builder->addValueInput("INPUT", -93.4); + block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_input"); + ASSERT_EQ(block->inputs().size(), 1); + ASSERT_EQ(block->inputAt(0)->name(), "INPUT"); m_builder->captureBlockReturnValue(); m_builder->build(); From baa7933e0075badc3ff96e71b47a3df9d5ed32a5 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 10:43:52 +0100 Subject: [PATCH 02/18] ScriptBuilder: Set compile functions of blocks in currentBlock() --- include/scratchcpp/dev/test/scriptbuilder.h | 3 +- src/dev/test/scriptbuilder.cpp | 55 ++++++++++++++------- test/dev/test_api/scriptbuilder_test.cpp | 1 + 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/include/scratchcpp/dev/test/scriptbuilder.h b/include/scratchcpp/dev/test/scriptbuilder.h index 36c254ce..4a0c188a 100644 --- a/include/scratchcpp/dev/test/scriptbuilder.h +++ b/include/scratchcpp/dev/test/scriptbuilder.h @@ -44,7 +44,7 @@ class LIBSCRATCHCPP_EXPORT ScriptBuilder void addDropdownInput(const std::string &name, const std::string &selectedValue); void addDropdownField(const std::string &name, const std::string &selectedValue); - std::shared_ptr currentBlock() const; + std::shared_ptr currentBlock(); void build(); void run(); @@ -53,6 +53,7 @@ class LIBSCRATCHCPP_EXPORT ScriptBuilder private: void addBlock(std::shared_ptr block); + void build(std::shared_ptr target); spimpl::unique_impl_ptr impl; }; diff --git a/src/dev/test/scriptbuilder.cpp b/src/dev/test/scriptbuilder.cpp index b11889f0..3b9f16ef 100644 --- a/src/dev/test/scriptbuilder.cpp +++ b/src/dev/test/scriptbuilder.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -153,31 +153,26 @@ void ScriptBuilder::addDropdownField(const std::string &name, const std::string impl->blocks.back()->addField(field); } -/*! Returns the current block (can be used e. g. with a custom Compiler instance). */ -std::shared_ptr ScriptBuilder::currentBlock() const +/*! + * Returns the current block (can be used e. g. with a custom Compiler instance).\n + * The script is automatically built to set the compile function of the block. + * \note This method is not intended for building scripts, use build() for that. + */ +std::shared_ptr ScriptBuilder::currentBlock() { + if (!impl->lastBlock) + return nullptr; + + if (!impl->lastBlock->compileFunction()) + build(std::make_shared()); + return impl->lastBlock; } /*! Builds and compiles the script. */ void ScriptBuilder::build() { - if (impl->target->blocks().empty()) { - for (auto block : impl->blocks) - impl->target->addBlock(block); - - for (auto block : impl->inputBlocks) - impl->target->addBlock(block); - } - - std::vector> targets = impl->engine->targets(); - - if (std::find(targets.begin(), targets.end(), impl->target) == targets.end()) { - targets.push_back(impl->target); - impl->engine->setTargets({ impl->target }); - } - - impl->engine->compile(); + build(impl->target); } /*! Runs the built script. */ @@ -202,3 +197,25 @@ void ScriptBuilder::addBlock(std::shared_ptr block) impl->blocks.push_back(block); } + +void ScriptBuilder::build(std::shared_ptr target) +{ + impl->engine->clear(); + + if (target->blocks().empty()) { + for (auto block : impl->blocks) + target->addBlock(block); + + for (auto block : impl->inputBlocks) + target->addBlock(block); + } + + std::vector> targets = impl->engine->targets(); + + if (std::find(targets.begin(), targets.end(), target) == targets.end()) { + targets.push_back(target); + impl->engine->setTargets({ target }); + } + + impl->engine->compile(); +} diff --git a/test/dev/test_api/scriptbuilder_test.cpp b/test/dev/test_api/scriptbuilder_test.cpp index 414467b7..eaec3336 100644 --- a/test/dev/test_api/scriptbuilder_test.cpp +++ b/test/dev/test_api/scriptbuilder_test.cpp @@ -40,6 +40,7 @@ TEST_F(ScriptBuilderTest, AddBlock) auto block = m_builder->currentBlock(); ASSERT_TRUE(block); ASSERT_EQ(block->opcode(), "test_simple"); + ASSERT_TRUE(block->compileFunction()); m_builder->build(); From 02f80acc1c47a31271d8d40cac8acec4d07b1144 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 10:44:37 +0100 Subject: [PATCH 03/18] Implement event_whentouchingobject --- src/dev/blocks/eventblocks.cpp | 10 +++++++++ src/dev/blocks/eventblocks.h | 3 +++ test/dev/blocks/event_blocks_test.cpp | 30 ++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/dev/blocks/eventblocks.cpp b/src/dev/blocks/eventblocks.cpp index 07477984..807949b6 100644 --- a/src/dev/blocks/eventblocks.cpp +++ b/src/dev/blocks/eventblocks.cpp @@ -1,5 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 +#include +#include + #include "eventblocks.h" using namespace libscratchcpp; @@ -16,4 +19,11 @@ std::string libscratchcpp::EventBlocks::description() const void EventBlocks::registerBlocks(IEngine *engine) { + engine->addCompileFunction(this, "event_whentouchingobject", &compileWhenTouchingObject); +} + +CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler) +{ + compiler->engine()->addWhenTouchingObjectScript(compiler->block()); + return nullptr; } diff --git a/src/dev/blocks/eventblocks.h b/src/dev/blocks/eventblocks.h index c395c3de..8633cc46 100644 --- a/src/dev/blocks/eventblocks.h +++ b/src/dev/blocks/eventblocks.h @@ -14,6 +14,9 @@ class EventBlocks : public IExtension std::string description() const override; void registerBlocks(IEngine *engine) override; + + private: + static CompilerValue *compileWhenTouchingObject(Compiler *compiler); }; } // namespace libscratchcpp diff --git a/test/dev/blocks/event_blocks_test.cpp b/test/dev/blocks/event_blocks_test.cpp index ab8370a6..c1563d01 100644 --- a/test/dev/blocks/event_blocks_test.cpp +++ b/test/dev/blocks/event_blocks_test.cpp @@ -1,15 +1,43 @@ +#include +#include +#include +#include #include #include "../common.h" #include "dev/blocks/eventblocks.h" using namespace libscratchcpp; +using namespace libscratchcpp::test; class EventBlocksTest : public testing::Test { public: - void SetUp() override { m_extension = std::make_unique(); } + void SetUp() override + { + m_extension = std::make_unique(); + m_engine = m_project.engine().get(); + m_extension->registerBlocks(m_engine); + } std::unique_ptr m_extension; + Project m_project; + IEngine *m_engine = nullptr; EngineMock m_engineMock; }; + +// TODO: Add test for when touching object hat predicate + +TEST_F(EventBlocksTest, WhenTouchingObject) +{ + auto target = std::make_shared(); + ScriptBuilder builder(m_extension.get(), m_engine, target); + + builder.addBlock("event_whentouchingobject"); + builder.addDropdownInput("TOUCHINGOBJECTMENU", "Sprite1"); + auto block = builder.currentBlock(); + + Compiler compiler(&m_engineMock, target.get()); + EXPECT_CALL(m_engineMock, addWhenTouchingObjectScript(block)); + compiler.compile(block); +} From 6c288f8cac029ffdd1e0df7cc3d3f8884c07db54 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 11:11:56 +0100 Subject: [PATCH 04/18] Implement event_whenflagclicked --- src/dev/blocks/eventblocks.cpp | 7 +++++++ src/dev/blocks/eventblocks.h | 1 + test/dev/blocks/event_blocks_test.cpp | 13 +++++++++++++ 3 files changed, 21 insertions(+) diff --git a/src/dev/blocks/eventblocks.cpp b/src/dev/blocks/eventblocks.cpp index 807949b6..2feea715 100644 --- a/src/dev/blocks/eventblocks.cpp +++ b/src/dev/blocks/eventblocks.cpp @@ -20,6 +20,7 @@ std::string libscratchcpp::EventBlocks::description() const void EventBlocks::registerBlocks(IEngine *engine) { engine->addCompileFunction(this, "event_whentouchingobject", &compileWhenTouchingObject); + engine->addCompileFunction(this, "event_whenflagclicked", &compileWhenFlagClicked); } CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler) @@ -27,3 +28,9 @@ CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler) compiler->engine()->addWhenTouchingObjectScript(compiler->block()); return nullptr; } + +CompilerValue *EventBlocks::compileWhenFlagClicked(Compiler *compiler) +{ + compiler->engine()->addGreenFlagScript(compiler->block()); + return nullptr; +} diff --git a/src/dev/blocks/eventblocks.h b/src/dev/blocks/eventblocks.h index 8633cc46..4dfb36fa 100644 --- a/src/dev/blocks/eventblocks.h +++ b/src/dev/blocks/eventblocks.h @@ -17,6 +17,7 @@ class EventBlocks : public IExtension private: static CompilerValue *compileWhenTouchingObject(Compiler *compiler); + static CompilerValue *compileWhenFlagClicked(Compiler *compiler); }; } // namespace libscratchcpp diff --git a/test/dev/blocks/event_blocks_test.cpp b/test/dev/blocks/event_blocks_test.cpp index c1563d01..d64be6bc 100644 --- a/test/dev/blocks/event_blocks_test.cpp +++ b/test/dev/blocks/event_blocks_test.cpp @@ -41,3 +41,16 @@ TEST_F(EventBlocksTest, WhenTouchingObject) EXPECT_CALL(m_engineMock, addWhenTouchingObjectScript(block)); compiler.compile(block); } + +TEST_F(EventBlocksTest, WhenFlagClicked) +{ + auto target = std::make_shared(); + ScriptBuilder builder(m_extension.get(), m_engine, target); + + builder.addBlock("event_whenflagclicked"); + auto block = builder.currentBlock(); + + Compiler compiler(&m_engineMock, target.get()); + EXPECT_CALL(m_engineMock, addGreenFlagScript(block)); + compiler.compile(block); +} From 5ad63a495472f386130a18b3646c7925036c2f86 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 11:24:55 +0100 Subject: [PATCH 05/18] Implement event_whenthisspriteclicked --- src/dev/blocks/eventblocks.cpp | 7 +++++++ src/dev/blocks/eventblocks.h | 1 + test/dev/blocks/event_blocks_test.cpp | 13 +++++++++++++ 3 files changed, 21 insertions(+) diff --git a/src/dev/blocks/eventblocks.cpp b/src/dev/blocks/eventblocks.cpp index 2feea715..908cd751 100644 --- a/src/dev/blocks/eventblocks.cpp +++ b/src/dev/blocks/eventblocks.cpp @@ -21,6 +21,7 @@ void EventBlocks::registerBlocks(IEngine *engine) { engine->addCompileFunction(this, "event_whentouchingobject", &compileWhenTouchingObject); engine->addCompileFunction(this, "event_whenflagclicked", &compileWhenFlagClicked); + engine->addCompileFunction(this, "event_whenthisspriteclicked", &compileWhenThisSpriteClicked); } CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler) @@ -34,3 +35,9 @@ CompilerValue *EventBlocks::compileWhenFlagClicked(Compiler *compiler) compiler->engine()->addGreenFlagScript(compiler->block()); return nullptr; } + +CompilerValue *EventBlocks::compileWhenThisSpriteClicked(Compiler *compiler) +{ + compiler->engine()->addTargetClickScript(compiler->block()); + return nullptr; +} diff --git a/src/dev/blocks/eventblocks.h b/src/dev/blocks/eventblocks.h index 4dfb36fa..81e6191f 100644 --- a/src/dev/blocks/eventblocks.h +++ b/src/dev/blocks/eventblocks.h @@ -18,6 +18,7 @@ class EventBlocks : public IExtension private: static CompilerValue *compileWhenTouchingObject(Compiler *compiler); static CompilerValue *compileWhenFlagClicked(Compiler *compiler); + static CompilerValue *compileWhenThisSpriteClicked(Compiler *compiler); }; } // namespace libscratchcpp diff --git a/test/dev/blocks/event_blocks_test.cpp b/test/dev/blocks/event_blocks_test.cpp index d64be6bc..6280c356 100644 --- a/test/dev/blocks/event_blocks_test.cpp +++ b/test/dev/blocks/event_blocks_test.cpp @@ -54,3 +54,16 @@ TEST_F(EventBlocksTest, WhenFlagClicked) EXPECT_CALL(m_engineMock, addGreenFlagScript(block)); compiler.compile(block); } + +TEST_F(EventBlocksTest, WhenThisSpriteClicked) +{ + auto target = std::make_shared(); + ScriptBuilder builder(m_extension.get(), m_engine, target); + + builder.addBlock("event_whenthisspriteclicked"); + auto block = builder.currentBlock(); + + Compiler compiler(&m_engineMock, target.get()); + EXPECT_CALL(m_engineMock, addTargetClickScript(block)); + compiler.compile(block); +} From 06718d696b5711146bee494a2c42d04fafae078d Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 11:47:43 +0100 Subject: [PATCH 06/18] Implement event_whenstageclicked --- src/dev/blocks/eventblocks.cpp | 7 +++++++ src/dev/blocks/eventblocks.h | 1 + test/dev/blocks/event_blocks_test.cpp | 13 +++++++++++++ 3 files changed, 21 insertions(+) diff --git a/src/dev/blocks/eventblocks.cpp b/src/dev/blocks/eventblocks.cpp index 908cd751..0237e375 100644 --- a/src/dev/blocks/eventblocks.cpp +++ b/src/dev/blocks/eventblocks.cpp @@ -22,6 +22,7 @@ void EventBlocks::registerBlocks(IEngine *engine) engine->addCompileFunction(this, "event_whentouchingobject", &compileWhenTouchingObject); engine->addCompileFunction(this, "event_whenflagclicked", &compileWhenFlagClicked); engine->addCompileFunction(this, "event_whenthisspriteclicked", &compileWhenThisSpriteClicked); + engine->addCompileFunction(this, "event_whenstageclicked", &compileWhenStageClicked); } CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler) @@ -41,3 +42,9 @@ CompilerValue *EventBlocks::compileWhenThisSpriteClicked(Compiler *compiler) compiler->engine()->addTargetClickScript(compiler->block()); return nullptr; } + +CompilerValue *EventBlocks::compileWhenStageClicked(Compiler *compiler) +{ + compiler->engine()->addTargetClickScript(compiler->block()); + return nullptr; +} diff --git a/src/dev/blocks/eventblocks.h b/src/dev/blocks/eventblocks.h index 81e6191f..46f3a0dc 100644 --- a/src/dev/blocks/eventblocks.h +++ b/src/dev/blocks/eventblocks.h @@ -19,6 +19,7 @@ class EventBlocks : public IExtension static CompilerValue *compileWhenTouchingObject(Compiler *compiler); static CompilerValue *compileWhenFlagClicked(Compiler *compiler); static CompilerValue *compileWhenThisSpriteClicked(Compiler *compiler); + static CompilerValue *compileWhenStageClicked(Compiler *compiler); }; } // namespace libscratchcpp diff --git a/test/dev/blocks/event_blocks_test.cpp b/test/dev/blocks/event_blocks_test.cpp index 6280c356..f3459345 100644 --- a/test/dev/blocks/event_blocks_test.cpp +++ b/test/dev/blocks/event_blocks_test.cpp @@ -67,3 +67,16 @@ TEST_F(EventBlocksTest, WhenThisSpriteClicked) EXPECT_CALL(m_engineMock, addTargetClickScript(block)); compiler.compile(block); } + +TEST_F(EventBlocksTest, WhenStageClicked) +{ + auto target = std::make_shared(); + ScriptBuilder builder(m_extension.get(), m_engine, target); + + builder.addBlock("event_whenstageclicked"); + auto block = builder.currentBlock(); + + Compiler compiler(&m_engineMock, target.get()); + EXPECT_CALL(m_engineMock, addTargetClickScript(block)); + compiler.compile(block); +} From 6a63262090d98f7d351c4ce2f2d511afd7f4c045 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 11:53:42 +0100 Subject: [PATCH 07/18] ScriptBuilder: Use last block in all input/field methods --- src/dev/test/scriptbuilder.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/dev/test/scriptbuilder.cpp b/src/dev/test/scriptbuilder.cpp index 3b9f16ef..a49751b1 100644 --- a/src/dev/test/scriptbuilder.cpp +++ b/src/dev/test/scriptbuilder.cpp @@ -121,7 +121,7 @@ void ScriptBuilder::addNullObscuredInput(const std::string &name) block->setCompileFunction([](Compiler *compiler) -> CompilerValue * { return compiler->addConstValue(Value()); }); input->setValueBlock(block); impl->inputBlocks.push_back(block); - impl->blocks.back()->addInput(input); + impl->lastBlock->addInput(input); } /*! Adds a dropdown menu input to the current block. */ @@ -130,11 +130,10 @@ void ScriptBuilder::addDropdownInput(const std::string &name, const std::string if (!impl->lastBlock) return; - auto block = impl->blocks.back(); auto input = std::make_shared(name, Input::Type::Shadow); - block->addInput(input); + impl->lastBlock->addInput(input); - auto menu = std::make_shared(std::to_string(impl->blockId++), block->opcode() + "_menu"); + auto menu = std::make_shared(std::to_string(impl->blockId++), impl->lastBlock->opcode() + "_menu"); menu->setShadow(true); impl->inputBlocks.push_back(menu); input->setValueBlock(menu); @@ -150,7 +149,7 @@ void ScriptBuilder::addDropdownField(const std::string &name, const std::string return; auto field = std::make_shared(name, selectedValue); - impl->blocks.back()->addField(field); + impl->lastBlock->addField(field); } /*! From 1f9dd99a1918765e534fc09abac89b7d7f8b9709 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:16:03 +0100 Subject: [PATCH 08/18] Engine: Add missing stage null checks --- src/engine/internal/engine.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/engine/internal/engine.cpp b/src/engine/internal/engine.cpp index 748797ce..1be628aa 100644 --- a/src/engine/internal/engine.cpp +++ b/src/engine/internal/engine.cpp @@ -1526,10 +1526,12 @@ std::shared_ptr Engine::getVariable(const std::string &id, Target *tar int index; // Check stage - index = stage->findVariableById(id); + if (stage) { + index = stage->findVariableById(id); - if (index != -1) - return stage->variableAt(index); + if (index != -1) + return stage->variableAt(index); + } // Check currently compiled target if (target != stage) { @@ -1562,10 +1564,12 @@ std::shared_ptr Engine::getList(const std::string &id, Target *target) int index; // Check stage - index = stage->findListById(id); + if (stage) { + index = stage->findListById(id); - if (index != -1) - return stage->listAt(index); + if (index != -1) + return stage->listAt(index); + } // Check currently compiled target if (target != stage) { From 258d02818f0ae09be694e48626f0784f2150be4b Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:16:27 +0100 Subject: [PATCH 09/18] ScriptBuilder: Add addEntityField() method --- include/scratchcpp/dev/test/scriptbuilder.h | 3 +++ src/dev/test/scriptbuilder.cpp | 13 +++++++++++-- test/dev/test_api/scriptbuilder_test.cpp | 17 +++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/scratchcpp/dev/test/scriptbuilder.h b/include/scratchcpp/dev/test/scriptbuilder.h index 4a0c188a..1cf5142b 100644 --- a/include/scratchcpp/dev/test/scriptbuilder.h +++ b/include/scratchcpp/dev/test/scriptbuilder.h @@ -13,6 +13,7 @@ namespace libscratchcpp class IExtension; class IEngine; class Target; +class Entity; class List; } // namespace libscratchcpp @@ -44,6 +45,8 @@ class LIBSCRATCHCPP_EXPORT ScriptBuilder void addDropdownInput(const std::string &name, const std::string &selectedValue); void addDropdownField(const std::string &name, const std::string &selectedValue); + void addEntityField(const std::string &name, std::shared_ptr entity); + std::shared_ptr currentBlock(); void build(); diff --git a/src/dev/test/scriptbuilder.cpp b/src/dev/test/scriptbuilder.cpp index a49751b1..1bdcd9f0 100644 --- a/src/dev/test/scriptbuilder.cpp +++ b/src/dev/test/scriptbuilder.cpp @@ -152,6 +152,17 @@ void ScriptBuilder::addDropdownField(const std::string &name, const std::string impl->lastBlock->addField(field); } +/*! Adds a field pointing to an entity (variable, list, broadcast, etc.) */ +void ScriptBuilder::addEntityField(const std::string &name, std::shared_ptr entity) +{ + if (!impl->lastBlock) + return; + + entity->setId(std::to_string(impl->blockId++)); + auto field = std::make_shared(name, Value(), entity); + impl->lastBlock->addField(field); +} + /*! * Returns the current block (can be used e. g. with a custom Compiler instance).\n * The script is automatically built to set the compile function of the block. @@ -199,8 +210,6 @@ void ScriptBuilder::addBlock(std::shared_ptr block) void ScriptBuilder::build(std::shared_ptr target) { - impl->engine->clear(); - if (target->blocks().empty()) { for (auto block : impl->blocks) target->addBlock(block); diff --git a/test/dev/test_api/scriptbuilder_test.cpp b/test/dev/test_api/scriptbuilder_test.cpp index eaec3336..45fafd4e 100644 --- a/test/dev/test_api/scriptbuilder_test.cpp +++ b/test/dev/test_api/scriptbuilder_test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../../common.h" #include "testextension.h" @@ -161,6 +162,22 @@ TEST_F(ScriptBuilderTest, AddDropdownField) ASSERT_EQ(testing::internal::GetCapturedStdout(), "hello\n"); } +TEST_F(ScriptBuilderTest, AddEntityField) +{ + auto broadcast = std::make_shared("", ""); + m_engine->setBroadcasts({ broadcast }); + + m_builder->addBlock("test_print_field"); + m_builder->addEntityField("STRING", broadcast); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_print_field"); + ASSERT_TRUE(block->inputs().empty()); + ASSERT_EQ(block->fields().size(), 1); + ASSERT_EQ(block->fieldAt(0)->name(), "STRING"); + ASSERT_EQ(block->fieldAt(0)->valuePtr(), broadcast); +} + TEST_F(ScriptBuilderTest, ReporterBlocks) { m_builder->addReporterBlock("test_teststr"); From 1e933d8999fc2cad6fbf81e32e520b59ef8f862d Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:26:10 +0100 Subject: [PATCH 10/18] Implement event_whenbroadcastreceived --- src/dev/blocks/eventblocks.cpp | 17 +++++++++++++++++ src/dev/blocks/eventblocks.h | 1 + test/dev/blocks/event_blocks_test.cpp | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/src/dev/blocks/eventblocks.cpp b/src/dev/blocks/eventblocks.cpp index 0237e375..71566730 100644 --- a/src/dev/blocks/eventblocks.cpp +++ b/src/dev/blocks/eventblocks.cpp @@ -2,6 +2,9 @@ #include #include +#include +#include +#include #include "eventblocks.h" @@ -23,6 +26,7 @@ void EventBlocks::registerBlocks(IEngine *engine) engine->addCompileFunction(this, "event_whenflagclicked", &compileWhenFlagClicked); engine->addCompileFunction(this, "event_whenthisspriteclicked", &compileWhenThisSpriteClicked); engine->addCompileFunction(this, "event_whenstageclicked", &compileWhenStageClicked); + engine->addCompileFunction(this, "event_whenbroadcastreceived", &compileWhenBroadcastReceived); } CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler) @@ -48,3 +52,16 @@ CompilerValue *EventBlocks::compileWhenStageClicked(Compiler *compiler) compiler->engine()->addTargetClickScript(compiler->block()); return nullptr; } + +CompilerValue *EventBlocks::compileWhenBroadcastReceived(Compiler *compiler) +{ + auto block = compiler->block(); + Field *field = compiler->field("BROADCAST_OPTION"); + + if (field) { + auto broadcast = std::static_pointer_cast(field->valuePtr()); + compiler->engine()->addBroadcastScript(block, field, broadcast.get()); + } + + return nullptr; +} diff --git a/src/dev/blocks/eventblocks.h b/src/dev/blocks/eventblocks.h index 46f3a0dc..113d7278 100644 --- a/src/dev/blocks/eventblocks.h +++ b/src/dev/blocks/eventblocks.h @@ -20,6 +20,7 @@ class EventBlocks : public IExtension static CompilerValue *compileWhenFlagClicked(Compiler *compiler); static CompilerValue *compileWhenThisSpriteClicked(Compiler *compiler); static CompilerValue *compileWhenStageClicked(Compiler *compiler); + static CompilerValue *compileWhenBroadcastReceived(Compiler *compiler); }; } // namespace libscratchcpp diff --git a/test/dev/blocks/event_blocks_test.cpp b/test/dev/blocks/event_blocks_test.cpp index f3459345..88c62aa8 100644 --- a/test/dev/blocks/event_blocks_test.cpp +++ b/test/dev/blocks/event_blocks_test.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include "../common.h" @@ -80,3 +82,20 @@ TEST_F(EventBlocksTest, WhenStageClicked) EXPECT_CALL(m_engineMock, addTargetClickScript(block)); compiler.compile(block); } + +TEST_F(EventBlocksTest, WhenBroadcastReceived) +{ + auto broadcast = std::make_shared("", ""); + m_engine->setBroadcasts({ broadcast }); + + auto target = std::make_shared(); + ScriptBuilder builder(m_extension.get(), m_engine, target); + + builder.addBlock("event_whenbroadcastreceived"); + builder.addEntityField("BROADCAST_OPTION", broadcast); + auto block = builder.currentBlock(); + + Compiler compiler(&m_engineMock, target.get()); + EXPECT_CALL(m_engineMock, addBroadcastScript(block, block->fieldAt(0).get(), broadcast.get())); + compiler.compile(block); +} From 715a95e2b8c4afdaa72523fa2f3890881c84a6da Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 14:21:42 +0100 Subject: [PATCH 11/18] Implement event_whenbackropswitchesto --- src/dev/blocks/eventblocks.cpp | 12 ++++++++++++ src/dev/blocks/eventblocks.h | 1 + test/dev/blocks/event_blocks_test.cpp | 14 ++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/dev/blocks/eventblocks.cpp b/src/dev/blocks/eventblocks.cpp index 71566730..f3ca6136 100644 --- a/src/dev/blocks/eventblocks.cpp +++ b/src/dev/blocks/eventblocks.cpp @@ -27,6 +27,7 @@ void EventBlocks::registerBlocks(IEngine *engine) engine->addCompileFunction(this, "event_whenthisspriteclicked", &compileWhenThisSpriteClicked); engine->addCompileFunction(this, "event_whenstageclicked", &compileWhenStageClicked); engine->addCompileFunction(this, "event_whenbroadcastreceived", &compileWhenBroadcastReceived); + engine->addCompileFunction(this, "event_whenbackdropswitchesto", &compileWhenBackdropSwitchesTo); } CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler) @@ -65,3 +66,14 @@ CompilerValue *EventBlocks::compileWhenBroadcastReceived(Compiler *compiler) return nullptr; } + +CompilerValue *EventBlocks::compileWhenBackdropSwitchesTo(Compiler *compiler) +{ + auto block = compiler->block(); + Field *field = compiler->field("BACKDROP"); + + if (field) + compiler->engine()->addBackdropChangeScript(block, field); + + return nullptr; +} diff --git a/src/dev/blocks/eventblocks.h b/src/dev/blocks/eventblocks.h index 113d7278..47fc0b7b 100644 --- a/src/dev/blocks/eventblocks.h +++ b/src/dev/blocks/eventblocks.h @@ -21,6 +21,7 @@ class EventBlocks : public IExtension static CompilerValue *compileWhenThisSpriteClicked(Compiler *compiler); static CompilerValue *compileWhenStageClicked(Compiler *compiler); static CompilerValue *compileWhenBroadcastReceived(Compiler *compiler); + static CompilerValue *compileWhenBackdropSwitchesTo(Compiler *compiler); }; } // namespace libscratchcpp diff --git a/test/dev/blocks/event_blocks_test.cpp b/test/dev/blocks/event_blocks_test.cpp index 88c62aa8..8d19168e 100644 --- a/test/dev/blocks/event_blocks_test.cpp +++ b/test/dev/blocks/event_blocks_test.cpp @@ -99,3 +99,17 @@ TEST_F(EventBlocksTest, WhenBroadcastReceived) EXPECT_CALL(m_engineMock, addBroadcastScript(block, block->fieldAt(0).get(), broadcast.get())); compiler.compile(block); } + +TEST_F(EventBlocksTest, WhenBackdropSwitchesTo) +{ + auto target = std::make_shared(); + ScriptBuilder builder(m_extension.get(), m_engine, target); + + builder.addBlock("event_whenbackdropswitchesto"); + builder.addDropdownField("BACKDROP", "backdrop2"); + auto block = builder.currentBlock(); + + Compiler compiler(&m_engineMock, target.get()); + EXPECT_CALL(m_engineMock, addBackdropChangeScript(block, block->fieldAt(0).get())); + compiler.compile(block); +} From c8dd2f3590993d412f1ead199dc472c32d0f07e3 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 14:46:49 +0100 Subject: [PATCH 12/18] Implement event_whengreaterthan --- src/dev/blocks/eventblocks.cpp | 7 +++++++ src/dev/blocks/eventblocks.h | 1 + test/dev/blocks/event_blocks_test.cpp | 17 +++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/dev/blocks/eventblocks.cpp b/src/dev/blocks/eventblocks.cpp index f3ca6136..097cf9c4 100644 --- a/src/dev/blocks/eventblocks.cpp +++ b/src/dev/blocks/eventblocks.cpp @@ -28,6 +28,7 @@ void EventBlocks::registerBlocks(IEngine *engine) engine->addCompileFunction(this, "event_whenstageclicked", &compileWhenStageClicked); engine->addCompileFunction(this, "event_whenbroadcastreceived", &compileWhenBroadcastReceived); engine->addCompileFunction(this, "event_whenbackdropswitchesto", &compileWhenBackdropSwitchesTo); + engine->addCompileFunction(this, "event_whengreaterthan", &compileWhenGreaterThan); } CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler) @@ -77,3 +78,9 @@ CompilerValue *EventBlocks::compileWhenBackdropSwitchesTo(Compiler *compiler) return nullptr; } + +CompilerValue *EventBlocks::compileWhenGreaterThan(Compiler *compiler) +{ + compiler->engine()->addWhenGreaterThanScript(compiler->block()); + return nullptr; +} diff --git a/src/dev/blocks/eventblocks.h b/src/dev/blocks/eventblocks.h index 47fc0b7b..1c9d51b2 100644 --- a/src/dev/blocks/eventblocks.h +++ b/src/dev/blocks/eventblocks.h @@ -22,6 +22,7 @@ class EventBlocks : public IExtension static CompilerValue *compileWhenStageClicked(Compiler *compiler); static CompilerValue *compileWhenBroadcastReceived(Compiler *compiler); static CompilerValue *compileWhenBackdropSwitchesTo(Compiler *compiler); + static CompilerValue *compileWhenGreaterThan(Compiler *compiler); }; } // namespace libscratchcpp diff --git a/test/dev/blocks/event_blocks_test.cpp b/test/dev/blocks/event_blocks_test.cpp index 8d19168e..0e3d9236 100644 --- a/test/dev/blocks/event_blocks_test.cpp +++ b/test/dev/blocks/event_blocks_test.cpp @@ -113,3 +113,20 @@ TEST_F(EventBlocksTest, WhenBackdropSwitchesTo) EXPECT_CALL(m_engineMock, addBackdropChangeScript(block, block->fieldAt(0).get())); compiler.compile(block); } + +// TODO: Add test for when greater than hat predicate + +TEST_F(EventBlocksTest, WhenGreaterThan) +{ + auto target = std::make_shared(); + ScriptBuilder builder(m_extension.get(), m_engine, target); + + builder.addBlock("event_whengreaterthan"); + builder.addDropdownField("WHENGREATERTHANMENU", "LOUDNESS"); + builder.addValueInput("VALUE", 8.9); + auto block = builder.currentBlock(); + + Compiler compiler(&m_engineMock, target.get()); + EXPECT_CALL(m_engineMock, addWhenGreaterThanScript(block)); + compiler.compile(block); +} From 4f3d6dc5dc11db906c364c5147ca4e2d17bc7c2e Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 16:01:07 +0100 Subject: [PATCH 13/18] ScriptBuilder: Add addEntityInput() method --- include/scratchcpp/dev/test/scriptbuilder.h | 5 ++--- src/dev/test/scriptbuilder.cpp | 15 +++++++++++++ test/dev/test_api/scriptbuilder_test.cpp | 24 +++++++++++++++++---- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/include/scratchcpp/dev/test/scriptbuilder.h b/include/scratchcpp/dev/test/scriptbuilder.h index 1cf5142b..65a3383c 100644 --- a/include/scratchcpp/dev/test/scriptbuilder.h +++ b/include/scratchcpp/dev/test/scriptbuilder.h @@ -4,8 +4,7 @@ #include -#include "../../global.h" -#include "../../spimpl.h" +#include "../../inputvalue.h" namespace libscratchcpp { @@ -13,7 +12,6 @@ namespace libscratchcpp class IExtension; class IEngine; class Target; -class Entity; class List; } // namespace libscratchcpp @@ -45,6 +43,7 @@ class LIBSCRATCHCPP_EXPORT ScriptBuilder void addDropdownInput(const std::string &name, const std::string &selectedValue); void addDropdownField(const std::string &name, const std::string &selectedValue); + void addEntityInput(const std::string &name, const std::string &entityName, InputValue::Type entityType, std::shared_ptr entity); void addEntityField(const std::string &name, std::shared_ptr entity); std::shared_ptr currentBlock(); diff --git a/src/dev/test/scriptbuilder.cpp b/src/dev/test/scriptbuilder.cpp index 1bdcd9f0..97d3aac2 100644 --- a/src/dev/test/scriptbuilder.cpp +++ b/src/dev/test/scriptbuilder.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,20 @@ void ScriptBuilder::addDropdownField(const std::string &name, const std::string impl->lastBlock->addField(field); } +/*! Adds an input pointing to an entity (variable, list, broadcast, etc.) */ +void ScriptBuilder::addEntityInput(const std::string &name, const std::string &entityName, InputValue::Type entityType, std::shared_ptr entity) +{ + if (!impl->lastBlock) + return; + + entity->setId(std::to_string(impl->blockId++)); + auto input = std::make_shared(name, Input::Type::Shadow); + input->setPrimaryValue(entityName); + input->primaryValue()->setValuePtr(entity); + input->primaryValue()->setType(entityType); + impl->lastBlock->addInput(input); +} + /*! Adds a field pointing to an entity (variable, list, broadcast, etc.) */ void ScriptBuilder::addEntityField(const std::string &name, std::shared_ptr entity) { diff --git a/test/dev/test_api/scriptbuilder_test.cpp b/test/dev/test_api/scriptbuilder_test.cpp index 45fafd4e..a2d4eb0e 100644 --- a/test/dev/test_api/scriptbuilder_test.cpp +++ b/test/dev/test_api/scriptbuilder_test.cpp @@ -162,19 +162,35 @@ TEST_F(ScriptBuilderTest, AddDropdownField) ASSERT_EQ(testing::internal::GetCapturedStdout(), "hello\n"); } +TEST_F(ScriptBuilderTest, AddEntityInput) +{ + auto broadcast = std::make_shared("", ""); + m_engine->setBroadcasts({ broadcast }); + + m_builder->addBlock("test_simple"); + m_builder->addEntityInput("BROADCAST", "test", InputValue::Type::Broadcast, broadcast); + auto block = m_builder->currentBlock(); + ASSERT_TRUE(block); + ASSERT_EQ(block->opcode(), "test_simple"); + ASSERT_EQ(block->inputs().size(), 1); + ASSERT_EQ(block->inputAt(0)->name(), "BROADCAST"); + ASSERT_EQ(block->inputAt(0)->primaryValue()->valuePtr(), broadcast); + ASSERT_EQ(block->inputAt(0)->primaryValue()->type(), InputValue::Type::Broadcast); +} + TEST_F(ScriptBuilderTest, AddEntityField) { auto broadcast = std::make_shared("", ""); m_engine->setBroadcasts({ broadcast }); - m_builder->addBlock("test_print_field"); - m_builder->addEntityField("STRING", broadcast); + m_builder->addBlock("test_simple"); + m_builder->addEntityField("BROADCAST", broadcast); auto block = m_builder->currentBlock(); ASSERT_TRUE(block); - ASSERT_EQ(block->opcode(), "test_print_field"); + ASSERT_EQ(block->opcode(), "test_simple"); ASSERT_TRUE(block->inputs().empty()); ASSERT_EQ(block->fields().size(), 1); - ASSERT_EQ(block->fieldAt(0)->name(), "STRING"); + ASSERT_EQ(block->fieldAt(0)->name(), "BROADCAST"); ASSERT_EQ(block->fieldAt(0)->valuePtr(), broadcast); } From 4fb010b0ee671af4c7c6338467f0635b819cdf60 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 10 Dec 2024 23:33:06 +0100 Subject: [PATCH 14/18] Use Thread instead of Target in ExecutionContext constructor --- include/scratchcpp/dev/executablecode.h | 4 +- include/scratchcpp/dev/executioncontext.h | 5 +- src/dev/engine/executioncontext.cpp | 11 +- src/dev/engine/executioncontext_p.cpp | 4 +- src/dev/engine/executioncontext_p.h | 5 +- .../internal/llvm/llvmexecutablecode.cpp | 7 +- .../engine/internal/llvm/llvmexecutablecode.h | 2 +- .../internal/llvm/llvmexecutioncontext.cpp | 4 +- .../internal/llvm/llvmexecutioncontext.h | 2 +- src/engine/thread.cpp | 8 +- .../executioncontext_test.cpp | 11 +- test/dev/llvm/llvmcodebuilder_test.cpp | 181 ++++++++++++++---- test/dev/llvm/llvmexecutablecode_test.cpp | 130 +++++++------ test/dev/llvm/llvmexecutioncontext_test.cpp | 8 +- test/mocks/executablecodemock.h | 2 +- test/thread/thread_test.cpp | 8 +- 16 files changed, 266 insertions(+), 126 deletions(-) diff --git a/include/scratchcpp/dev/executablecode.h b/include/scratchcpp/dev/executablecode.h index ba5d03e4..8136e40e 100644 --- a/include/scratchcpp/dev/executablecode.h +++ b/include/scratchcpp/dev/executablecode.h @@ -10,7 +10,7 @@ namespace libscratchcpp { class ExecutionContext; -class Target; +class Thread; /*! \brief The ExecutableCode class represents the code of a compiled Scratch script. */ class LIBSCRATCHCPP_EXPORT ExecutableCode @@ -31,7 +31,7 @@ class LIBSCRATCHCPP_EXPORT ExecutableCode virtual bool isFinished(ExecutionContext *context) const = 0; /*! Creates an execution context for the given Target. */ - virtual std::shared_ptr createExecutionContext(Target *target) const = 0; + virtual std::shared_ptr createExecutionContext(Thread *thread) const = 0; }; } // namespace libscratchcpp diff --git a/include/scratchcpp/dev/executioncontext.h b/include/scratchcpp/dev/executioncontext.h index 4651d079..d56f703f 100644 --- a/include/scratchcpp/dev/executioncontext.h +++ b/include/scratchcpp/dev/executioncontext.h @@ -8,6 +8,7 @@ namespace libscratchcpp { +class Thread; class Target; class Promise; class ExecutionContextPrivate; @@ -16,11 +17,11 @@ class ExecutionContextPrivate; class LIBSCRATCHCPP_EXPORT ExecutionContext { public: - ExecutionContext(Target *target); + ExecutionContext(Thread *thread); ExecutionContext(const ExecutionContext &) = delete; virtual ~ExecutionContext() { } - Target *target() const; + Thread *thread() const; std::shared_ptr promise() const; void setPromise(std::shared_ptr promise); diff --git a/src/dev/engine/executioncontext.cpp b/src/dev/engine/executioncontext.cpp index 81f8cb06..643335c2 100644 --- a/src/dev/engine/executioncontext.cpp +++ b/src/dev/engine/executioncontext.cpp @@ -1,21 +1,22 @@ // SPDX-License-Identifier: Apache-2.0 #include +#include #include "executioncontext_p.h" using namespace libscratchcpp; /*! Constructs ExecutionContext. */ -ExecutionContext::ExecutionContext(Target *target) : - impl(spimpl::make_unique_impl(target)) +ExecutionContext::ExecutionContext(Thread *thread) : + impl(spimpl::make_unique_impl(thread)) { } -/*! Returns the Target of this context. */ -Target *ExecutionContext::target() const +/*! Returns the thread of this context. */ +Thread *ExecutionContext::thread() const { - return impl->target; + return impl->thread; } /*! Returns the script promise. */ diff --git a/src/dev/engine/executioncontext_p.cpp b/src/dev/engine/executioncontext_p.cpp index f2efa1e1..bb42caac 100644 --- a/src/dev/engine/executioncontext_p.cpp +++ b/src/dev/engine/executioncontext_p.cpp @@ -4,7 +4,7 @@ using namespace libscratchcpp; -ExecutionContextPrivate::ExecutionContextPrivate(Target *target) : - target(target) +ExecutionContextPrivate::ExecutionContextPrivate(Thread *thread) : + thread(thread) { } diff --git a/src/dev/engine/executioncontext_p.h b/src/dev/engine/executioncontext_p.h index 19a22e96..19322c13 100644 --- a/src/dev/engine/executioncontext_p.h +++ b/src/dev/engine/executioncontext_p.h @@ -7,14 +7,15 @@ namespace libscratchcpp { +class Thread; class Target; class Promise; struct ExecutionContextPrivate { - ExecutionContextPrivate(Target *target); + ExecutionContextPrivate(Thread *thread); - Target *target = nullptr; + Thread *thread = nullptr; std::shared_ptr promise; }; diff --git a/src/dev/engine/internal/llvm/llvmexecutablecode.cpp b/src/dev/engine/internal/llvm/llvmexecutablecode.cpp index 944e5d44..20aa9dfc 100644 --- a/src/dev/engine/internal/llvm/llvmexecutablecode.cpp +++ b/src/dev/engine/internal/llvm/llvmexecutablecode.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ void LLVMExecutableCode::run(ExecutionContext *context) ctx->setFinished(done); } else { - Target *target = ctx->target(); + Target *target = ctx->thread()->target(); void *handle = m_mainFunction(context, target, target->variableData(), target->listData()); if (!handle) @@ -95,9 +96,9 @@ bool LLVMExecutableCode::isFinished(ExecutionContext *context) const return getContext(context)->finished(); } -std::shared_ptr LLVMExecutableCode::createExecutionContext(Target *target) const +std::shared_ptr LLVMExecutableCode::createExecutionContext(Thread *thread) const { - return std::make_shared(target); + return std::make_shared(thread); } uint64_t LLVMExecutableCode::lookupFunction(const std::string &name) diff --git a/src/dev/engine/internal/llvm/llvmexecutablecode.h b/src/dev/engine/internal/llvm/llvmexecutablecode.h index ecdc09c3..6d293b3d 100644 --- a/src/dev/engine/internal/llvm/llvmexecutablecode.h +++ b/src/dev/engine/internal/llvm/llvmexecutablecode.h @@ -25,7 +25,7 @@ class LLVMExecutableCode : public ExecutableCode bool isFinished(ExecutionContext *context) const override; - std::shared_ptr createExecutionContext(Target *target) const override; + std::shared_ptr createExecutionContext(Thread *thread) const override; private: uint64_t lookupFunction(const std::string &name); diff --git a/src/dev/engine/internal/llvm/llvmexecutioncontext.cpp b/src/dev/engine/internal/llvm/llvmexecutioncontext.cpp index 5934a90a..97696b34 100644 --- a/src/dev/engine/internal/llvm/llvmexecutioncontext.cpp +++ b/src/dev/engine/internal/llvm/llvmexecutioncontext.cpp @@ -4,8 +4,8 @@ using namespace libscratchcpp; -LLVMExecutionContext::LLVMExecutionContext(Target *target) : - ExecutionContext(target) +LLVMExecutionContext::LLVMExecutionContext(Thread *thread) : + ExecutionContext(thread) { } diff --git a/src/dev/engine/internal/llvm/llvmexecutioncontext.h b/src/dev/engine/internal/llvm/llvmexecutioncontext.h index c6357819..c3c952fc 100644 --- a/src/dev/engine/internal/llvm/llvmexecutioncontext.h +++ b/src/dev/engine/internal/llvm/llvmexecutioncontext.h @@ -10,7 +10,7 @@ namespace libscratchcpp class LLVMExecutionContext : public ExecutionContext { public: - LLVMExecutionContext(Target *target); + LLVMExecutionContext(Thread *thread); void *coroutineHandle() const; void setCoroutineHandle(void *newCoroutineHandle); diff --git a/src/engine/thread.cpp b/src/engine/thread.cpp index 3c1cbfc5..bf34cdab 100644 --- a/src/engine/thread.cpp +++ b/src/engine/thread.cpp @@ -18,8 +18,12 @@ Thread::Thread(Target *target, IEngine *engine, Script *script) : { impl->vm = std::make_unique(target, engine, script, this); #ifdef USE_LLVM - impl->code = impl->script->code(); - impl->executionContext = impl->code->createExecutionContext(target); + if (impl->script) { + impl->code = impl->script->code(); + + if (impl->code) + impl->executionContext = impl->code->createExecutionContext(this); + } #endif } diff --git a/test/dev/executioncontext/executioncontext_test.cpp b/test/dev/executioncontext/executioncontext_test.cpp index d1145373..7f4eac6b 100644 --- a/test/dev/executioncontext/executioncontext_test.cpp +++ b/test/dev/executioncontext/executioncontext_test.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include "../../common.h" @@ -8,15 +8,14 @@ using namespace libscratchcpp; TEST(ExecutionContextTest, Constructor) { - Target target; - ExecutionContext ctx(&target); - ASSERT_EQ(ctx.target(), &target); + Thread thread(nullptr, nullptr, nullptr); + ExecutionContext ctx(&thread); + ASSERT_EQ(ctx.thread(), &thread); } TEST(ExecutionContextTest, Promise) { - Target target; - ExecutionContext ctx(&target); + ExecutionContext ctx(nullptr); ASSERT_EQ(ctx.promise(), nullptr); auto promise = std::make_shared(); diff --git a/test/dev/llvm/llvmcodebuilder_test.cpp b/test/dev/llvm/llvmcodebuilder_test.cpp index e624fb9c..a51729d6 100644 --- a/test/dev/llvm/llvmcodebuilder_test.cpp +++ b/test/dev/llvm/llvmcodebuilder_test.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include @@ -243,7 +245,10 @@ class LLVMCodeBuilderTest : public testing::Test std::string expected = str + str; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); @@ -269,7 +274,10 @@ class LLVMCodeBuilderTest : public testing::Test std::string expected = str + str; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); @@ -296,7 +304,10 @@ class LLVMCodeBuilderTest : public testing::Test std::string expected = str + str; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); @@ -342,7 +353,10 @@ TEST_F(LLVMCodeBuilderTest, FunctionCalls) { v, v1, v2 }); m_builder->addTargetFunctionCall("test_function_1_arg", Compiler::StaticType::Void, { Compiler::StaticType::String }, { v }); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); std::stringstream s; s << ctx.get(); @@ -393,7 +407,10 @@ TEST_F(LLVMCodeBuilderTest, ConstCasting) m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String }, { v }); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); static const std::string expected = "5.2\n" @@ -479,7 +496,10 @@ TEST_F(LLVMCodeBuilderTest, RawValueCasting) m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String }, { v }); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); static const std::string expected = "5.2\n" @@ -1384,7 +1404,11 @@ TEST_F(LLVMCodeBuilderTest, WriteVariable) m_builder->createVariableWrite(localVar3.get(), v); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_EQ(globalVar1->value(), 5); @@ -1463,7 +1487,11 @@ TEST_F(LLVMCodeBuilderTest, Select) auto code = m_builder->finalize(); testing::internal::CaptureStdout(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); } @@ -1519,7 +1547,11 @@ TEST_F(LLVMCodeBuilderTest, ReadVariable) expected += localVar3->value().toString() + '\n'; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -1587,7 +1619,11 @@ TEST_F(LLVMCodeBuilderTest, ClearList) m_builder->createListClear(localList2.get()); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_TRUE(globalList1->empty()); @@ -1634,7 +1670,11 @@ TEST_F(LLVMCodeBuilderTest, RemoveFromList) m_builder->createListRemove(localList.get(), v); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_EQ(globalList->toString(), "13"); @@ -1690,7 +1730,11 @@ TEST_F(LLVMCodeBuilderTest, AppendToList) m_builder->createListAppend(localList.get(), v); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_EQ(globalList->toString(), "1 2 3 1 test"); @@ -1752,7 +1796,11 @@ TEST_F(LLVMCodeBuilderTest, InsertToList) m_builder->createListInsert(localList.get(), v1, v2); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_EQ(globalList->toString(), "1 2 1 test 3"); @@ -1808,7 +1856,11 @@ TEST_F(LLVMCodeBuilderTest, ListReplace) m_builder->createListReplace(localList.get(), v1, v2); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_EQ(globalList->toString(), "1 test 1"); @@ -1854,7 +1906,11 @@ TEST_F(LLVMCodeBuilderTest, GetListContents) "Lorem ipsum dolor sit\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -1923,7 +1979,11 @@ TEST_F(LLVMCodeBuilderTest, GetListItem) "sit\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -1968,7 +2028,11 @@ TEST_F(LLVMCodeBuilderTest, GetListSize) "4\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -2059,7 +2123,11 @@ TEST_F(LLVMCodeBuilderTest, GetListItemIndex) "-1\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -2150,7 +2218,11 @@ TEST_F(LLVMCodeBuilderTest, ListContainsItem) "false\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -2192,7 +2264,10 @@ TEST_F(LLVMCodeBuilderTest, Yield) build(); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); static const std::string expected1 = "no_args\n" @@ -2221,7 +2296,7 @@ TEST_F(LLVMCodeBuilderTest, Yield) createBuilder(true); build(); code = m_builder->finalize(); - ctx = code->createExecutionContext(&m_target); + ctx = code->createExecutionContext(&thread); static const std::string expected = "no_args\n" @@ -2273,7 +2348,11 @@ TEST_F(LLVMCodeBuilderTest, VariablesAfterSuspend) "-4.8\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_FALSE(code->isFinished(ctx.get())); @@ -2361,7 +2440,11 @@ TEST_F(LLVMCodeBuilderTest, ListsAfterSuspend) "hello\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_FALSE(code->isFinished(ctx.get())); @@ -2523,7 +2606,10 @@ TEST_F(LLVMCodeBuilderTest, IfStatement) m_builder->endIf(); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); static const std::string expected = "no_args\n" @@ -2634,7 +2720,11 @@ TEST_F(LLVMCodeBuilderTest, IfStatementVariables) "true\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -2771,7 +2861,11 @@ TEST_F(LLVMCodeBuilderTest, IfStatementLists) "false\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -2842,7 +2936,10 @@ TEST_F(LLVMCodeBuilderTest, RepeatLoop) m_builder->endLoop(); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); static const std::string expected = "no_args\n" @@ -2882,7 +2979,7 @@ TEST_F(LLVMCodeBuilderTest, RepeatLoop) m_builder->endLoop(); code = m_builder->finalize(); - ctx = code->createExecutionContext(&m_target); + ctx = code->createExecutionContext(&thread); static const std::string expected1 = "no_args\n"; @@ -2908,7 +3005,7 @@ TEST_F(LLVMCodeBuilderTest, RepeatLoop) m_builder->endLoop(); code = m_builder->finalize(); - ctx = code->createExecutionContext(&m_target); + ctx = code->createExecutionContext(&thread); code->run(ctx.get()); ASSERT_TRUE(code->isFinished(ctx.get())); } @@ -2976,7 +3073,10 @@ TEST_F(LLVMCodeBuilderTest, WhileLoop) m_builder->endLoop(); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); static const std::string expected = "1_arg 0\n" @@ -3001,7 +3101,7 @@ TEST_F(LLVMCodeBuilderTest, WhileLoop) m_builder->endLoop(); code = m_builder->finalize(); - ctx = code->createExecutionContext(&m_target); + ctx = code->createExecutionContext(&thread); static const std::string expected1 = "no_args\n"; @@ -3081,7 +3181,10 @@ TEST_F(LLVMCodeBuilderTest, RepeatUntilLoop) m_builder->endLoop(); auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&m_target); + Script script(&m_target, nullptr, nullptr); + script.setCode(code); + Thread thread(&m_target, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); static const std::string expected = "1_arg 0\n" @@ -3106,7 +3209,7 @@ TEST_F(LLVMCodeBuilderTest, RepeatUntilLoop) m_builder->endLoop(); code = m_builder->finalize(); - ctx = code->createExecutionContext(&m_target); + ctx = code->createExecutionContext(&thread); static const std::string expected1 = "no_args\n"; @@ -3244,7 +3347,11 @@ TEST_F(LLVMCodeBuilderTest, LoopVariables) "true\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); @@ -3434,7 +3541,11 @@ TEST_F(LLVMCodeBuilderTest, LoopLists) "false\n"; auto code = m_builder->finalize(); - auto ctx = code->createExecutionContext(&sprite); + Script script(&sprite, nullptr, nullptr); + script.setCode(code); + ; + Thread thread(&sprite, nullptr, &script); + auto ctx = code->createExecutionContext(&thread); testing::internal::CaptureStdout(); code->run(ctx.get()); ASSERT_EQ(testing::internal::GetCapturedStdout(), expected); diff --git a/test/dev/llvm/llvmexecutablecode_test.cpp b/test/dev/llvm/llvmexecutablecode_test.cpp index def0f985..581a3a58 100644 --- a/test/dev/llvm/llvmexecutablecode_test.cpp +++ b/test/dev/llvm/llvmexecutablecode_test.cpp @@ -3,11 +3,13 @@ #include #include #include +#include +#include #include #include #include #include -#include +#include #include "testmock.h" #include "testfunctions.h" @@ -23,6 +25,8 @@ class LLVMExecutableCodeTest : public testing::Test m_builder = std::make_unique>(m_ctx); test_function(nullptr, nullptr, nullptr, nullptr, nullptr); // force dependency + m_script = std::make_unique