Skip to content

Commit 7f142b0

Browse files
committed
Add a callback for monitor removed events
1 parent 9936b16 commit 7f142b0

File tree

6 files changed

+52
-5
lines changed

6 files changed

+52
-5
lines changed

include/scratchcpp/iengine.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Script;
2424
class ITimer;
2525
class KeyEvent;
2626
class Monitor;
27+
class IMonitorHandler;
2728

2829
/*!
2930
* \brief The IEngine interface provides an API for running Scratch projects.
@@ -310,6 +311,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
310311
/*! Sets the function which is called when a monitor is added. */
311312
virtual void setAddMonitorHandler(const std::function<void(Monitor *)> &handler) = 0;
312313

314+
/*! Sets the function which is called when a monitor is removed. */
315+
virtual void setRemoveMonitorHandler(const std::function<void(Monitor *, IMonitorHandler *)> &handler) = 0;
316+
313317
/*! Returns the list of extension names. */
314318
virtual const std::vector<std::string> &extensions() const = 0;
315319

include/scratchcpp/monitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class MonitorPrivate;
1919
class LIBSCRATCHCPP_EXPORT Monitor : public Entity
2020
{
2121
public:
22+
friend class Engine;
23+
2224
enum class Mode
2325
{
2426
Default,

src/engine/internal/engine.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "blocks/standardblocks.h"
3030
#include "blocks/variableblocks.h"
3131
#include "blocks/listblocks.h"
32+
#include "scratch/monitor_p.h"
3233

3334
using namespace libscratchcpp;
3435

@@ -57,6 +58,11 @@ void Engine::clear()
5758
{
5859
stop();
5960

61+
if (m_removeMonitorHandler) {
62+
for (auto monitor : m_monitors)
63+
m_removeMonitorHandler(monitor.get(), monitor->impl->iface);
64+
}
65+
6066
m_sections.clear();
6167
m_targets.clear();
6268
m_broadcasts.clear();
@@ -1033,6 +1039,11 @@ void Engine::setAddMonitorHandler(const std::function<void(Monitor *)> &handler)
10331039
m_addMonitorHandler = handler;
10341040
}
10351041

1042+
void Engine::setRemoveMonitorHandler(const std::function<void(Monitor *, IMonitorHandler *)> &handler)
1043+
{
1044+
m_removeMonitorHandler = handler;
1045+
}
1046+
10361047
const std::vector<std::string> &Engine::extensions() const
10371048
{
10381049
return m_extensions;

src/engine/internal/engine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class Engine : public IEngine
134134
const std::vector<std::shared_ptr<Monitor>> &monitors() const override;
135135
void setMonitors(const std::vector<std::shared_ptr<Monitor>> &newMonitors) override;
136136
void setAddMonitorHandler(const std::function<void(Monitor *)> &handler) override;
137+
void setRemoveMonitorHandler(const std::function<void(Monitor *, IMonitorHandler *)> &handler) override;
137138

138139
const std::vector<std::string> &extensions() const override;
139140
void setExtensions(const std::vector<std::string> &newExtensions) override;
@@ -244,6 +245,7 @@ class Engine : public IEngine
244245
std::mutex m_stopEventLoopMutex;
245246

246247
std::function<void(Monitor *)> m_addMonitorHandler = nullptr;
248+
std::function<void(Monitor *, IMonitorHandler *)> m_removeMonitorHandler = nullptr;
247249
};
248250

249251
} // namespace libscratchcpp

test/engine/engine_test.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <clockmock.h>
1414
#include <audioplayerfactorymock.h>
1515
#include <audioplayermock.h>
16+
#include <monitorhandlermock.h>
1617
#include <thread>
1718

1819
#include "../common.h"
@@ -38,10 +39,11 @@ class RedrawMock
3839
MOCK_METHOD(void, redraw, ());
3940
};
4041

41-
class AddMonitorMock
42+
class AddRemoveMonitorMock
4243
{
4344
public:
4445
MOCK_METHOD(void, monitorAdded, (Monitor *));
46+
MOCK_METHOD(void, monitorRemoved, (Monitor *, IMonitorHandler *));
4547
};
4648

4749
TEST(EngineTest, Clock)
@@ -65,11 +67,36 @@ TEST(EngineTest, Clear)
6567
auto section = std::make_shared<TestSection>();
6668
engine.registerSection(section);
6769

