Skip to content

Commit 44305dc

Browse files
committed
Engine: Implement monitors
1 parent f56e550 commit 44305dc

File tree

3 files changed

+43
-18
lines changed

3 files changed

+43
-18
lines changed

src/engine/internal/engine.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,10 @@ void Engine::updateMonitors()
468468
auto script = monitor->script();
469469

470470
if (script) {
471-
// TODO: Implement this
472-
/*auto thread = script->start();
473-
thread->run();
474-
monitor->updateValue(thread->vm());*/
471+
auto thread = script->start();
472+
ValueData value = thread->runReporter();
473+
monitor->updateValue(Value(value));
474+
value_free(&value);
475475
}
476476
}
477477
}
@@ -1851,7 +1851,35 @@ int Engine::resolveFieldValue(IExtension *extension, const std::string &value) c
18511851

18521852
void Engine::compileMonitor(std::shared_ptr<Monitor> monitor)
18531853
{
1854-
// TODO: Implement this
1854+
Target *target = monitor->sprite() ? static_cast<Target *>(monitor->sprite()) : stage();
1855+
auto block = monitor->block();
1856+
auto ext = blockExtension(block->opcode());
1857+
1858+
if (ext) {
1859+
auto ctx = Compiler::createContext(this, target);
1860+
Compiler compiler(ctx.get());
1861+
MonitorNameFunc nameFunc = resolveMonitorNameFunc(ext, block->opcode());
1862+
1863+
if (nameFunc)
1864+
monitor->setName(nameFunc(block.get()));
1865+
1866+
MonitorChangeFunc changeFunc = resolveMonitorChangeFunc(ext, block->opcode());
1867+
monitor->setValueChangeFunction(changeFunc);
1868+
1869+
auto script = std::make_shared<Script>(target, block, this);
1870+
monitor->setScript(script);
1871+
auto code = compiler.compile(block, Compiler::CodeType::Reporter);
1872+
script->setCode(code);
1873+
m_monitorCompilerContexts[monitor.get()] = ctx;
1874+
1875+
const auto &unsupportedBlocks = compiler.unsupportedBlocks();
1876+
1877+
for (const std::string &opcode : unsupportedBlocks)
1878+
m_unsupportedBlocks.insert(opcode);
1879+
} else {
1880+
std::cout << "warning: unsupported monitor block: " << block->opcode() << std::endl;
1881+
m_unsupportedBlocks.insert(block->opcode());
1882+
}
18551883
}
18561884

18571885
void Engine::finalize()

src/engine/internal/engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ class Engine : public IEngine
237237

238238
std::vector<std::shared_ptr<Target>> m_targets;
239239
std::unordered_map<Target *, std::shared_ptr<CompilerContext>> m_compilerContexts;
240+
std::unordered_map<Monitor *, std::shared_ptr<CompilerContext>> m_monitorCompilerContexts; // TODO: Use shared_ptr in (LLVM)ExecutableCode and remove these maps (might not be a good idea)
240241
std::vector<std::shared_ptr<Broadcast>> m_broadcasts;
241242
std::unordered_map<Broadcast *, std::vector<Script *>> m_broadcastMap;
242243
std::unordered_map<Broadcast *, std::vector<Script *>> m_backdropBroadcastMap;

test/engine/engine_test.cpp

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <scratchcpp/script.h>
1313
#include <scratchcpp/thread.h>
1414
#include <scratchcpp/scratchconfiguration.h>
15+
#include <scratchcpp/compiler.h>
16+
#include <scratchcpp/compilerconstant.h>
1517
#include <scratch/sound_p.h>
1618
#include <timermock.h>
1719
#include <clockmock.h>
@@ -189,7 +191,7 @@ TEST(EngineTest, StopSignal)
189191
}
190192
}
191193

