Skip to content

Commit daba5a4

Browse files
committed
fix #660: Stop the entire thread in stop all and delete this clone
1 parent 9f3749d commit daba5a4

8 files changed

+106
-2
lines changed

src/blocks/controlblocks.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ CompilerValue *ControlBlocks::compileStop(Compiler *compiler)
9090

9191
if (str == "all") {
9292
compiler->addFunctionCallWithCtx("control_stop_all", Compiler::StaticType::Void);
93-
compiler->createStop();
93+
compiler->invalidateTarget(); // if this is a clone, it doesn't exist anymore
94+
compiler->createThreadStop();
9495
} else if (str == "this script")
9596
compiler->createStop();
9697
else if (str == "other scripts in sprite" || str == "other scripts in stage")
@@ -181,7 +182,8 @@ CompilerValue *ControlBlocks::compileDeleteThisClone(Compiler *compiler)
181182
{
182183
CompilerValue *deleted = compiler->addTargetFunctionCall("control_delete_this_clone", Compiler::StaticType::Bool);
183184
compiler->beginIfStatement(deleted);
184-
compiler->createStopWithoutSync(); // sync happens before the function call
185+
compiler->invalidateTarget(); // the sprite doesn't exist anymore
186+
compiler->createThreadStop(); // callers should be stopped too
185187
compiler->endIf();
186188
return nullptr;
187189
}

test/engine/engine_test.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2280,3 +2280,105 @@ TEST(EngineTest, BroadcastAndWaitCaseInsensitive)
22802280
ASSERT_VAR(stage, "passed");
22812281
ASSERT_TRUE(GET_VAR(stage, "passed")->value().toBool());
22822282
}
2283+
2284+
TEST(EngineTest, CloneScriptsAreStoppedFromProcedureDeletingTheClone)
2285+
{
2286+
// Regtest for #660
2287+
Project p("regtest_projects/660_stop_script_from_procedure_clone.sb3");
2288+
ASSERT_TRUE(p.load());
2289+
2290+
auto engine = p.engine();
2291+
2292+
Stage *stage = engine->stage();
2293+
ASSERT_TRUE(stage);
2294+
2295+
engine->run();
2296+
2297+
ASSERT_VAR(stage, "passed");
2298+
ASSERT_TRUE(GET_VAR(stage, "passed")->value().toBool());
2299+
}
2300+
2301+
TEST(EngineTest, ScriptsAreNotStoppedFromProcedureStoppingTheProcedureScript)
2302+
{
2303+
// Regtest for #660
2304+
Project p("regtest_projects/660_stop_script_from_procedure_stop_this_script.sb3");
2305+
ASSERT_TRUE(p.load());
2306+
2307+
auto engine = p.engine();
2308+
2309+
Stage *stage = engine->stage();
2310+
ASSERT_TRUE(stage);
2311+
2312+
engine->run();
2313+
2314+
ASSERT_VAR(stage, "passed");
2315+
ASSERT_TRUE(GET_VAR(stage, "passed")->value().toBool());
2316+
}
2317+
2318+
TEST(EngineTest, ScriptsAreNotStoppedFromProcedureStoppingOtherScripts)
2319+
{
2320+
// Regtest for #660
2321+
Project p("regtest_projects/660_stop_script_from_procedure_stop_other_scripts.sb3");
2322+
ASSERT_TRUE(p.load());
2323+
2324+
auto engine = p.engine();
2325+
2326+
Stage *stage = engine->stage();
2327+
ASSERT_TRUE(stage);
2328+
2329+
engine->run();
2330+
2331+
ASSERT_VAR(stage, "passed");
2332+
ASSERT_TRUE(GET_VAR(stage, "passed")->value().toBool());
2333+
}
2334+
2335+
TEST(EngineTest, ScriptsAreStoppedFromProcedureStoppingAll)
2336+
{
2337+
// Regtest for #660
2338+
Project p("regtest_projects/660_stop_script_from_procedure_stop_all.sb3");
2339+
ASSERT_TRUE(p.load());
2340+
2341+
auto engine = p.engine();
2342+
2343+
Stage *stage = engine->stage();
2344+
ASSERT_TRUE(stage);
2345+
2346+
engine->run();
2347+
2348+
ASSERT_VAR(stage, "passed");
2349+
ASSERT_TRUE(GET_VAR(stage, "passed")->value().toBool());
2350+
}
2351+
2352+
TEST(EngineTest, ScriptsAreStoppedFromProcedureStoppingAll_NonWarp)
2353+
{
2354+
// Regtest for #660
2355+
Project p("regtest_projects/660_stop_script_from_procedure_stop_all_non_warp.sb3");
2356+
ASSERT_TRUE(p.load());
2357+
2358+
auto engine = p.engine();
2359+
2360+
Stage *stage = engine->stage();
2361+
ASSERT_TRUE(stage);
2362+
2363+
engine->run();
2364+
2365+
ASSERT_VAR(stage, "passed");
2366+
ASSERT_TRUE(GET_VAR(stage, "passed")->value().toBool());
2367+
}
2368+
2369+
TEST(EngineTest, ScriptsAreStoppedFromProcedureStoppingAll_Nested)
2370+
{
2371+
// Regtest for #660
2372+
Project p("regtest_projects/660_stop_script_from_procedure_stop_all_nested.sb3");
2373+
ASSERT_TRUE(p.load());
2374+
2375+
auto engine = p.engine();
2376+
2377+
Stage *stage = engine->stage();
2378+
ASSERT_TRUE(stage);
2379+
2380+
engine->run();
2381+
2382+
ASSERT_VAR(stage, "passed");
2383+
ASSERT_TRUE(GET_VAR(stage, "passed")->value().toBool());
2384+
}
2.3 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)