Skip to content

Commit 187fb02

Browse files
authored
Merge pull request #471 from scratchcpp/monitor_visibility_blocks
Implement monitor visibility blocks
2 parents d14fe3b + e507813 commit 187fb02

File tree

16 files changed

+690
-4
lines changed

16 files changed

+690
-4
lines changed

include/scratchcpp/list.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace libscratchcpp
1212
{
1313

1414
class Target;
15+
class Monitor;
1516
class ListPrivate;
1617

1718
/*! \brief The List class represents a Scratch list. */
@@ -29,6 +30,9 @@ class LIBSCRATCHCPP_EXPORT List
2930
Target *target() const;
3031
void setTarget(Target *target);
3132

33+
Monitor *monitor() const;
34+
void setMonitor(Monitor *monitor);
35+
3236
long indexOf(const Value &value) const;
3337
bool contains(const Value &value) const;
3438

include/scratchcpp/variable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace libscratchcpp
1010
{
1111

1212
class Target;
13+
class Monitor;
1314
class VariablePrivate;
1415

1516
/*! \brief The Variable class represents a Scratch variable. */
@@ -33,6 +34,9 @@ class LIBSCRATCHCPP_EXPORT Variable : public Entity
3334
Target *target() const;
3435
void setTarget(Target *target);
3536

37+
Monitor *monitor() const;
38+
void setMonitor(Monitor *monitor);
39+
3640
std::shared_ptr<Variable> clone();
3741

3842
private:

src/blocks/listblocks.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <scratchcpp/field.h>
66
#include <scratchcpp/block.h>
77
#include <scratchcpp/list.h>
8+
#include <scratchcpp/stage.h>
9+
#include <scratchcpp/monitor.h>
810

911
#include "listblocks.h"
1012

@@ -33,6 +35,8 @@ void ListBlocks::registerBlocks(IEngine *engine)
3335
engine->addCompileFunction(this, "data_itemnumoflist", &compileItemNumberInList);
3436
engine->addCompileFunction(this, "data_lengthoflist", &compileLengthOfList);
3537
engine->addCompileFunction(this, "data_listcontainsitem", &compileListContainsItem);
38+
engine->addCompileFunction(this, "data_showlist", &compileShowList);
39+
engine->addCompileFunction(this, "data_hidelist", &compileHideList);
3640

3741
// Monitor names
3842
engine->addMonitorNameFunction(this, "data_listcontents", &listContentsMonitorName);
@@ -107,6 +111,84 @@ void ListBlocks::compileListContainsItem(Compiler *compiler)
107111
compiler->addInstruction(vm::OP_LIST_CONTAINS, { compiler->listIndex(compiler->field(LIST)->valuePtr()) });
108112
}
109113

114+
void ListBlocks::compileShowList(Compiler *compiler)
115+
{
116+
Field *field = compiler->field(LIST);
117+
assert(field);
118+
List *var = static_cast<List *>(field->valuePtr().get());
119+
assert(var);
120+
121+
compiler->addConstValue(var->id());
122+
123+
if (var->target() == static_cast<Target *>(compiler->engine()->stage()))
124+
compiler->addFunctionCall(&showGlobalList);
125+
else
126+
compiler->addFunctionCall(&showList);
127+
}
128+
129+
void ListBlocks::compileHideList(Compiler *compiler)
130+
{
131+
Field *field = compiler->field(LIST);
132+
assert(field);
133+
List *var = static_cast<List *>(field->valuePtr().get());
134+
assert(var);
135+
136+
compiler->addConstValue(var->id());
137+
138+
if (var->target() == static_cast<Target *>(compiler->engine()->stage()))
139+
compiler->addFunctionCall(&hideGlobalList);
140+
else
141+
compiler->addFunctionCall(&hideList);
142+
}
143+
144+
void ListBlocks::setListVisible(std::shared_ptr<List> list, bool visible)
145+
{
146+
if (list) {
147+
assert(list->monitor());
148+
list->monitor()->setVisible(visible);
149+
}
150+
}
151+
152+
unsigned int ListBlocks::showGlobalList(VirtualMachine *vm)
153+
{
154+
if (Stage *target = vm->engine()->stage()) {
155+
int index = target->findListById(vm->getInput(0, 1)->toString());
156+
setListVisible(target->listAt(index), true);
157+
}
158+
159+
return 1;
160+
}
161+
162+
unsigned int ListBlocks::showList(VirtualMachine *vm)
163+
{
164+
if (Target *target = vm->target()) {
165+
int index = target->findListById(vm->getInput(0, 1)->toString());
166+
setListVisible(target->listAt(index), true);
167+
}
168+
169+
return 1;
170+
}
171+
172+
unsigned int ListBlocks::hideGlobalList(VirtualMachine *vm)
173+
{
174+
if (Stage *target = vm->engine()->stage()) {
175+
int index = target->findListById(vm->getInput(0, 1)->toString());
176+
setListVisible(target->listAt(index), false);
177+
}
178+
179+
return 1;
180+
}
181+
182+
unsigned int ListBlocks::hideList(VirtualMachine *vm)
183+
{
184+
if (Target *target = vm->target()) {
185+
int index = target->findListById(vm->getInput(0, 1)->toString());
186+
setListVisible(target->listAt(index), false);
187+
}
188+
189+
return 1;
190+
}
191+
110192
const std::string &ListBlocks::listContentsMonitorName(Block *block)
111193
{
112194
List *list = dynamic_cast<List *>(block->findFieldById(LIST)->valuePtr().get());

src/blocks/listblocks.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace libscratchcpp
88
{
99

1010
class Compiler;
11+
class List;
1112

1213
/*! \brief The ListBlocks class contains the implementation of list blocks. */
1314
class ListBlocks : public IBlockSection
@@ -39,6 +40,15 @@ class ListBlocks : public IBlockSection
3940
static void compileItemNumberInList(Compiler *compiler);
4041
static void compileLengthOfList(Compiler *compiler);
4142
static void compileListContainsItem(Compiler *compiler);
43+
static void compileShowList(Compiler *compiler);
44+
static void compileHideList(Compiler *compiler);
45+
46+
static void setListVisible(std::shared_ptr<List> list, bool visible);
47+
48+
static unsigned int showGlobalList(VirtualMachine *vm);
49+
static unsigned int showList(VirtualMachine *vm);
50+
static unsigned int hideGlobalList(VirtualMachine *vm);
51+
static unsigned int hideList(VirtualMachine *vm);
4252

4353
static const std::string &listContentsMonitorName(Block *block);
4454

src/blocks/variableblocks.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <scratchcpp/field.h>
66
#include <scratchcpp/block.h>
77
#include <scratchcpp/variable.h>
8+
#include <scratchcpp/stage.h>
9+
#include <scratchcpp/monitor.h>
810

911
#include "variableblocks.h"
1012

@@ -21,6 +23,8 @@ void VariableBlocks::registerBlocks(IEngine *engine)
2123
engine->addCompileFunction(this, "data_variable", &compileVariable);
2224
engine->addCompileFunction(this, "data_setvariableto", &compileSetVariable);
2325
engine->addCompileFunction(this, "data_changevariableby", &compileChangeVariableBy);
26+
engine->addCompileFunction(this, "data_showvariable", &compileShowVariable);
27+
engine->addCompileFunction(this, "data_hidevariable", &compileHideVariable);
2428

2529
// Monitor names
2630
engine->addMonitorNameFunction(this, "data_variable", &variableMonitorName);
@@ -53,6 +57,84 @@ void VariableBlocks::compileChangeVariableBy(Compiler *compiler)
5357
compiler->addInstruction(vm::OP_CHANGE_VAR, { compiler->variableIndex(compiler->field(VARIABLE)->valuePtr()) });
5458
}
5559

60+
void VariableBlocks::compileShowVariable(Compiler *compiler)
61+
{
62+
Field *field = compiler->field(VARIABLE);
63+
assert(field);
64+
Variable *var = static_cast<Variable *>(field->valuePtr().get());
65+
assert(var);
66+
67+
compiler->addConstValue(var->id());
68+
69+
if (var->target() == static_cast<Target *>(compiler->engine()->stage()))
70+
compiler->addFunctionCall(&showGlobalVariable);
71+
else
72+
compiler->addFunctionCall(&showVariable);
73+
}
74+
75+
void VariableBlocks::compileHideVariable(Compiler *compiler)
76+
{
77+
Field *field = compiler->field(VARIABLE);
78+
assert(field);
79+
Variable *var = static_cast<Variable *>(field->valuePtr().get());
80+
assert(var);
81+
82+
compiler->addConstValue(var->id());
83+
84+
if (var->target() == static_cast<Target *>(compiler->engine()->stage()))
85+
compiler->addFunctionCall(&hideGlobalVariable);
86+
else
87+
compiler->addFunctionCall(&hideVariable);
88+
}
89+
90+
void VariableBlocks::setVarVisible(std::shared_ptr<Variable> var, bool visible)
91+
{
92+
if (var) {
93+
assert(var->monitor());
94+
var->monitor()->setVisible(visible);
95+
}
96+
}
97+
98+
unsigned int VariableBlocks::showGlobalVariable(VirtualMachine *vm)
99+
{
100+
if (Stage *target = vm->engine()->stage()) {
101+
int index = target->findVariableById(vm->getInput(0, 1)->toString());
102+
setVarVisible(target->variableAt(index), true);
103+
}
104+
105+
return 1;
106+
}
107+
108+
unsigned int VariableBlocks::showVariable(VirtualMachine *vm)
109+
{
110+
if (Target *target = vm->target()) {
111+
int index = target->findVariableById(vm->getInput(0, 1)->toString());
112+
setVarVisible(target->variableAt(index), true);
113+
}
114+
115+
return 1;
116+
}
117+
118+
unsigned int VariableBlocks::hideGlobalVariable(VirtualMachine *vm)
119+
{
120+
if (Stage *target = vm->engine()->stage()) {
121+
int index = target->findVariableById(vm->getInput(0, 1)->toString());
122+
setVarVisible(target->variableAt(index), false);
123+
}
124+
125+
return 1;
126+
}
127+
128+
unsigned int VariableBlocks::hideVariable(VirtualMachine *vm)
129+
{
130+
if (Target *target = vm->target()) {
131+
int index = target->findVariableById(vm->getInput(0, 1)->toString());
132+
setVarVisible(target->variableAt(index), false);
133+
}
134+
135+
return 1;
136+
}
137+
56138
const std::string &VariableBlocks::variableMonitorName(Block *block)
57139
{
58140
Variable *var = dynamic_cast<Variable *>(block->findFieldById(VARIABLE)->valuePtr().get());

src/blocks/variableblocks.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace libscratchcpp
88
{
99

1010
class Compiler;
11+
class Variable;
1112

1213
/*! \brief The VariableBlocks class contains the implementation of variable blocks. */
1314
class VariableBlocks : public IBlockSection
@@ -30,6 +31,15 @@ class VariableBlocks : public IBlockSection
3031
static void compileVariable(Compiler *compiler);
3132
static void compileSetVariable(Compiler *compiler);
3233
static void compileChangeVariableBy(Compiler *compiler);
34+
static void compileShowVariable(Compiler *compiler);
35+
static void compileHideVariable(Compiler *compiler);
36+
37+
static void setVarVisible(std::shared_ptr<Variable> var, bool visible);
38+
39+
static unsigned int showGlobalVariable(VirtualMachine *vm);
40+
static unsigned int showVariable(VirtualMachine *vm);
41+
static unsigned int hideGlobalVariable(VirtualMachine *vm);
42+
static unsigned int hideVariable(VirtualMachine *vm);
3343

3444
static const std::string &variableMonitorName(Block *block);
3545
static void changeVariableMonitorValue(Block *block, const Value &newValue);

src/engine/internal/engine.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,19 +164,31 @@ void Engine::resolveIds()
164164
if (field->name() == "VARIABLE") {
165165
std::string name = field->value().toString();
166166
int index = target->findVariable(name);
167+
std::shared_ptr<Variable> var;
167168

168-
if (index == -1)
169-
index = target->addVariable(std::make_shared<Variable>(monitor->id(), name));
169+
if (index == -1) {
170+
var = std::make_shared<Variable>(monitor->id(), name);
171+
index = target->addVariable(var);
172+
} else
173+
var = target->variableAt(index);
170174

171175
field->setValuePtr(target->variableAt(index));
176+
assert(var);
177+
var->setMonitor(monitor.get());
172178
} else if (field->name() == "LIST") {
173179
std::string name = field->value().toString();
174180
int index = target->findList(name);
181+
std::shared_ptr<List> list;
175182

176-
if (index == -1)
177-
index = target->addList(std::make_shared<List>(monitor->id(), name));
183+
if (index == -1) {
184+
list = std::make_shared<List>(monitor->id(), name);
185+
index = target->addList(list);
186+
} else
187+
list = target->listAt(index);
178188

179189
field->setValuePtr(target->listAt(index));
190+
assert(list);
191+
list->setMonitor(monitor.get());
180192
}
181193
}
182194

src/scratch/list.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ void List::setTarget(Target *target)
3838
impl->target = target;
3939
}
4040

41+
/*! Returns the monitor of this list. */
42+
Monitor *List::monitor() const
43+
{
44+
return impl->monitor;
45+
}
46+
47+
/*! Sets the monitor of this list. */
48+
void List::setMonitor(Monitor *monitor)
49+
{
50+
impl->monitor = monitor;
51+
}
52+
4153
/*! Returns the index of the given item. */
4254
long List::indexOf(const Value &value) const
4355
{

src/scratch/list_p.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ namespace libscratchcpp
88
{
99

1010
class Target;
11+
class Monitor;
1112

1213
struct ListPrivate
1314
{
1415
ListPrivate(const std::string &name);
1516

1617
std::string name;
1718
Target *target = nullptr;
19+
Monitor *monitor = nullptr;
1820
};
1921

2022
} // namespace libscratchcpp

src/scratch/variable.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ void Variable::setTarget(Target *target)
6161
impl->target = target;
6262
}
6363

64+
/*! Returns the monitor of this variable. */
65+
Monitor *Variable::monitor() const
66+
{
67+
return impl->monitor;
68+
}
69+
70+
/*! Sets the monitor of this variable. */
71+
void Variable::setMonitor(Monitor *monitor)
72+
{
73+
impl->monitor = monitor;
74+
}
75+
6476
/*! Creates a copy of the variable. */
6577
std::shared_ptr<Variable> Variable::clone()
6678
{

0 commit comments

Comments
 (0)