Skip to content

Implement data monitor blocks #432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/blocks/listblocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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<size_t>(compiler->listIndex(compiler->field(LIST)->valuePtr())));
}

void ListBlocks::compileAddToList(Compiler *compiler)
{
compiler->addInput(ITEM);
Expand Down
1 change: 1 addition & 0 deletions src/blocks/listblocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions src/blocks/variableblocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/blocks/variableblocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
Expand Down
31 changes: 31 additions & 0 deletions test/blocks/list_blocks_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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<List>("b", "list1");
auto block1 = createListBlock("a", "data_listcontents", list1);

// [list2]
auto list2 = std::make_shared<List>("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<unsigned int>({ vm::OP_START, vm::OP_CONST, 0, vm::OP_CONST, 1, vm::OP_HALT }));
ASSERT_EQ(compiler.constValues(), std::vector<Value>({ 0, 1 }));
ASSERT_TRUE(compiler.variables().empty());
ASSERT_EQ(
compiler.lists(),
std::vector<List *>({
list1.get(),
list2.get(),
}));
}

TEST_F(ListBlocksTest, AddToList)
{
Compiler compiler(&m_engine);
Expand Down
43 changes: 43 additions & 0 deletions test/blocks/variable_blocks_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ class VariableBlocksTest : public testing::Test
return block;
}

// For read variable
std::shared_ptr<Block> createVariableBlock(const std::string &id, const std::string &opcode, std::shared_ptr<Variable> variable) const
{
auto block = std::make_shared<Block>(id, opcode);

auto variableField = std::make_shared<Field>("VARIABLE", Value(), variable);
variableField->setFieldId(VariableBlocks::VARIABLE);
block->addField(variableField);

return block;
}

std::unique_ptr<IBlockSection> m_section;
EngineMock m_engineMock;
Engine m_engine;
Expand All @@ -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);

Expand All @@ -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<Variable>("b", "var1");
auto block1 = createVariableBlock("a", "data_variable", var1);

// [var2]
auto var2 = std::make_shared<Variable>("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<unsigned int>({ 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<Variable *>({
var1.get(),
var2.get(),
}));
ASSERT_TRUE(compiler.lists().empty());
}

TEST_F(VariableBlocksTest, SetVariableTo)
{
Compiler compiler(&m_engine);
Expand Down