Skip to content

Commit 8e43154

Browse files
committed
Fix delete this clone stopping behavior
1 parent e505c20 commit 8e43154

File tree

2 files changed

+77
-13
lines changed

2 files changed

+77
-13
lines changed

src/blocks/controlblocks.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ CompilerValue *ControlBlocks::compileCreateCloneOf(Compiler *compiler)
178178

179179
CompilerValue *ControlBlocks::compileDeleteThisClone(Compiler *compiler)
180180
{
181-
compiler->addTargetFunctionCall("control_delete_this_clone");
181+
CompilerValue *deleted = compiler->addTargetFunctionCall("control_delete_this_clone", Compiler::StaticType::Bool);
182+
compiler->beginIfStatement(deleted);
183+
compiler->createStop();
184+
compiler->endIf();
182185
return nullptr;
183186
}
184187

@@ -234,10 +237,17 @@ extern "C" void control_create_clone(ExecutionContext *ctx, const StringPtr *spr
234237
}
235238
}
236239

237-
extern "C" void control_delete_this_clone(Target *target)
240+
extern "C" bool control_delete_this_clone(Target *target)
238241
{
239242
if (!target->isStage()) {
240-
target->engine()->stopTarget(target, nullptr);
241-
static_cast<Sprite *>(target)->deleteClone();
243+
Sprite *sprite = static_cast<Sprite *>(target);
244+
245+
if (sprite->isClone()) {
246+
target->engine()->stopTarget(target, nullptr);
247+
sprite->deleteClone();
248+
return true;
249+
}
242250
}
251+
252+
return false;
243253
}

test/blocks/control_blocks_test.cpp

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,45 +1064,96 @@ TEST_F(ControlBlocksTest, CreateCloneOfStage)
10641064
}
10651065
}
10661066

1067-
TEST_F(ControlBlocksTest, DeleteThisClone)
1067+
TEST_F(ControlBlocksTest, DeleteThisClone_Clone)
10681068
{
1069-
Sprite sprite;
1070-
sprite.setEngine(&m_engineMock);
1069+
auto sprite = std::make_shared<Sprite>();
1070+
sprite->setEngine(&m_engineMock);
1071+
1072+
auto var = std::make_shared<Variable>("", "");
1073+
sprite->addVariable(var);
10711074

10721075
std::shared_ptr<Sprite> clone;
10731076
EXPECT_CALL(m_engineMock, cloneLimit()).WillRepeatedly(Return(-1));
10741077
EXPECT_CALL(m_engineMock, initClone(_)).WillOnce(SaveArg<0>(&clone));
1075-
EXPECT_CALL(m_engineMock, moveDrawableBehindOther(_, &sprite));
1078+
EXPECT_CALL(m_engineMock, moveDrawableBehindOther(_, sprite.get()));
10761079
EXPECT_CALL(m_engineMock, requestRedraw());
1077-
sprite.clone();
1080+
sprite->clone();
10781081
ASSERT_TRUE(clone);
10791082

1080-
ScriptBuilder builder(m_extension.get(), m_engine, clone);
1083+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
10811084

10821085
builder.addBlock("control_delete_this_clone");
10831086
auto block = builder.currentBlock();
10841087

1085-
Compiler compiler(&m_engineMock, clone.get());
1088+
builder.addBlock("test_set_var");
1089+
builder.addEntityField("VARIABLE", var);
1090+
builder.addValueInput("VALUE", true);
1091+
builder.currentBlock();
1092+
1093+
Compiler compiler(&m_engineMock, sprite.get());
10861094
auto code = compiler.compile(block);
1087-
Script script(clone.get(), block, &m_engineMock);
1095+
Script script(sprite.get(), block, &m_engineMock);
10881096
script.setCode(code);
10891097
Thread thread(clone.get(), &m_engineMock, &script);
10901098

10911099
EXPECT_CALL(m_engineMock, stopTarget(clone.get(), nullptr));
10921100
EXPECT_CALL(m_engineMock, deinitClone(clone));
10931101
thread.run();
1102+
1103+
// The script should stop (variable value is false)
1104+
ASSERT_FALSE(clone->variableAt(0)->value().toBool());
10941105
}
10951106

1096-
TEST_F(ControlBlocksTest, DeleteThisCloneStage)
1107+
TEST_F(ControlBlocksTest, DeleteThisClone_NotCloneSprite)
1108+
{
1109+
auto sprite = std::make_shared<Sprite>();
1110+
sprite->setEngine(&m_engineMock);
1111+
1112+
auto var = std::make_shared<Variable>("", "");
1113+
sprite->addVariable(var);
1114+
1115+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
1116+
1117+
builder.addBlock("control_delete_this_clone");
1118+
auto block = builder.currentBlock();
1119+
1120+
builder.addBlock("test_set_var");
1121+
builder.addEntityField("VARIABLE", var);
1122+
builder.addValueInput("VALUE", true);
1123+
builder.currentBlock();
1124+
1125+
Compiler compiler(&m_engineMock, sprite.get());
1126+
auto code = compiler.compile(block);
1127+
Script script(sprite.get(), block, &m_engineMock);
1128+
script.setCode(code);
1129+
Thread thread(sprite.get(), &m_engineMock, &script);
1130+
1131+
EXPECT_CALL(m_engineMock, stopTarget).Times(0);
1132+
EXPECT_CALL(m_engineMock, deinitClone).Times(0);
1133+
thread.run();
1134+
1135+
// The script should NOT stop (variable value is true)
1136+
ASSERT_TRUE(var->value().toBool());
1137+
}
1138+
1139+
TEST_F(ControlBlocksTest, DeleteThisClone_Stage)
10971140
{
10981141
auto target = std::make_shared<Stage>();
10991142
target->setEngine(&m_engineMock);
11001143

1144+
auto var = std::make_shared<Variable>("", "");
1145+
target->addVariable(var);
1146+
11011147
ScriptBuilder builder(m_extension.get(), m_engine, target);
11021148

11031149
builder.addBlock("control_delete_this_clone");
11041150
auto block = builder.currentBlock();
11051151

1152+
builder.addBlock("test_set_var");
1153+
builder.addEntityField("VARIABLE", var);
1154+
builder.addValueInput("VALUE", true);
1155+
builder.currentBlock();
1156+
11061157
Compiler compiler(&m_engineMock, target.get());
11071158
auto code = compiler.compile(block);
11081159
Script script(target.get(), block, &m_engineMock);
@@ -1112,4 +1163,7 @@ TEST_F(ControlBlocksTest, DeleteThisCloneStage)
11121163
EXPECT_CALL(m_engineMock, stopTarget).Times(0);
11131164
EXPECT_CALL(m_engineMock, deinitClone).Times(0);
11141165
thread.run();
1166+
1167+
// The script should NOT stop (variable value is true)
1168+
ASSERT_TRUE(var->value().toBool());
11151169
}

0 commit comments

Comments
 (0)