Skip to content

Commit 694f1bf

Browse files
committed
Add getVisibleTargets() method to IEngine
Resolves: #533
1 parent 14c3d56 commit 694f1bf

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

include/scratchcpp/iengine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
331331
/*! Returns the target at index. */
332332
virtual Target *targetAt(int index) const = 0;
333333

334+
/*! Gets visible targets sorted by layer order and stores them in the given vector. */
335+
virtual void getVisibleTargets(std::vector<Target *> &dst) const = 0;
336+
334337
/*!
335338
* Returns the index of the target with the given name.
336339
* \note Using "Stage" will return the index of the sprite with this name, or nullptr if it doesn't exist.

src/engine/internal/engine.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,33 @@ Target *Engine::targetAt(int index) const
12271227
return m_targets[index].get();
12281228
}
12291229

1230+
void Engine::getVisibleTargets(std::vector<Target *> &dst) const
1231+
{
1232+
dst.clear();
1233+
1234+
for (auto target : m_targets) {
1235+
assert(target);
1236+
1237+
if (target->isStage())
1238+
dst.push_back(target.get());
1239+
else {
1240+
Sprite *sprite = static_cast<Sprite *>(target.get());
1241+
1242+
if (sprite->visible())
1243+
dst.push_back(target.get());
1244+
1245+
const auto &clones = sprite->clones();
1246+
1247+
for (auto clone : clones) {
1248+
if (clone->visible())
1249+
dst.push_back(clone.get());
1250+
}
1251+
}
1252+
}
1253+
1254+
std::sort(dst.begin(), dst.end(), [](Target *t1, Target *t2) { return t1->layerOrder() > t2->layerOrder(); });
1255+
}
1256+
12301257
int Engine::findTarget(const std::string &targetName) const
12311258
{
12321259
auto it = std::find_if(m_targets.begin(), m_targets.end(), [targetName](std::shared_ptr<Target> target) {

src/engine/internal/engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class Engine : public IEngine
138138
const std::vector<std::shared_ptr<Target>> &targets() const override;
139139
void setTargets(const std::vector<std::shared_ptr<Target>> &newTargets) override;
140140
Target *targetAt(int index) const override;
141+
void getVisibleTargets(std::vector<Target *> &dst) const override;
141142
int findTarget(const std::string &targetName) const override;
142143

143144
void moveSpriteToFront(Sprite *sprite) override;

test/engine/engine_test.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,16 +1411,21 @@ TEST(EngineTest, Targets)
14111411
Engine engine;
14121412
ASSERT_TRUE(engine.targets().empty());
14131413

1414-
auto t1 = std::make_shared<Target>();
1414+
auto t1 = std::make_shared<Sprite>();
14151415
t1->setName("Sprite1");
1416-
auto t2 = std::make_shared<Target>();
1416+
t1->setVisible(true);
1417+
t1->setLayerOrder(3);
1418+
auto t2 = std::make_shared<Sprite>();
14171419
auto block1 = std::make_shared<Block>("", "");
14181420
auto block2 = std::make_shared<Block>("", "");
14191421
t2->setName("Sprite2");
1422+
t2->setVisible(false);
1423+
t2->setLayerOrder(1);
14201424
t2->addBlock(block1);
14211425
t2->addBlock(block2);
14221426
auto t3 = std::make_shared<Stage>();
14231427
t3->setName("Stage");
1428+
t3->setLayerOrder(0);
14241429
engine.setTargets({ t1, t2, t3 });
14251430

14261431
ASSERT_EQ(engine.targets(), std::vector<std::shared_ptr<Target>>({ t1, t2, t3 }));
@@ -1436,16 +1441,25 @@ TEST(EngineTest, Targets)
14361441
ASSERT_EQ(engine.findTarget("Stage"), -1);
14371442
ASSERT_EQ(engine.findTarget("_stage_"), 2);
14381443

1439-
auto t4 = std::make_shared<Target>();
1444+
auto t4 = std::make_shared<Sprite>();
14401445
t4->setName("Stage");
1446+
t4->setVisible(true);
1447+
t4->setLayerOrder(2);
14411448
engine.setTargets({ t1, t2, t4 });
14421449
ASSERT_EQ(engine.findTarget("Stage"), 2);
14431450
ASSERT_EQ(engine.findTarget("_stage_"), -1);
14441451

1452+
std::vector<Target *> visibleTargets;
1453+
engine.getVisibleTargets(visibleTargets);
1454+
ASSERT_EQ(visibleTargets, std::vector<Target *>({ t1.get(), t4.get() }));
1455+
14451456
engine.setTargets({ t1, t2, t3, t4 });
14461457
ASSERT_EQ(engine.findTarget("Stage"), 3);
14471458
ASSERT_EQ(engine.findTarget("_stage_"), 2);
14481459

1460+
engine.getVisibleTargets(visibleTargets);
1461+
ASSERT_EQ(visibleTargets, std::vector<Target *>({ t1.get(), t4.get(), t3.get() }));
1462+
14491463
ASSERT_EQ(t1->engine(), &engine);
14501464
ASSERT_EQ(t2->engine(), &engine);
14511465
ASSERT_EQ(t3->engine(), &engine);

test/mocks/enginemock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ class EngineMock : public IEngine
118118
MOCK_METHOD(const std::vector<std::shared_ptr<Target>> &, targets, (), (const, override));
119119
MOCK_METHOD(void, setTargets, (const std::vector<std::shared_ptr<Target>> &), (override));
120120
MOCK_METHOD(Target *, targetAt, (int), (const, override));
121+
MOCK_METHOD(void, getVisibleTargets, (std::vector<Target *> &), (const, override));
121122
MOCK_METHOD(int, findTarget, (const std::string &), (const, override));
122123

123124
MOCK_METHOD(void, moveSpriteToFront, (Sprite * sprite), (override));

0 commit comments

Comments
 (0)