Skip to content

Commit 4c2f1aa

Browse files
authored
Merge pull request #112 from scratchcpp/fix_loading_bugs
Fix loading bugs
2 parents 0a77257 + a586391 commit 4c2f1aa

9 files changed

+89
-25
lines changed

src/ProjectPlayer.qml

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ ProjectScene {
133133
id: projectPenLayer
134134
engine: loader.engine
135135
anchors.fill: parent
136+
visible: !priv.loading
136137
}
137138

138139
Component {

src/mouseeventhandler.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ void scratchcpprender::MouseEventHandler::getSprites()
113113
Q_ASSERT(sprite->scratchTarget());
114114
m_sprites.push_back(sprite);
115115
}
116+
117+
// Make sure the clicked and hovered item pointers are in the list
118+
// If not, make them nullptr
119+
if (std::find(m_sprites.begin(), m_sprites.end(), m_clickedItem) == m_sprites.end())
120+
m_clickedItem = nullptr;
121+
122+
if (std::find(m_sprites.begin(), m_sprites.end(), m_hoveredItem) == m_sprites.end())
123+
m_hoveredItem = nullptr;
116124
}
117125

118126
void scratchcpprender::MouseEventHandler::addClone(SpriteModel *model)

src/projectloader.cpp

+47-8
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,46 @@ void ProjectLoader::setFileName(const QString &newFileName)
6464

6565
m_fileName = newFileName;
6666

67+
// Stop the project
68+
if (m_engine)
69+
m_engine->stop();
70+
71+
// Reset stage model
72+
m_stage.init(nullptr);
73+
74+
if (m_stage.renderedTarget())
75+
m_stage.renderedTarget()->update();
76+
77+
// Delete old sprites
78+
for (SpriteModel *sprite : m_sprites)
79+
sprite->deleteLater();
80+
81+
m_sprites.clear();
82+
emit spritesChanged();
83+
84+
// Delete old clones
85+
for (SpriteModel *clone : m_clones)
86+
deleteCloneObject(clone);
87+
88+
m_clones.clear();
89+
emit clonesChanged();
90+
91+
// Delete old monitors
92+
for (MonitorModel *monitor : m_monitors) {
93+
emit monitorRemoved(monitor);
94+
monitor->deleteLater();
95+
}
96+
97+
m_monitors.clear();
98+
emit monitorsChanged();
99+
100+
// Clear the engine
101+
if (m_engine)
102+
m_engine->clear();
103+
104+
m_engine = nullptr;
105+
emit engineChanged();
106+
67107
m_project.setScratchVersion(ScratchVersion::Scratch3);
68108
m_project.setFileName(m_fileName.toStdString());
69109
m_loadStatus = false;
@@ -198,12 +238,6 @@ void ProjectLoader::load()
198238
m_engineMutex.lock();
199239
m_engine = m_project.engine().get();
200240

201-
// Delete old sprites
202-
for (SpriteModel *sprite : m_sprites)
203-
sprite->deleteLater();
204-
205-
m_sprites.clear();
206-
207241
if (!m_engine || m_stopLoading) {
208242
m_engineMutex.unlock();
209243
emit fileNameChanged();
@@ -313,13 +347,18 @@ void ProjectLoader::addClone(SpriteModel *model)
313347
emit clonesChanged();
314348
}
315349

316-
void ProjectLoader::deleteClone(SpriteModel *model)
350+
void ProjectLoader::deleteCloneObject(SpriteModel *model)
317351
{
318-
m_clones.removeAll(model);
319352
emit cloneDeleted(model);
320353
Q_ASSERT(model->renderedTarget());
321354
model->renderedTarget()->deinitClone();
322355
model->deleteLater();
356+
}
357+
358+
void ProjectLoader::deleteClone(SpriteModel *model)
359+
{
360+
m_clones.removeAll(model);
361+
deleteCloneObject(model);
323362
emit clonesChanged();
324363
}
325364

src/projectloader.h

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class ProjectLoader : public QObject
120120
void initTimer();
121121
void redraw();
122122
void addClone(SpriteModel *model);
123+
void deleteCloneObject(SpriteModel *model);
123124
void deleteClone(SpriteModel *model);
124125
void addMonitor(libscratchcpp::Monitor *monitor);
125126
void removeMonitor(libscratchcpp::Monitor *monitor, libscratchcpp::IMonitorHandler *iface);

src/renderedtarget.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,22 @@ void RenderedTarget::setEngine(IEngine *newEngine)
199199
return;
200200

201201
m_engine = newEngine;
202+
m_costume = nullptr;
203+
m_costumesLoaded = false;
204+
205+
if (!m_skinsInherited) {
206+
for (const auto &[costume, skin] : m_skins)
207+
delete skin;
208+
209+
m_skins.clear();
210+
}
211+
212+
m_skin = nullptr;
213+
m_texture = Texture();
214+
m_oldTexture = Texture();
215+
clearGraphicEffects();
216+
m_hullPoints.clear();
217+
202218
emit engineChanged();
203219
}
204220

src/stagemodel.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,8 @@ void StageModel::onBubbleTextChanged(const std::string &text)
7979

8080
void StageModel::loadCostume()
8181
{
82-
if (m_renderedTarget && m_stage) {
83-
if (m_stage)
84-
m_renderedTarget->updateCostume(m_stage->currentCostume().get());
85-
}
82+
if (m_renderedTarget && m_stage)
83+
m_renderedTarget->updateCostume(m_stage->currentCostume().get());
8684
}
8785

8886
libscratchcpp::Stage *StageModel::stage() const
@@ -101,7 +99,6 @@ void StageModel::setRenderedTarget(IRenderedTarget *newRenderedTarget)
10199
return;
102100

