Skip to content

Commit be30417

Browse files
committed
Implement control_delete_this_clone block
1 parent 8da80bd commit be30417

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

src/blocks/controlblocks.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ void ControlBlocks::registerBlocks(IEngine *engine)
3232
engine->addCompileFunction(this, "control_wait_until", &compileWaitUntil);
3333
engine->addCompileFunction(this, "control_start_as_clone", &compileStartAsClone);
3434
engine->addCompileFunction(this, "control_create_clone_of", &compileCreateClone);
35+
engine->addCompileFunction(this, "control_delete_this_clone", &compileDeleteThisClone);
3536

3637
// Inputs
3738
engine->addInput(this, "SUBSTACK", SUBSTACK);
@@ -187,6 +188,11 @@ void ControlBlocks::compileCreateClone(Compiler *compiler)
187188
}
188189
}
189190

191+
void ControlBlocks::compileDeleteThisClone(Compiler *compiler)
192+
{
193+
compiler->addFunctionCall(&deleteThisClone);
194+
}
195+
190196
unsigned int ControlBlocks::stopAll(VirtualMachine *vm)
191197
{
192198
vm->engine()->stop();
@@ -267,3 +273,15 @@ unsigned int ControlBlocks::createCloneOfMyself(VirtualMachine *vm)
267273

268274
return 0;
269275
}
276+
277+
unsigned int ControlBlocks::deleteThisClone(VirtualMachine *vm)
278+
{
279+
Target *target = vm->target();
280+
281+
if (target) {
282+
vm->engine()->stopTarget(target, nullptr);
283+
target->~Target();
284+
}
285+
286+
return 0;
287+
}

src/blocks/controlblocks.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class ControlBlocks : public IBlockSection
5656
static void compileWaitUntil(Compiler *compiler);
5757
static void compileStartAsClone(Compiler *compiler);
5858
static void compileCreateClone(Compiler *compiler);
59+
static void compileDeleteThisClone(Compiler *compiler);
5960

6061
static unsigned int stopAll(VirtualMachine *vm);
6162
static unsigned int stopOtherScriptsInSprite(VirtualMachine *vm);
@@ -65,6 +66,7 @@ class ControlBlocks : public IBlockSection
6566
static unsigned int createClone(VirtualMachine *vm);
6667
static unsigned int createCloneByIndex(VirtualMachine *vm);
6768
static unsigned int createCloneOfMyself(VirtualMachine *vm);
69+
static unsigned int deleteThisClone(VirtualMachine *vm);
6870

6971
static inline std::unordered_map<VirtualMachine *, std::pair<std::chrono::steady_clock::time_point, int>> m_timeMap;
7072
};

test/blocks/control_blocks_test.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
using namespace libscratchcpp;
1515

1616
using ::testing::Return;
17+
using ::testing::_;
18+
using ::testing::SaveArg;
1719

1820
class ControlBlocksTest : public testing::Test
1921
{
@@ -153,6 +155,7 @@ TEST_F(ControlBlocksTest, RegisterBlocks)
153155
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "control_wait_until", &ControlBlocks::compileWaitUntil)).Times(1);
154156
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "control_start_as_clone", &ControlBlocks::compileStartAsClone)).Times(1);
155157
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "control_create_clone_of", &ControlBlocks::compileCreateClone)).Times(1);
158+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "control_delete_this_clone", &ControlBlocks::compileDeleteThisClone)).Times(1);
156159

157160
// Inputs
158161
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "SUBSTACK", ControlBlocks::SUBSTACK));
@@ -938,3 +941,47 @@ TEST_F(ControlBlocksTest, StartAsClone)
938941
EXPECT_CALL(m_engineMock, addCloneInitScript(block)).Times(1);
939942
ControlBlocks::compileStartAsClone(&compiler);
940943
}
944+
945+
TEST_F(ControlBlocksTest, DeleteThisClone)
946+
{
947+
Compiler compiler(&m_engineMock);
948+
949+
auto block = createControlBlock("a", "control_delete_this_clone");
950+
951+
EXPECT_CALL(m_engineMock, functionIndex(&ControlBlocks::deleteThisClone)).WillOnce(Return(0));
952+
953+
compiler.init();
954+
compiler.setBlock(block);
955+
ControlBlocks::compileDeleteThisClone(&compiler);
956+
compiler.end();
957+
958+
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_EXEC, 0, vm::OP_HALT }));
959+
ASSERT_TRUE(compiler.constValues().empty());
960+
ASSERT_TRUE(compiler.variables().empty());
961+
ASSERT_TRUE(compiler.lists().empty());
962+
}
963+
964+
TEST_F(ControlBlocksTest, DeleteThisCloneImpl)
965+
{
966+
static unsigned int bytecode[] = { vm::OP_START, vm::OP_EXEC, 0, vm::OP_HALT };
967+
static BlockFunc functions[] = { &ControlBlocks::deleteThisClone };
968+
969+
Sprite sprite;
970+
sprite.setEngine(&m_engineMock);
971+
972+
Sprite *clone;
973+
EXPECT_CALL(m_engineMock, initClone(_)).WillOnce(SaveArg<0>(&clone));
974+
sprite.clone();
975+
ASSERT_TRUE(clone);
976+
977+
VirtualMachine vm(clone, &m_engineMock, nullptr);
978+
vm.setFunctions(functions);
979+
980+
EXPECT_CALL(m_engineMock, stopTarget(clone, nullptr)).Times(1);
981+
982+
vm.setBytecode(bytecode);
983+
vm.run();
984+
985+
ASSERT_EQ(vm.registerCount(), 0);
986+
ASSERT_TRUE(sprite.children().empty());
987+
}

0 commit comments

Comments
 (0)