Skip to content

Commit 6235b99

Browse files
authored
Merge pull request #542 from scratchcpp/start_stop_signals
Add stopped signal
2 parents 2e86f84 + 8099516 commit 6235b99

File tree

5 files changed

+64
-16
lines changed

5 files changed

+64
-16
lines changed

include/scratchcpp/iengine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
116116
/*! Emits when a script is about to stop. */
117117
virtual sigslot::signal<VirtualMachine *> &threadAboutToStop() = 0;
118118

119+
/*! Emits when the project is stopped by calling stop(). */
120+
virtual sigslot::signal<> &stopped() = 0;
121+
119122
/*! Returns true if the project is currently running. */
120123
virtual bool isRunning() const = 0;
121124

src/engine/internal/engine.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,8 @@ void Engine::stop()
383383
m_threads.clear();
384384
m_running = false;
385385
}
386+
387+
m_stopped();
386388
}
387389

388390
VirtualMachine *Engine::startScript(std::shared_ptr<Block> topLevelBlock, Target *target)
@@ -565,6 +567,11 @@ sigslot::signal<VirtualMachine *> &Engine::threadAboutToStop()
565567
return m_threadAboutToStop;
566568
}
567569

570+
sigslot::signal<> &Engine::stopped()
571+
{
572+
return m_stopped;
573+
}
574+
568575
std::vector<std::shared_ptr<VirtualMachine>> Engine::stepThreads()
569576
{
570577
// https://github.com/scratchfoundation/scratch-vm/blob/develop/src/engine/sequencer.js#L70-L173

src/engine/internal/engine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class Engine : public IEngine
5151

5252
sigslot::signal<> &aboutToRender() override;
5353
sigslot::signal<VirtualMachine *> &threadAboutToStop() override;
54+
sigslot::signal<> &stopped() override;
5455

5556
bool isRunning() const override;
5657

@@ -268,6 +269,7 @@ class Engine : public IEngine
268269
bool m_redrawRequested = false;
269270
sigslot::signal<> m_aboutToRedraw;
270271
sigslot::signal<VirtualMachine *> m_threadAboutToStop;
272+
sigslot::signal<> m_stopped;
271273
bool m_stopEventLoop = false;
272274
std::mutex m_stopEventLoopMutex;
273275

test/engine/engine_test.cpp

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ class RedrawMock
4747
MOCK_METHOD(void, redraw, ());
4848
};
4949

50-
class ThreadAboutToStopMock
50+
class StopMock
5151
{
5252
public:
5353
MOCK_METHOD(void, threadRemoved, (VirtualMachine *));
54+
MOCK_METHOD(void, stopped, ());
5455
};
5556

5657
class AddRemoveMonitorMock
@@ -124,13 +125,13 @@ TEST(EngineTest, ClearThreadAboutToStopSignal)
124125
engine->start();
125126
engine->step();
126127

127-
ThreadAboutToStopMock threadRemovedMock;
128-
EXPECT_CALL(threadRemovedMock, threadRemoved(_)).Times(3).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
128+
StopMock stopMock;
129+
EXPECT_CALL(stopMock, threadRemoved(_)).Times(3).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
129130
ASSERT_TRUE(vm);
130131
ASSERT_FALSE(vm->atEnd());
131132
})));
132133

133-
engine->threadAboutToStop().connect(&ThreadAboutToStopMock::threadRemoved, &threadRemovedMock);
134+
engine->threadAboutToStop().connect(&StopMock::threadRemoved, &stopMock);
134135
engine->clear();
135136
}
136137

@@ -143,16 +144,50 @@ TEST(EngineTest, StopThreadAboutToStopSignal)
143144
engine->start();
144145
engine->step();
145146

146-
ThreadAboutToStopMock threadRemovedMock;
147-
EXPECT_CALL(threadRemovedMock, threadRemoved(_)).Times(3).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
147+
StopMock stopMock;
148+
EXPECT_CALL(stopMock, threadRemoved(_)).Times(3).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
148149
ASSERT_TRUE(vm);
149150
ASSERT_FALSE(vm->atEnd());
150151
})));
151152

152-
engine->threadAboutToStop().connect(&ThreadAboutToStopMock::threadRemoved, &threadRemovedMock);
153+
engine->threadAboutToStop().connect(&StopMock::threadRemoved, &stopMock);
153154
engine->stop();
154155
}
155156

