Skip to content

Commit 8f90f33

Browse files
committed
Implement data_variable monitor
1 parent 98865bf commit 8f90f33

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

src/blocks/variableblocks.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <scratchcpp/iengine.h>
44
#include <scratchcpp/compiler.h>
55
#include <scratchcpp/compilerconstant.h>
6+
#include <scratchcpp/block.h>
67
#include <scratchcpp/input.h>
78
#include <scratchcpp/field.h>
89
#include <scratchcpp/variable.h>
@@ -28,9 +29,16 @@ Rgb VariableBlocks::color() const
2829

2930
void VariableBlocks::registerBlocks(IEngine *engine)
3031
{
32+
// Blocks
3133
engine->addCompileFunction(this, "data_variable", &compileVariable);
3234
engine->addCompileFunction(this, "data_setvariableto", &compileSetVariableTo);
3335
engine->addCompileFunction(this, "data_changevariableby", &compileChangeVariableBy);
36+
37+
// Monitor names
38+
engine->addMonitorNameFunction(this, "data_variable", &variableMonitorName);
39+
40+
// Monitor change functions
41+
engine->addMonitorChangeFunction(this, "data_variable", &changeVariableMonitorValue);
3442
}
3543

3644
CompilerValue *VariableBlocks::compileVariable(Compiler *compiler)
@@ -70,3 +78,33 @@ CompilerValue *VariableBlocks::compileChangeVariableBy(Compiler *compiler)
7078

7179
return nullptr;
7280
}
81+
82+
const std::string &VariableBlocks::variableMonitorName(Block *block)
83+
{
84+
static const std::string empty = "";
85+
86+
auto field = block->fieldAt(block->findField("VARIABLE"));
87+
88+
if (!field)
89+
return empty;
90+
91+
Variable *var = dynamic_cast<Variable *>(field->valuePtr().get());
92+
93+
if (var)
94+
return var->name();
95+
else
96+
return empty;
97+
}
98+
99+
void VariableBlocks::changeVariableMonitorValue(Block *block, const Value &newValue)
100+
{
101+
auto field = block->fieldAt(block->findField("VARIABLE"));
102+
103+
if (!field)
104+
return;
105+
106+
Variable *var = dynamic_cast<Variable *>(field->valuePtr().get());
107+
108+
if (var)
109+
var->setValue(newValue);
110+
}

src/blocks/variableblocks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class VariableBlocks : public IExtension
2020
static CompilerValue *compileVariable(Compiler *compiler);
2121
static CompilerValue *compileSetVariableTo(Compiler *compiler);
2222
static CompilerValue *compileChangeVariableBy(Compiler *compiler);
23+
24+
static const std::string &variableMonitorName(Block *block);
25+
static void changeVariableMonitorValue(Block *block, const Value &newValue);
2326
};
2427

2528
} // namespace libscratchcpp

test/blocks/variable_blocks_test.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <scratchcpp/variable.h>
44
#include <scratchcpp/list.h>
55
#include <scratchcpp/compiler.h>
6+
#include <scratchcpp/monitor.h>
7+
#include <scratchcpp/block.h>
68
#include <scratchcpp/test/scriptbuilder.h>
79
#include <enginemock.h>
810

@@ -55,6 +57,41 @@ TEST_F(VariableBlocksTest, Variable)
5557
ASSERT_EQ(Value(values[1]), "Hello world");
5658
}
5759

60+
TEST_F(VariableBlocksTest, VariableMonitor)
61+
{
62+
auto target = std::make_shared<Sprite>();
63+
auto var1 = std::make_shared<Variable>("", "var1", 835.21);
64+
target->addVariable(var1);
65+
auto var2 = std::make_shared<Variable>("", "var2", "Hello world");
66+
target->addVariable(var2);
67+
68+
auto monitor1 = std::make_shared<Monitor>("monitor", "data_variable");
69+
auto monitor2 = std::make_shared<Monitor>("monitor", "data_variable");
70+
monitor1->block()->setTarget(target.get());
71+
monitor2->block()->setTarget(target.get());
72+
m_engine->setMonitors({ monitor1, monitor2 });
73+
74+
ScriptBuilder builder1(m_extension.get(), m_engine, target);
75+
builder1.addBlock(monitor1->block());
76+
builder1.addEntityField("VARIABLE", var1);
77+
78+
ScriptBuilder builder2(m_extension.get(), m_engine, target);
79+
builder2.addBlock(monitor2->block());
80+
builder2.addEntityField("VARIABLE", var2);
81+
82+
m_engine->compile();
83+
ASSERT_EQ(monitor1->name(), var1->name());
84+
ASSERT_EQ(monitor2->name(), var2->name());
85+
86+
monitor1->changeValue("test");
87+
ASSERT_EQ(var1->value().toString(), "test");
88+
ASSERT_EQ(var2->value().toString(), "Hello world");
89+
90+
monitor2->changeValue(-0.25);
91+
ASSERT_EQ(var1->value().toString(), "test");
92+
ASSERT_EQ(var2->value().toDouble(), -0.25);
93+
}
94+
5895
TEST_F(VariableBlocksTest, SetVariableTo)
5996
{
6097
auto target = std::make_shared<Sprite>();

0 commit comments

Comments
 (0)