103101
m_renderedTarget = newRenderedTarget;
104-
loadCostume();
105102

106103
emit renderedTargetChanged();
107104
}

test/projectloader/projectloader_test.cpp

+12-9
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ProjectLoaderTest : public testing::Test
2929
QSignalSpy engineSpy(loader, &ProjectLoader::engineChanged);
3030
QSignalSpy stageSpy(loader, &ProjectLoader::stageChanged);
3131
QSignalSpy spritesSpy(loader, &ProjectLoader::spritesChanged);
32+
QSignalSpy clonesSpy(loader, &ProjectLoader::clonesChanged);
3233
QSignalSpy monitorsSpy(loader, &ProjectLoader::monitorsChanged);
3334
QSignalSpy monitorAddedSpy(loader, &ProjectLoader::monitorAdded);
3435

@@ -37,10 +38,11 @@ class ProjectLoaderTest : public testing::Test
3738
ASSERT_EQ(fileNameSpy.count(), 1);
3839
ASSERT_EQ(loadStatusSpy.count(), 1);
3940
ASSERT_TRUE(loadingFinishedSpy.empty());
40-
ASSERT_TRUE(engineSpy.empty());
41+
ASSERT_EQ(engineSpy.count(), 1);
4142
ASSERT_TRUE(stageSpy.empty());
42-
ASSERT_TRUE(spritesSpy.empty());
43-
ASSERT_TRUE(monitorsSpy.empty());
43+
ASSERT_EQ(spritesSpy.count(), 1);
44+
ASSERT_EQ(clonesSpy.count(), 1);
45+
ASSERT_EQ(monitorsSpy.count(), 1);
4446
ASSERT_TRUE(monitorAddedSpy.empty());
4547
ASSERT_EQ(loader->fileName(), fileName);
4648
ASSERT_FALSE(loader->loadStatus());
@@ -52,10 +54,11 @@ class ProjectLoaderTest : public testing::Test
5254
ASSERT_EQ(fileNameSpy.count(), 1);
5355
ASSERT_EQ(loadStatusSpy.count(), 2);
5456
ASSERT_EQ(loadingFinishedSpy.count(), 1);
55-
ASSERT_EQ(engineSpy.count(), 1);
57+
ASSERT_EQ(engineSpy.count(), 2);
5658
ASSERT_EQ(stageSpy.count(), 1);
57-
ASSERT_EQ(spritesSpy.count(), 1);
58-
ASSERT_EQ(monitorsSpy.count(), loader->monitorList().size());
59+
ASSERT_EQ(spritesSpy.count(), 2);
60+
ASSERT_EQ(clonesSpy.count(), 1);
61+
ASSERT_EQ(monitorsSpy.count(), loader->monitorList().size() + 1);
5962
ASSERT_EQ(monitorAddedSpy.count(), loader->monitorList().size());
6063
}
6164
};
@@ -113,13 +116,13 @@ TEST_F(ProjectLoaderTest, Clones)
113116
load(&loader, "clones.sb3");
114117
ASSERT_TRUE(cloneCreatedSpy.empty());
115118
ASSERT_TRUE(cloneDeletedSpy.empty());
116-
ASSERT_TRUE(clonesChangedSpy.empty());
119+
ASSERT_EQ(clonesChangedSpy.count(), 1);
117120

118121
auto engine = loader.engine();
119122
engine->run();
120123
ASSERT_EQ(cloneCreatedSpy.count(), 3);
121124
ASSERT_EQ(cloneDeletedSpy.count(), 0);
122-
ASSERT_EQ(clonesChangedSpy.count(), 3);
125+
ASSERT_EQ(clonesChangedSpy.count(), 4);
123126

124127
const auto &sprites = loader.spriteList();
125128
const auto &clones = loader.cloneList();
@@ -138,7 +141,7 @@ TEST_F(ProjectLoaderTest, Clones)
138141
clones[1]->sprite()->deleteClone();
139142
ASSERT_EQ(cloneCreatedSpy.count(), 3);
140143
ASSERT_EQ(cloneDeletedSpy.count(), 1);
141-
ASSERT_EQ(clonesChangedSpy.count(), 4);
144+
ASSERT_EQ(clonesChangedSpy.count(), 5);
142145
ASSERT_EQ(clones.size(), 2);
143146
}
144147

test/renderedtarget/renderedtarget_test.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ TEST_F(RenderedTargetTest, UpdateMethods)
5656
createContextAndSurface(&context, &surface);
5757
RenderedTarget parent; // a parent item is needed for setVisible() to work
5858
RenderedTarget target(&parent);
59+
EngineMock engine;
60+
target.setEngine(&engine);
5961
QSignalSpy mirrorHorizontallySpy(&target, &RenderedTarget::mirrorHorizontallyChanged);
6062
ASSERT_FALSE(target.costumesLoaded());
6163

@@ -73,8 +75,6 @@ TEST_F(RenderedTargetTest, UpdateMethods)
7375
stage.addCostume(costume);
7476
target.loadCostumes();
7577
ASSERT_TRUE(target.costumesLoaded());
76-
EngineMock engine;
77-
target.setEngine(&engine);
7878

7979
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
8080
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));

test/target_models/stagemodel_test.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ TEST(StageModelTest, RenderedTarget)
123123

124124
RenderedTargetMock renderedTarget;
125125
QSignalSpy spy(&model, &StageModel::renderedTargetChanged);
126-
EXPECT_CALL(renderedTarget, updateCostume(c2.get()));
127126
model.setRenderedTarget(&renderedTarget);
128127
ASSERT_EQ(spy.count(), 1);
129128
ASSERT_EQ(model.renderedTarget(), &renderedTarget);

0 commit comments

Comments
 (0)