Skip to content

Commit f1461c0

Browse files
committed
Add stopEventLoop method to IEngine
1 parent f75a571 commit f1461c0

File tree

5 files changed

+39
-0
lines changed

5 files changed

+39
-0
lines changed

include/scratchcpp/iengine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
9191
*/
9292
virtual void runEventLoop() = 0;
9393

94+
/*! Stops the event loop which is running in another thread. */
95+
virtual void stopEventLoop() = 0;
96+
9497
/*! Sets the function which is called on every frame. */
9598
virtual void setRedrawHandler(const std::function<void()> &handler) = 0;
9699

src/engine/internal/engine.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,13 @@ void Engine::runEventLoop()
322322
eventLoop();
323323
}
324324

325+
void Engine::stopEventLoop()
326+
{
327+
m_stopEventLoopMutex.lock();
328+
m_stopEventLoop = true;
329+
m_stopEventLoopMutex.unlock();
330+
}
331+
325332
void Engine::setRedrawHandler(const std::function<void()> &handler)
326333
{
327334
m_redrawHandler = handler;
@@ -331,6 +338,7 @@ void Engine::eventLoop(bool untilProjectStops)
331338
{
332339
updateFrameDuration();
333340
m_newScripts.clear();
341+
m_stopEventLoop = false;
334342

335343
while (true) {
336344
auto frameStart = m_clock->currentSteadyTime();
@@ -369,6 +377,16 @@ void Engine::eventLoop(bool untilProjectStops)
369377
}
370378
}
371379

380+
// Stop the event loop if stopEventLoop() was called
381+
m_stopEventLoopMutex.lock();
382+
383+
if (m_stopEventLoop) {
384+
stop = true;
385+
break;
386+
}
387+
388+
m_stopEventLoopMutex.unlock();
389+
372390
currentTime = m_clock->currentSteadyTime();
373391
elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - frameStart);
374392
sleepTime = m_frameDuration - elapsedTime;

src/engine/internal/engine.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <unordered_map>
99
#include <memory>
1010
#include <chrono>
11+
#include <mutex>
1112

1213
#include "blocksectioncontainer.h"
1314

@@ -37,8 +38,10 @@ class Engine : public IEngine
3738
void stopTarget(Target *target, VirtualMachine *exceptScript) override;
3839
void initClone(libscratchcpp::Sprite *clone) override;
3940
void deinitClone(libscratchcpp::Sprite *clone) override;
41+
4042
void run() override;
4143
void runEventLoop() override;
44+
void stopEventLoop() override;
4245

4346
void setRedrawHandler(const std::function<void()> &handler) override;
4447

@@ -183,6 +186,8 @@ class Engine : public IEngine
183186
bool m_running = false;
184187
bool m_redrawRequested = false;
185188
std::function<void()> m_redrawHandler = nullptr;
189+
bool m_stopEventLoop = false;
190+
std::mutex m_stopEventLoopMutex;
186191
};
187192

188193
} // namespace libscratchcpp

test/engine/engine_test.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <scratchcpp/list.h>
88
#include <timermock.h>
99
#include <clockmock.h>
10+
#include <thread>
1011

1112
#include "../common.h"
1213
#include "testsection.h"
@@ -68,6 +69,16 @@ TEST(EngineTest, IsRunning)
6869
ASSERT_FALSE(engine.isRunning());
6970
}
7071

72+
TEST(EngineTest, EventLoop)
73+
{
74+
Engine engine;
75+
76+
std::thread th([&engine]() { engine.runEventLoop(); });
77+
std::this_thread::sleep_for(std::chrono::milliseconds(100));
78+
engine.stopEventLoop();
79+
th.join(); // should return immediately
80+
}
81+
7182
TEST(EngineTest, Fps)
7283
{
7384
Engine engine;

test/mocks/enginemock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ class EngineMock : public IEngine
2323
MOCK_METHOD(void, stopTarget, (Target *, VirtualMachine *), (override));
2424
MOCK_METHOD(void, initClone, (Sprite *), (override));
2525
MOCK_METHOD(void, deinitClone, (Sprite *), (override));
26+
2627
MOCK_METHOD(void, run, (), (override));
2728
MOCK_METHOD(void, runEventLoop, (), (override));
29+
MOCK_METHOD(void, stopEventLoop, (), (override));
2830

2931
MOCK_METHOD(void, setRedrawHandler, (const std::function<void()> &), (override));
3032

0 commit comments

Comments
 (0)