157+
TEST(EngineTest, StopSignal)
158+
{
159+
StopMock stopMock;
160+
161+
{
162+
Project p("3_threads.sb3");
163+
ASSERT_TRUE(p.load());
164+
auto engine = p.engine();
165+
166+
engine->stopped().connect(&StopMock::stopped, &stopMock);
167+
EXPECT_CALL(stopMock, stopped());
168+
engine->start();
169+
engine->step();
170+
171+
EXPECT_CALL(stopMock, stopped());
172+
engine->stop();
173+
}
174+
175+
{
176+
Project p("stop_all_bypass.sb3");
177+
ASSERT_TRUE(p.load());
178+
auto engine = p.engine();
179+
180+
engine->stopped().connect(&StopMock::stopped, &stopMock);
181+
EXPECT_CALL(stopMock, stopped());
182+
engine->start();
183+
EXPECT_CALL(stopMock, stopped());
184+
engine->step();
185+
186+
EXPECT_CALL(stopMock, stopped());
187+
engine->stop();
188+
}
189+
}
190+
156191
TEST(EngineTest, CompileAndExecuteMonitors)
157192
{
158193
Engine engine;
@@ -1894,13 +1929,13 @@ TEST(EngineTest, BroadcastsProject)
18941929

18951930
auto engine = p.engine();
18961931

1897-
ThreadAboutToStopMock threadRemovedMock;
1898-
EXPECT_CALL(threadRemovedMock, threadRemoved(_)).Times(21).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
1932+
StopMock stopMock;
1933+
EXPECT_CALL(stopMock, threadRemoved(_)).Times(21).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
18991934
ASSERT_TRUE(vm);
19001935
ASSERT_FALSE(vm->atEnd());
19011936
})));
19021937

1903-
engine->threadAboutToStop().connect(&ThreadAboutToStopMock::threadRemoved, &threadRemovedMock);
1938+
engine->threadAboutToStop().connect(&StopMock::threadRemoved, &stopMock);
19041939
engine->setFps(1000);
19051940
p.run();
19061941

@@ -1942,13 +1977,13 @@ TEST(EngineTest, StopAllBypass)
19421977

19431978
auto engine = p.engine();
19441979

1945-
ThreadAboutToStopMock threadRemovedMock;
1946-
EXPECT_CALL(threadRemovedMock, threadRemoved(_)).Times(2).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
1980+
StopMock stopMock;
1981+
EXPECT_CALL(stopMock, threadRemoved(_)).Times(2).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
19471982
ASSERT_TRUE(vm);
19481983
ASSERT_FALSE(vm->atEnd());
19491984
})));
19501985

1951-
engine->threadAboutToStop().connect(&ThreadAboutToStopMock::threadRemoved, &threadRemovedMock);
1986+
engine->threadAboutToStop().connect(&StopMock::threadRemoved, &stopMock);
19521987
p.run();
19531988

19541989
Stage *stage = engine->stage();
@@ -1970,13 +2005,13 @@ TEST(EngineTest, StopOtherScriptsInSprite)
19702005

19712006
auto engine = p.engine();
19722007

1973-
ThreadAboutToStopMock threadRemovedMock;
1974-
EXPECT_CALL(threadRemovedMock, threadRemoved(_)).Times(4).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
2008+
StopMock stopMock;
2009+
EXPECT_CALL(stopMock, threadRemoved(_)).Times(4).WillRepeatedly(WithArgs<0>(Invoke([](VirtualMachine *vm) {
19752010
ASSERT_TRUE(vm);
19762011
ASSERT_FALSE(vm->atEnd());
19772012
})));
19782013

1979-
engine->threadAboutToStop().connect(&ThreadAboutToStopMock::threadRemoved, &threadRemovedMock);
2014+
engine->threadAboutToStop().connect(&StopMock::threadRemoved, &stopMock);
19802015
p.run();
19812016

19822017
Stage *stage = engine->stage();

test/mocks/enginemock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class EngineMock : public IEngine
3434

3535
MOCK_METHOD(sigslot::signal<> &, aboutToRender, (), (override));
3636
MOCK_METHOD(sigslot::signal<VirtualMachine *> &, threadAboutToStop, (), (override));
37+
MOCK_METHOD(sigslot::signal<> &, stopped, (), (override));
3738

3839
MOCK_METHOD(bool, isRunning, (), (const, override));
3940

0 commit comments

Comments
 (0)