Skip to content

Commit 7b4141d

Browse files
committed
Add monitor name API
1 parent 5138865 commit 7b4141d

File tree

11 files changed

+80
-0
lines changed

11 files changed

+80
-0
lines changed

include/scratchcpp/global.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#define LIBSCRATCHCPP_EXPORT DECL_IMPORT
1818
#endif
1919

20+
#include <string>
21+
2022
/*! \brief The main namespace of the library. */
2123
namespace libscratchcpp
2224
{
@@ -29,6 +31,7 @@ enum class ScratchVersion
2931

3032
class VirtualMachine;
3133
class Compiler;
34+
class Block;
3235

3336
/*!
3437
* \typedef BlockFunc
@@ -44,6 +47,13 @@ using BlockFunc = unsigned int (*)(VirtualMachine *vm);
4447
*/
4548
using BlockComp = void (*)(Compiler *);
4649

50+
/*!
51+
* \typedef MonitorNameFunc
52+
*
53+
* MonitorNameFunc is a function pointer for functions which are used to get monitor names.
54+
*/
55+
using MonitorNameFunc = const std::string &(*)(Block *);
56+
4757
} // namespace libscratchcpp
4858

4959
#endif // LIBSCRATCHCPP_GLOBAL_H

include/scratchcpp/iengine.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,12 @@ class LIBSCRATCHCPP_EXPORT IEngine
217217
*/
218218
virtual void addCompileFunction(IBlockSection *section, const std::string &opcode, BlockComp f) = 0;
219219