192-
/*TEST(EngineTest, CompileAndExecuteMonitors)
194+
TEST(EngineTest, CompileAndExecuteMonitors)
193195
{
194196
Engine engine;
195197
auto stage = std::make_shared<Stage>();
@@ -209,8 +211,8 @@ TEST(EngineTest, StopSignal)
209211
EXPECT_CALL(*extension, onInit);
210212
ScratchConfiguration::registerExtension(extension);
211213
engine.setExtensions({ "MonitorTest" });
212-
engine.addCompileFunction(extension.get(), m1->opcode(), [](Compiler *compiler) { compiler->addConstValue(5.4); });
213-
engine.addCompileFunction(extension.get(), m2->opcode(), [](Compiler *compiler) { compiler->addConstValue("test"); });
214+
engine.addCompileFunction(extension.get(), m1->opcode(), [](Compiler *compiler) -> CompilerValue * { return compiler->addConstValue(5.4); });
215+
engine.addCompileFunction(extension.get(), m2->opcode(), [](Compiler *compiler) -> CompilerValue * { return compiler->addConstValue("test"); });
214216

215217
engine.addMonitorNameFunction(extension.get(), m1->opcode(), [](Block *block) -> const std::string & {
216218
static const std::string testStr = "test";
@@ -229,11 +231,9 @@ TEST(EngineTest, StopSignal)
229231
auto script3 = m3->script();
230232
ASSERT_TRUE(script1 && script2 && !script3);
231233

232-
ASSERT_EQ(script1->bytecodeVector(), std::vector<unsigned int>({ vm::OP_START, vm::OP_CONST, 0, vm::OP_EXEC, 0, vm::OP_HALT }));
233234
ASSERT_EQ(script1->target(), stage.get());
234235
ASSERT_EQ(script1->topBlock(), m1->block());
235236

236-
ASSERT_EQ(script2->bytecodeVector(), std::vector<unsigned int>({ vm::OP_START, vm::OP_CONST, 0, vm::OP_EXEC, 0, vm::OP_HALT }));
237237
ASSERT_EQ(script2->target(), sprite.get());
238238
ASSERT_EQ(script2->topBlock(), m2->block());
239239

@@ -255,27 +255,23 @@ TEST(EngineTest, StopSignal)
255255
m3->setInterface(&iface3);
256256

257257
EXPECT_CALL(iface1, onValueChanged).Times(0);
258-
EXPECT_CALL(iface2, onValueChanged(_)).WillOnce(WithArgs<0>(Invoke([](const VirtualMachine *vm) {
259-
ASSERT_EQ(vm->registerCount(), 1);
260-
ASSERT_EQ(vm->getInput(0, 1)->toString(), "test");
261-
ASSERT_FALSE(vm->atEnd()); // the script shouldn't end because that would spam the console with leak warnings
262-
})));
258+
EXPECT_CALL(iface2, onValueChanged(_)).WillOnce(WithArgs<0>(Invoke([](const Value &value) { ASSERT_EQ(value.toString(), "test"); })));
263259
EXPECT_CALL(iface3, onValueChanged).Times(0);
264260
engine.updateMonitors();
265261

266262
// Change the monitor values
267-
testing::internal::CaptureStdout();
263+
/*testing::internal::CaptureStdout();
268264
EXPECT_CALL(iface1, onValueChanged);
269265
m1->changeValue(0);
270266
ASSERT_EQ(testing::internal::GetCapturedStdout(), "change 1!\n");
271267
272268
testing::internal::CaptureStdout();
273269
EXPECT_CALL(iface2, onValueChanged);
274270
m2->changeValue(0);
275-
ASSERT_EQ(testing::internal::GetCapturedStdout(), "change 2!\n");
271+
ASSERT_EQ(testing::internal::GetCapturedStdout(), "change 2!\n");*/
276272

277273
ScratchConfiguration::removeExtension(extension);
278-
}*/
274+
}
279275

280276
TEST(EngineTest, IsRunning)
281277
{

0 commit comments

Comments
 (0)