Skip to content

Commit 366e11d

Browse files
committed
fix #567: Fix variable and list lookup order
1 parent 3e5c33d commit 366e11d

File tree

4 files changed

+69
-10
lines changed

4 files changed

+69
-10
lines changed

src/engine/internal/engine.cpp

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,32 +1436,74 @@ std::shared_ptr<Block> Engine::getBlock(const std::string &id, Target *target)
14361436
}
14371437

14381438
// Returns the variable with the given ID.
1439-
std::shared_ptr<Variable> Engine::getVariable(const std::string &id)
1439+
std::shared_ptr<Variable> Engine::getVariable(const std::string &id, Target *target)
14401440
{
14411441
if (id.empty())
14421442
return nullptr;
14431443

1444-
for (auto target : m_targets) {
1445-
int index = target->findVariableById(id);
1444+
Stage *stage = this->stage();
1445+
int index;
1446+
1447+
// Check stage
1448+
index = stage->findVariableById(id);
1449+
1450+
if (index != -1)
1451+
return stage->variableAt(index);
1452+
1453+
// Check currently compiled target
1454+
if (target != stage) {
1455+
index = target->findVariableById(id);
1456+
14461457
if (index != -1)
14471458
return target->variableAt(index);
14481459
}
14491460

1461+
// Fall back to checking all the other targets
1462+
for (auto t : m_targets) {
1463+
if (t.get() != stage && t.get() != target) {
1464+
int index = t->findVariableById(id);
1465+
1466+
if (index != -1)
1467+
return t->variableAt(index);
1468+
}
1469+
}
1470+
14501471
return nullptr;
14511472
}
14521473

14531474
// Returns the Scratch list with the given ID.
1454-
std::shared_ptr<List> Engine::getList(const std::string &id)
1475+
std::shared_ptr<List> Engine::getList(const std::string &id, Target *target)
14551476
{
14561477
if (id.empty())
14571478
return nullptr;
14581479

1459-
for (auto target : m_targets) {
1460-
int index = target->findListById(id);
1480+
Stage *stage = this->stage();
1481+
int index;
1482+
1483+
// Check stage
1484+
index = stage->findListById(id);
1485+
1486+
if (index != -1)
1487+
return stage->listAt(index);
1488+
1489+
// Check currently compiled target
1490+
if (target != stage) {
1491+
index = target->findListById(id);
1492+
14611493
if (index != -1)
14621494
return target->listAt(index);
14631495
}
14641496

1497+
// Fall back to checking all the other targets
1498+
for (auto t : m_targets) {
1499+
if (t.get() != stage && t.get() != target) {
1500+
int index = t->findListById(id);
1501+
1502+
if (index != -1)
1503+
return t->listAt(index);
1504+
}
1505+
}
1506+
14651507
return nullptr;
14661508
}
14671509

@@ -1507,12 +1549,12 @@ std::shared_ptr<Comment> Engine::getComment(const std::string &id, Target *targe
15071549
std::shared_ptr<Entity> Engine::getEntity(const std::string &id, Target *target)
15081550
{
15091551
// Variables
1510-
auto variable = getVariable(id);
1552+
auto variable = getVariable(id, target);
15111553
if (variable)
15121554
return std::static_pointer_cast<Entity>(variable);
15131555

15141556
// Lists
1515-
auto list = getList(id);
1557+
auto list = getList(id, target);
15161558
if (list)
15171559
return std::static_pointer_cast<Entity>(list);
15181560

src/engine/internal/engine.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ class Engine : public IEngine
203203
void createMissingMonitors();
204204
void addVarOrListMonitor(std::shared_ptr<Monitor> monitor, Target *target);
205205
std::shared_ptr<Block> getBlock(const std::string &id, Target *target);
206-
std::shared_ptr<Variable> getVariable(const std::string &id);
207-
std::shared_ptr<List> getList(const std::string &id);
206+
std::shared_ptr<Variable> getVariable(const std::string &id, Target *target);
207+
std::shared_ptr<List> getList(const std::string &id, Target *target);
208208
std::shared_ptr<Broadcast> getBroadcast(const std::string &id);
209209
std::shared_ptr<Comment> getComment(const std::string &id, Target *target);
210210
std::shared_ptr<Entity> getEntity(const std::string &id, Target *target);

test/engine/engine_test.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,3 +2333,20 @@ TEST(EngineTest, AlwaysStopCloneThreads)
23332333
ASSERT_VAR(stage, "test");
23342334
ASSERT_EQ(GET_VAR(stage, "test")->value().toInt(), 0);
23352335
}
2336+
2337+
TEST(EngineTest, DuplicateVariableOrListIDs)
2338+
{
2339+
// Regtest for #567
2340+
Project p("regtest_projects/567_duplicate_variable_list_id.sb3");
2341+
ASSERT_TRUE(p.load());
2342+
2343+
auto engine = p.engine();
2344+
2345+
Stage *stage = engine->stage();
2346+
ASSERT_TRUE(stage);
2347+
2348+
engine->run();
2349+
2350+
ASSERT_VAR(stage, "passed");
2351+
ASSERT_TRUE(GET_VAR(stage, "passed")->value().toBool());
2352+
}
Binary file not shown.

0 commit comments

Comments
 (0)