Skip to content

Commit f62c2e0

Browse files
committed
Implement control_while
1 parent 834b91c commit f62c2e0

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

src/dev/blocks/controlblocks.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ void ControlBlocks::registerBlocks(IEngine *engine)
3434
engine->addCompileFunction(this, "control_wait", &compileWait);
3535
engine->addCompileFunction(this, "control_wait_until", &compileWaitUntil);
3636
engine->addCompileFunction(this, "control_repeat_until", &compileRepeatUntil);
37+
engine->addCompileFunction(this, "control_while", &compileWhile);
3738
}
3839

3940
CompilerValue *ControlBlocks::compileForever(Compiler *compiler)
@@ -114,6 +115,14 @@ CompilerValue *ControlBlocks::compileRepeatUntil(Compiler *compiler)
114115
return nullptr;
115116
}
116117

118+
CompilerValue *ControlBlocks::compileWhile(Compiler *compiler)
119+
{
120+
auto substack = compiler->input("SUBSTACK");
121+
compiler->beginLoopCondition();
122+
compiler->moveToWhileLoop(compiler->addInput("CONDITION"), substack ? substack->valueBlock() : nullptr);
123+
return nullptr;
124+
}
125+
117126
extern "C" void control_stop_all(ExecutionContext *ctx)
118127
{
119128
ctx->engine()->stop();

src/dev/blocks/controlblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ControlBlocks : public IExtension
2424
static CompilerValue *compileWait(Compiler *compiler);
2525
static CompilerValue *compileWaitUntil(Compiler *compiler);
2626
static CompilerValue *compileRepeatUntil(Compiler *compiler);
27+
static CompilerValue *compileWhile(Compiler *compiler);
2728
};
2829

2930
} // namespace libscratchcpp

test/dev/blocks/control_blocks_test.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,90 @@ TEST_F(ControlBlocksTest, RepeatUntil)
559559
}
560560
}
561561
}
562+
563+
TEST_F(ControlBlocksTest, While)
564+
{
565+
auto target = std::make_shared<Sprite>();
566+
567+
{
568+
ScriptBuilder builder(m_extension.get(), m_engine, target);
569+
570+
builder.addBlock("control_while");
571+
auto substack = std::make_shared<Block>("", "test_print_test");
572+
builder.addObscuredInput("SUBSTACK", substack);
573+
builder.addValueInput("CONDITION", true);
574+
builder.build();
575+
m_engine->start();
576+
577+
for (int i = 0; i < 2; i++) {
578+
testing::internal::CaptureStdout();
579+
m_engine->step();
580+
ASSERT_EQ(testing::internal::GetCapturedStdout().substr(0, 10), "test\ntest\n");
581+
ASSERT_TRUE(m_engine->isRunning());
582+
}
583+
}
584+
585+
m_engine->clear();
586+
target = std::make_shared<Sprite>();
587+
588+
{
589+
ScriptBuilder builder(m_extension.get(), m_engine, target);
590+
591+
builder.addBlock("control_while");
592+
auto substack = std::make_shared<Block>("", "test_print_test");
593+
builder.addObscuredInput("SUBSTACK", substack);
594+
builder.addValueInput("CONDITION", false);
595+
builder.build();
596+
m_engine->start();
597+
598+
testing::internal::CaptureStdout();
599+
m_engine->step();
600+
m_engine->step();
601+
ASSERT_TRUE(testing::internal::GetCapturedStdout().empty());
602+
ASSERT_FALSE(m_engine->isRunning());
603+
}
604+
605+
m_engine->clear();
606+
target = std::make_shared<Sprite>();
607+
608+
{
609+
ScriptBuilder builder(m_extension.get(), m_engine, target);
610+
611+
builder.addBlock("control_while");
612+
auto substack = std::make_shared<Block>("", "test_print_test");
613+
builder.addObscuredInput("SUBSTACK", substack);
614+
auto block = std::make_shared<Block>("", "test_condition");
615+
builder.addObscuredInput("CONDITION", block);
616+
builder.build();
617+
618+
conditionReturnValue = true;
619+
m_engine->start();
620+
621+
testing::internal::CaptureStdout();
622+
m_engine->step();
623+
ASSERT_EQ(testing::internal::GetCapturedStdout().substr(0, 10), "test\ntest\n");
624+
ASSERT_TRUE(m_engine->isRunning());
625+
626+
conditionReturnValue = false;
627+
m_engine->step();
628+
m_engine->step();
629+
ASSERT_FALSE(m_engine->isRunning());
630+
}
631+
632+
m_engine->clear();
633+
target = std::make_shared<Sprite>();
634+
635+
{
636+
ScriptBuilder builder(m_extension.get(), m_engine, target);
637+
builder.addBlock("control_while");
638+
builder.addValueInput("CONDITION", true);
639+
640+
builder.build();
641+
m_engine->start();
642+
643+
for (int i = 0; i < 2; i++) {
644+
m_engine->step();
645+
ASSERT_TRUE(m_engine->isRunning());
646+
}
647+
}
648+
}

0 commit comments

Comments
 (0)