Skip to content

Commit 48839af

Browse files
committed
Add clone support to ProjectLoader
1 parent 478c263 commit 48839af

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

src/projectloader.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ const QList<SpriteModel *> &ProjectLoader::spriteList() const
116116
return m_sprites;
117117
}
118118

119+
QQmlListProperty<SpriteModel> ProjectLoader::clones()
120+
{
121+
return QQmlListProperty<SpriteModel>(this, &m_clones);
122+
}
123+
124+
const QList<SpriteModel *> &ProjectLoader::cloneList() const
125+
{
126+
return m_clones;
127+
}
128+
119129
void ProjectLoader::start()
120130
{
121131
if (m_loadThread.isRunning())
@@ -196,6 +206,7 @@ void ProjectLoader::load()
196206
SpriteModel *sprite = new SpriteModel;
197207
sprite->moveToThread(qApp->thread());
198208
dynamic_cast<Sprite *>(target.get())->setInterface(sprite);
209+
connect(sprite, &SpriteModel::cloned, this, &ProjectLoader::addClone);
199210
m_sprites.push_back(sprite);
200211
}
201212
}
@@ -240,6 +251,31 @@ void ProjectLoader::redraw()
240251
if (renderedTarget)
241252
renderedTarget->beforeRedraw();
242253
}
254+
255+
for (auto sprite : m_clones) {
256+
auto renderedTarget = sprite->renderedTarget();
257+
258+
if (renderedTarget)
259+
renderedTarget->beforeRedraw();
260+
}
261+
}
262+
263+
void ProjectLoader::addClone(SpriteModel *model)
264+
{
265+
connect(model, &SpriteModel::cloneDeleted, this, &ProjectLoader::deleteClone);
266+
m_clones.push_back(model);
267+
emit cloneCreated(model);
268+
emit clonesChanged();
269+
}
270+
271+
void ProjectLoader::deleteClone(SpriteModel *model)
272+
{
273+
m_clones.removeAll(model);
274+
emit cloneDeleted(model);
275+
Q_ASSERT(model->renderedTarget());
276+
model->renderedTarget()->deinitClone();
277+
model->deleteLater();
278+
emit clonesChanged();
243279
}
244280

245281
double ProjectLoader::fps() const

src/projectloader.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#include "stagemodel.h"
1111

12+
Q_MOC_INCLUDE("spritemodel.h");
13+
1214
namespace scratchcpprender
1315
{
1416

@@ -23,6 +25,7 @@ class ProjectLoader : public QObject
2325
Q_PROPERTY(libscratchcpp::IEngine *engine READ engine NOTIFY engineChanged)
2426
Q_PROPERTY(StageModel *stage READ stage NOTIFY stageChanged)
2527
Q_PROPERTY(QQmlListProperty<SpriteModel> sprites READ sprites NOTIFY spritesChanged)
28+
Q_PROPERTY(QQmlListProperty<SpriteModel> clones READ clones NOTIFY clonesChanged)
2629
Q_PROPERTY(double fps READ fps WRITE setFps NOTIFY fpsChanged)
2730
Q_PROPERTY(bool turboMode READ turboMode WRITE setTurboMode NOTIFY turboModeChanged)
2831
Q_PROPERTY(unsigned int stageWidth READ stageWidth WRITE setStageWidth NOTIFY stageWidthChanged)
@@ -49,6 +52,9 @@ class ProjectLoader : public QObject
4952
QQmlListProperty<SpriteModel> sprites();
5053
const QList<SpriteModel *> &spriteList() const;
5154

55+
QQmlListProperty<SpriteModel> clones();
56+
const QList<SpriteModel *> &cloneList() const;
57+
5258
Q_INVOKABLE void start();
5359
Q_INVOKABLE void stop();
5460

@@ -81,6 +87,7 @@ class ProjectLoader : public QObject
8187
void engineChanged();
8288
void stageChanged();
8389
void spritesChanged();
90+
void clonesChanged();
8491
void fpsChanged();
8592
void turboModeChanged();
8693
void stageWidthChanged();
@@ -89,6 +96,8 @@ class ProjectLoader : public QObject
8996
void spriteFencingChanged();
9097
void downloadedAssetsChanged();
9198
void assetCountChanged();
99+
void cloneCreated(SpriteModel *model);
100+
void cloneDeleted(SpriteModel *model);
92101

93102
protected:
94103
void timerEvent(QTimerEvent *event) override;
@@ -98,6 +107,8 @@ class ProjectLoader : public QObject
98107
void load();
99108
void initTimer();
100109
void redraw();
110+
void addClone(SpriteModel *model);
111+
void deleteClone(SpriteModel *model);
101112

102113
int m_timerId = -1;
103114
QString m_fileName;
@@ -108,6 +119,7 @@ class ProjectLoader : public QObject
108119
bool m_loadStatus = false;
109120
StageModel m_stage;
110121
QList<SpriteModel *> m_sprites;
122+
QList<SpriteModel *> m_clones;
111123
double m_fps = 30;
112124
bool m_turboMode = false;
113125
unsigned int m_stageWidth = 480;

test/clones.sb3

1.32 KB
Binary file not shown.

test/projectloader/projectloader_test.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <projectloader.h>
33
#include <spritemodel.h>
44
#include <enginemock.h>
5+
#include <renderedtargetmock.h>
56

67
#include "../common.h"
78

@@ -73,6 +74,44 @@ TEST_F(ProjectLoaderTest, Load)
7374
ASSERT_EQ(sprites[1]->sprite(), engine->targetAt(2));
7475
}
7576