70+
auto monitor1 = std::make_shared<Monitor>("", "");
71+
auto monitor2 = std::make_shared<Monitor>("", "");
72+
auto monitor3 = std::make_shared<Monitor>("", "");
73+
auto monitor4 = std::make_shared<Monitor>("", "");
74+
75+
MonitorHandlerMock iface1, iface3, iface4;
76+
EXPECT_CALL(iface1, init);
77+
EXPECT_CALL(iface3, init);
78+
EXPECT_CALL(iface4, init);
79+
monitor1->setInterface(&iface1);
80+
monitor3->setInterface(&iface3);
81+
monitor4->setInterface(&iface4);
82+
6883
engine.clear();
6984
ASSERT_TRUE(engine.targets().empty());
7085
ASSERT_TRUE(engine.broadcasts().empty());
7186
ASSERT_TRUE(engine.monitors().empty());
7287
ASSERT_TRUE(engine.registeredSections().empty());
88+
89+
AddRemoveMonitorMock removeMonitorMock;
90+
auto handler = std::bind(&AddRemoveMonitorMock::monitorRemoved, &removeMonitorMock, std::placeholders::_1, std::placeholders::_2);
91+
engine.setRemoveMonitorHandler(std::function<void(Monitor *, IMonitorHandler *)>(handler));
92+
engine.setMonitors({ monitor1, monitor2, monitor3, monitor4 });
93+
94+
EXPECT_CALL(removeMonitorMock, monitorRemoved(monitor1.get(), &iface1));
95+
EXPECT_CALL(removeMonitorMock, monitorRemoved(monitor2.get(), nullptr));
96+
EXPECT_CALL(removeMonitorMock, monitorRemoved(monitor3.get(), &iface3));
97+
EXPECT_CALL(removeMonitorMock, monitorRemoved(monitor4.get(), &iface4));
98+
engine.clear();
99+
ASSERT_TRUE(engine.monitors().empty());
73100
}
74101

75102
TEST(EngineTest, IsRunning)
@@ -1154,8 +1181,8 @@ TEST(EngineTest, Monitors)
11541181
engine.setMonitors({ m1, m2, m3 });
11551182
ASSERT_EQ(engine.monitors(), std::vector<std::shared_ptr<Monitor>>({ m1, m2, m3 }));
11561183

1157-
AddMonitorMock addMonitorMock;
1158-
auto handler = std::bind(&AddMonitorMock::monitorAdded, &addMonitorMock, std::placeholders::_1);
1184+
AddRemoveMonitorMock addMonitorMock;
1185+
auto handler = std::bind(&AddRemoveMonitorMock::monitorAdded, &addMonitorMock, std::placeholders::_1);
11591186
engine.setAddMonitorHandler(std::function<void(Monitor *)>(handler));
11601187
engine.setMonitors({});
11611188

@@ -1264,8 +1291,8 @@ TEST(EngineTest, CreateMissingMonitors)
12641291

12651292
{
12661293
Engine engine;
1267-
AddMonitorMock addMonitorMock;
1268-
auto handler = std::bind(&AddMonitorMock::monitorAdded, &addMonitorMock, std::placeholders::_1);
1294+
AddRemoveMonitorMock addMonitorMock;
1295+
auto handler = std::bind(&AddRemoveMonitorMock::monitorAdded, &addMonitorMock, std::placeholders::_1);
12691296
engine.setAddMonitorHandler(std::function<void(Monitor *)>(handler));
12701297

12711298
EXPECT_CALL(addMonitorMock, monitorAdded(m1.get()));

test/mocks/enginemock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class EngineMock : public IEngine
115115
MOCK_METHOD(const std::vector<std::shared_ptr<Monitor>> &, monitors, (), (const, override));
116116
MOCK_METHOD(void, setMonitors, (const std::vector<std::shared_ptr<Monitor>> &), (override));
117117
MOCK_METHOD(void, setAddMonitorHandler, (const std::function<void(Monitor *)> &), (override));
118+
MOCK_METHOD(void, setRemoveMonitorHandler, (const std::function<void(Monitor *, IMonitorHandler *)> &), (override));
118119

119120
MOCK_METHOD(std::vector<std::string> &, extensions, (), (const, override));
120121
MOCK_METHOD(void, setExtensions, (const std::vector<std::string> &), (override));

0 commit comments

Comments
 (0)