220+
/*!
221+
* Call this from IBlockSection#registerBlocks() to add a monitor name function to a block section.
222+
* \see <a href="blockSections.html">Block sections</a>
223+
*/
224+
virtual void addMonitorNameFunction(IBlockSection *section, const std::string &opcode, MonitorNameFunc f) = 0;
225+
220226
/*!
221227
* Call this from IBlockSection#registerBlocks() to add a hat block to a block section.
222228
* \see <a href="blockSections.html">Block sections</a>

include/scratchcpp/monitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class LIBSCRATCHCPP_EXPORT Monitor : public Entity
3737

3838
void setInterface(IMonitorHandler *iface);
3939

40+
const std::string &name() const;
41+
4042
Mode mode() const;
4143
void setMode(Mode mode);
4244

src/engine/internal/blocksectioncontainer.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ void BlockSectionContainer::addCompileFunction(const std::string &opcode, BlockC
1111
m_compileFunctions[opcode] = f;
1212
}
1313

14+
void BlockSectionContainer::addMonitorNameFunction(const std::string &opcode, MonitorNameFunc f)
15+
{
16+
m_monitorNameFunctions[opcode] = f;
17+
}
18+
1419
void BlockSectionContainer::addHatBlock(const std::string &opcode)
1520
{
1621
m_compileFunctions[opcode] = &dummyFunction;
@@ -38,6 +43,13 @@ BlockComp BlockSectionContainer::resolveBlockCompileFunc(const std::string &opco
3843
return nullptr;
3944
}
4045

46+
MonitorNameFunc BlockSectionContainer::resolveMonitorNameFunc(const std::string &opcode) const
47+
{
48+
if (m_monitorNameFunctions.count(opcode) == 1)
49+
return m_monitorNameFunctions.at(opcode);
50+
return nullptr;
51+
}
52+
4153
int BlockSectionContainer::resolveInput(const std::string &name) const
4254
{
4355
if (m_inputs.count(name) == 1)

src/engine/internal/blocksectioncontainer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,21 @@ class BlockSectionContainer
1616
BlockSectionContainer(const BlockSectionContainer &) = delete;
1717

1818
void addCompileFunction(const std::string &opcode, BlockComp f);
19+
void addMonitorNameFunction(const std::string &opcode, MonitorNameFunc f);
1920
void addHatBlock(const std::string &opcode);
2021
void addInput(const std::string &name, int id);
2122
void addField(const std::string &name, int id);
2223
void addFieldValue(const std::string &value, int id);
2324

2425
BlockComp resolveBlockCompileFunc(const std::string &opcode) const;
26+
MonitorNameFunc resolveMonitorNameFunc(const std::string &opcode) const;
2527
int resolveInput(const std::string &name) const;
2628
int resolveField(const std::string &name) const;
2729
int resolveFieldValue(const std::string &value) const;
2830

2931
private:
3032
std::unordered_map<std::string, BlockComp> m_compileFunctions;
33+
std::unordered_map<std::string, MonitorNameFunc> m_monitorNameFunctions;
3134
std::unordered_map<std::string, int> m_inputs;
3235
std::unordered_map<std::string, int> m_fields;
3336
std::unordered_map<std::string, int> m_fieldValues;

src/engine/internal/engine.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,14 @@ void Engine::compile()
226226
Compiler compiler(this, target);
227227
auto block = monitor->block();
228228
auto section = blockSection(block->opcode());
229+
auto container = blockSectionContainer(block->opcode());
230+
231+
if (container) {
232+
MonitorNameFunc f = container->resolveMonitorNameFunc(block->opcode());
233+
234+
if (f)
235+
monitor->impl->name = f(block.get());
236+
}
229237

230238
if (section) {
231239
auto script = std::make_shared<Script>(target, block, this);
@@ -804,6 +812,14 @@ void Engine::addCompileFunction(IBlockSection *section, const std::string &opcod
804812
container->addCompileFunction(opcode, f);
805813
}
806814

815+
void Engine::addMonitorNameFunction(IBlockSection *section, const std::string &opcode, MonitorNameFunc f)
816+
{
817+
auto container = blockSectionContainer(section);
818+
819+
if (container)
820+
container->addMonitorNameFunction(opcode, f);
821+
}
822+
807823
void Engine::addHatBlock(IBlockSection *section, const std::string &opcode)
808824
{
809825
auto container = blockSectionContainer(section);
@@ -1439,6 +1455,14 @@ void Engine::addVarOrListMonitor(std::shared_ptr<Monitor> monitor, Target *targe
14391455
monitor->setSprite(dynamic_cast<Sprite *>(target));
14401456

14411457
monitor->impl->blockSection = blockSection(monitor->opcode());
1458+
auto container = blockSectionContainer(monitor->opcode());
1459+
1460+
if (container) {
1461+
MonitorNameFunc f = container->resolveMonitorNameFunc(monitor->opcode());
1462+
1463+
if (f)
1464+
monitor->impl->name = f(monitor->block().get());
1465+
}
14421466

14431467
// Auto-position the monitor
14441468
Rect rect = Monitor::getInitialPosition(m_monitors, monitor->width(), monitor->height());

src/engine/internal/engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class Engine : public IEngine
102102
unsigned int functionIndex(BlockFunc f) override;
103103

104104
void addCompileFunction(IBlockSection *section, const std::string &opcode, BlockComp f) override;
105+
void addMonitorNameFunction(IBlockSection *section, const std::string &opcode, MonitorNameFunc f) override;
105106
void addHatBlock(IBlockSection *section, const std::string &opcode) override;
106107
void addInput(IBlockSection *section, const std::string &name, int id) override;
107108
void addField(IBlockSection *section, const std::string &name, int id) override;

src/scratch/monitor.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ void Monitor::setInterface(IMonitorHandler *iface)
3232
iface->init(this);
3333
}
3434

35+
/*
36+
* Returns the name of this monitor.
37+
* \note Add the monitor to a project to initialize this property.
38+
*/
39+
const std::string &Monitor::name() const
40+
{
41+
return impl->name;
42+
}
43+
3544
/*! Returns the monitor's mode. */
3645
Monitor::Mode Monitor::mode() const
3746
{

src/scratch/monitor_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ struct MonitorPrivate
1717
MonitorPrivate(const MonitorPrivate &) = delete;
1818

1919
IMonitorHandler *iface = nullptr;
20+
std::string name;
2021
Monitor::Mode mode = Monitor::Mode::Default;
2122
std::shared_ptr<Script> script;
2223
std::shared_ptr<IBlockSection> blockSection;

test/engine/engine_test.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ TEST(EngineTest, CompileAndExecuteMonitors)
123123
engine.addCompileFunction(section.get(), m1->opcode(), [](Compiler *compiler) { compiler->addConstValue(5.4); });
124124
engine.addCompileFunction(section.get(), m2->opcode(), [](Compiler *compiler) { compiler->addConstValue("test"); });
125125

126+
engine.addMonitorNameFunction(section.get(), m1->opcode(), [](Block *block) -> const std::string & {
127+
static const std::string testStr = "test";
128+
return testStr;
129+
});
130+
131+
engine.addMonitorNameFunction(section.get(), m2->opcode(), [](Block *block) -> const std::string & { return block->opcode(); });
132+
126133
// Compile the monitor blocks
127134
engine.compile();
128135
auto script1 = m1->script();
@@ -142,6 +149,10 @@ TEST(EngineTest, CompileAndExecuteMonitors)
142149
ASSERT_EQ(m2->blockSection(), section);
143150
ASSERT_FALSE(m3->blockSection());
144151

152+
ASSERT_EQ(m1->name(), "test");
153+
ASSERT_EQ(m2->name(), m2->opcode());
154+
ASSERT_TRUE(m3->name().empty());
155+
145156
// Execute the monitor blocks
146157
MonitorHandlerMock iface1, iface2, iface3;
147158
EXPECT_CALL(iface1, init);

0 commit comments

Comments
 (0)