77+
TEST_F(ProjectLoaderTest, Clones)
78+
{
79+
ProjectLoader loader;
80+
QSignalSpy cloneCreatedSpy(&loader, &ProjectLoader::cloneCreated);
81+
QSignalSpy cloneDeletedSpy(&loader, &ProjectLoader::cloneDeleted);
82+
QSignalSpy clonesChangedSpy(&loader, &ProjectLoader::clonesChanged);
83+
load(&loader, "clones.sb3");
84+
ASSERT_TRUE(cloneCreatedSpy.empty());
85+
ASSERT_TRUE(cloneDeletedSpy.empty());
86+
ASSERT_TRUE(clonesChangedSpy.empty());
87+
88+
auto engine = loader.engine();
89+
engine->run();
90+
ASSERT_EQ(cloneCreatedSpy.count(), 3);
91+
ASSERT_EQ(cloneDeletedSpy.count(), 0);
92+
ASSERT_EQ(clonesChangedSpy.count(), 3);
93+
94+
const auto &sprites = loader.spriteList();
95+
const auto &clones = loader.cloneList();
96+
ASSERT_EQ(sprites.size(), 1);
97+
ASSERT_EQ(clones.size(), 3);
98+
ASSERT_EQ(clones[0]->sprite()->cloneSprite(), sprites[0]->sprite());
99+
ASSERT_EQ(clones[1]->sprite()->cloneSprite(), sprites[0]->sprite());
100+
ASSERT_EQ(clones[2]->sprite()->cloneSprite(), sprites[0]->sprite());
101+
102+
RenderedTargetMock target1, target2, target3;
103+
clones[0]->setRenderedTarget(&target1);
104+
clones[1]->setRenderedTarget(&target2);
105+
clones[2]->setRenderedTarget(&target3);
106+
107+
EXPECT_CALL(target2, deinitClone());
108+
clones[1]->sprite()->deleteClone();
109+
ASSERT_EQ(cloneCreatedSpy.count(), 3);
110+
ASSERT_EQ(cloneDeletedSpy.count(), 1);
111+
ASSERT_EQ(clonesChangedSpy.count(), 4);
112+
ASSERT_EQ(clones.size(), 2);
113+
}
114+
76115
TEST_F(ProjectLoaderTest, StartStop)
77116
{
78117
ProjectLoader loader;

0 commit comments

Comments
 (0)