From 22cf854c67b754f9d32945e85f1b58c99da99102 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sat, 13 Jan 2024 13:41:14 +0100 Subject: [PATCH 1/2] Implement data_variable block --- src/blocks/variableblocks.cpp | 7 +++++ src/blocks/variableblocks.h | 1 + test/blocks/variable_blocks_test.cpp | 43 ++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/blocks/variableblocks.cpp b/src/blocks/variableblocks.cpp index 0c38a0df..71d3e9ad 100644 --- a/src/blocks/variableblocks.cpp +++ b/src/blocks/variableblocks.cpp @@ -16,6 +16,7 @@ std::string VariableBlocks::name() const void VariableBlocks::registerBlocks(IEngine *engine) { // Blocks + engine->addCompileFunction(this, "data_variable", &compileVariable); engine->addCompileFunction(this, "data_setvariableto", &compileSetVariable); engine->addCompileFunction(this, "data_changevariableby", &compileChangeVariableBy); @@ -26,6 +27,12 @@ void VariableBlocks::registerBlocks(IEngine *engine) engine->addField(this, "VARIABLE", VARIABLE); } +void VariableBlocks::compileVariable(Compiler *compiler) +{ + // NOTE: This block is only used by variable monitors + compiler->addInstruction(vm::OP_READ_VAR, { compiler->variableIndex(compiler->field(VARIABLE)->valuePtr()) }); +} + void VariableBlocks::compileSetVariable(Compiler *compiler) { compiler->addInput(VALUE); diff --git a/src/blocks/variableblocks.h b/src/blocks/variableblocks.h index 883c8faa..362771c2 100644 --- a/src/blocks/variableblocks.h +++ b/src/blocks/variableblocks.h @@ -27,6 +27,7 @@ class VariableBlocks : public IBlockSection void registerBlocks(IEngine *engine) override; + static void compileVariable(Compiler *compiler); static void compileSetVariable(Compiler *compiler); static void compileChangeVariableBy(Compiler *compiler); }; diff --git a/test/blocks/variable_blocks_test.cpp b/test/blocks/variable_blocks_test.cpp index 33eecad3..507e766c 100644 --- a/test/blocks/variable_blocks_test.cpp +++ b/test/blocks/variable_blocks_test.cpp @@ -37,6 +37,18 @@ class VariableBlocksTest : public testing::Test return block; } + // For read variable + std::shared_ptr createVariableBlock(const std::string &id, const std::string &opcode, std::shared_ptr variable) const + { + auto block = std::make_shared(id, opcode); + + auto variableField = std::make_shared("VARIABLE", Value(), variable); + variableField->setFieldId(VariableBlocks::VARIABLE); + block->addField(variableField); + + return block; + } + std::unique_ptr m_section; EngineMock m_engineMock; Engine m_engine; @@ -55,6 +67,7 @@ TEST_F(VariableBlocksTest, CategoryVisible) TEST_F(VariableBlocksTest, RegisterBlocks) { // Blocks + EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "data_variable", &VariableBlocks::compileVariable)).Times(1); EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "data_setvariableto", &VariableBlocks::compileSetVariable)).Times(1); EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "data_changevariableby", &VariableBlocks::compileChangeVariableBy)).Times(1); @@ -67,6 +80,36 @@ TEST_F(VariableBlocksTest, RegisterBlocks) m_section->registerBlocks(&m_engineMock); } +TEST_F(VariableBlocksTest, Variable) +{ + Compiler compiler(&m_engine); + + // [var1] + auto var1 = std::make_shared("b", "var1"); + auto block1 = createVariableBlock("a", "data_variable", var1); + + // [var2] + auto var2 = std::make_shared("d", "var2"); + auto block2 = createVariableBlock("c", "data_variable", var2); + + compiler.init(); + compiler.setBlock(block1); + VariableBlocks::compileVariable(&compiler); + compiler.setBlock(block2); + VariableBlocks::compileVariable(&compiler); + compiler.end(); + + ASSERT_EQ(compiler.bytecode(), std::vector({ vm::OP_START, vm::OP_READ_VAR, 0, vm::OP_READ_VAR, 1, vm::OP_HALT })); + ASSERT_TRUE(compiler.constValues().empty()); + ASSERT_EQ( + compiler.variables(), + std::vector({ + var1.get(), + var2.get(), + })); + ASSERT_TRUE(compiler.lists().empty()); +} + TEST_F(VariableBlocksTest, SetVariableTo) { Compiler compiler(&m_engine); From e7ff662b5f5b0004ef409bfbfb6c3e7d52ef80dd Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sat, 13 Jan 2024 14:01:12 +0100 Subject: [PATCH 2/2] Implement data_listcontents block --- src/blocks/listblocks.cpp | 9 +++++++++ src/blocks/listblocks.h | 1 + test/blocks/list_blocks_test.cpp | 31 +++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/blocks/listblocks.cpp b/src/blocks/listblocks.cpp index dbfe9a26..852a1746 100644 --- a/src/blocks/listblocks.cpp +++ b/src/blocks/listblocks.cpp @@ -21,6 +21,7 @@ bool ListBlocks::categoryVisible() const void ListBlocks::registerBlocks(IEngine *engine) { // Blocks + engine->addCompileFunction(this, "data_listcontents", &compileListContents); engine->addCompileFunction(this, "data_addtolist", &compileAddToList); engine->addCompileFunction(this, "data_deleteoflist", &compileDeleteFromList); engine->addCompileFunction(this, "data_deletealloflist", &compileDeleteAllOfList); @@ -39,6 +40,14 @@ void ListBlocks::registerBlocks(IEngine *engine) engine->addField(this, "LIST", LIST); } +void ListBlocks::compileListContents(Compiler *compiler) +{ + // NOTE: This block is only used by list monitors + // Instead of returning the actual list contents, let's just return the index of the list + // and let the renderer read the list using the index + compiler->addConstValue(static_cast(compiler->listIndex(compiler->field(LIST)->valuePtr()))); +} + void ListBlocks::compileAddToList(Compiler *compiler) { compiler->addInput(ITEM); diff --git a/src/blocks/listblocks.h b/src/blocks/listblocks.h index 051c55c6..d671b72c 100644 --- a/src/blocks/listblocks.h +++ b/src/blocks/listblocks.h @@ -29,6 +29,7 @@ class ListBlocks : public IBlockSection void registerBlocks(IEngine *engine) override; + static void compileListContents(Compiler *compiler); static void compileAddToList(Compiler *compiler); static void compileDeleteFromList(Compiler *compiler); static void compileDeleteAllOfList(Compiler *compiler); diff --git a/test/blocks/list_blocks_test.cpp b/test/blocks/list_blocks_test.cpp index 5ec69805..a7ea157b 100644 --- a/test/blocks/list_blocks_test.cpp +++ b/test/blocks/list_blocks_test.cpp @@ -94,6 +94,7 @@ TEST_F(ListBlocksTest, CategoryVisible) TEST_F(ListBlocksTest, RegisterBlocks) { // Blocks + EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "data_listcontents", &ListBlocks::compileListContents)).Times(1); EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "data_addtolist", &ListBlocks::compileAddToList)).Times(1); EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "data_deleteoflist", &ListBlocks::compileDeleteFromList)).Times(1); EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "data_deletealloflist", &ListBlocks::compileDeleteAllOfList)).Times(1); @@ -114,6 +115,36 @@ TEST_F(ListBlocksTest, RegisterBlocks) m_section->registerBlocks(&m_engineMock); } +TEST_F(ListBlocksTest, ListContents) +{ + Compiler compiler(&m_engine); + + // [list1] + auto list1 = std::make_shared("b", "list1"); + auto block1 = createListBlock("a", "data_listcontents", list1); + + // [list2] + auto list2 = std::make_shared("d", "list2"); + auto block2 = createListBlock("c", "data_listcontents", list2); + + compiler.init(); + compiler.setBlock(block1); + ListBlocks::compileListContents(&compiler); + compiler.setBlock(block2); + ListBlocks::compileListContents(&compiler); + compiler.end(); + + ASSERT_EQ(compiler.bytecode(), std::vector({ vm::OP_START, vm::OP_CONST, 0, vm::OP_CONST, 1, vm::OP_HALT })); + ASSERT_EQ(compiler.constValues(), std::vector({ 0, 1 })); + ASSERT_TRUE(compiler.variables().empty()); + ASSERT_EQ( + compiler.lists(), + std::vector({ + list1.get(), + list2.get(), + })); +} + TEST_F(ListBlocksTest, AddToList) { Compiler compiler(&m_engine);