Skip to content

Commit 87b1b34

Browse files
committed
Add green flag script map to Engine
1 parent ce0ecbb commit 87b1b34

File tree

7 files changed

+41
-17
lines changed

7 files changed

+41
-17
lines changed

include/scratchcpp/iengine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
245245
/*! Returns the index of the broadcast with the given ID. */
246246
virtual int findBroadcastById(const std::string &broadcastId) const = 0;
247247

248+
/*! Registers the "green flag" script. */
249+
virtual void addGreenFlagScript(std::shared_ptr<Block> hatBlock) = 0;
250+
248251
/*! Registers the broadcast script. */
249252
virtual void addBroadcastScript(std::shared_ptr<Block> whenReceivedBlock, Broadcast *broadcast) = 0;
250253

src/blocks/eventblocks.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ std::string EventBlocks::name() const
2121
void EventBlocks::registerBlocks(IEngine *engine)
2222
{
2323
// Blocks
24-
engine->addHatBlock(this, "event_whenflagclicked");
24+
engine->addCompileFunction(this, "event_whenflagclicked", &compileWhenFlagClicked);
2525
engine->addCompileFunction(this, "event_broadcast", &compileBroadcast);
2626
engine->addCompileFunction(this, "event_broadcastandwait", &compileBroadcastAndWait);
2727
engine->addCompileFunction(this, "event_whenbroadcastreceived", &compileWhenBroadcastReceived);
@@ -37,6 +37,11 @@ void EventBlocks::registerBlocks(IEngine *engine)
3737
engine->addField(this, "KEY_OPTION", KEY_OPTION);
3838
}
3939

40+
void EventBlocks::compileWhenFlagClicked(Compiler *compiler)
41+
{
42+
compiler->engine()->addGreenFlagScript(compiler->block());
43+
}
44+
4045
void EventBlocks::compileBroadcast(Compiler *compiler)
4146
{
4247
auto input = compiler->input(BROADCAST_INPUT);

src/blocks/eventblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class EventBlocks : public IBlockSection
3030

3131
void registerBlocks(IEngine *engine) override;
3232

33+
static void compileWhenFlagClicked(Compiler *compiler);
3334
static void compileBroadcast(Compiler *compiler);
3435
static void compileBroadcastAndWait(Compiler *compiler);
3536
static void compileWhenBroadcastReceived(Compiler *compiler);

src/engine/internal/engine.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,11 @@ int Engine::findBroadcastById(const std::string &broadcastId) const
737737
return -1;
738738
}
739739

740+
void Engine::addGreenFlagScript(std::shared_ptr<Block> hatBlock)
741+
{
742+
addHatToMap(m_greenFlagHats, m_scripts[hatBlock].get());
743+
}
744+
740745
void Engine::addBroadcastScript(std::shared_ptr<Block> whenReceivedBlock, Broadcast *broadcast)
741746
{
742747
assert(!broadcast->isBackdropBroadcast());
@@ -1087,21 +1092,8 @@ std::vector<Script *> Engine::getHats(Target *target, HatType type)
10871092
}
10881093

10891094
switch (type) {
1090-
case HatType::GreenFlag: {
1091-
// TODO: Add a map for green flag hats and return reference
1092-
std::vector<Script *> out;
1093-
const auto &blocks = target->blocks();
1094-
1095-
for (auto block : blocks) {
1096-
if (block->opcode() == "event_whenflagclicked") {
1097-
assert(block->topLevel());
1098-
assert(m_scripts.find(block) != m_scripts.cend());
1099-
out.push_back(m_scripts[block].get());
1100-
}
1101-
}
1102-
1103-
return out;
1104-
}
1095+
case HatType::GreenFlag:
1096+
return m_greenFlagHats[target];
11051097

11061098
case HatType::BroadcastReceived:
11071099
return m_broadcastHats[target];

src/engine/internal/engine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class Engine : public IEngine
109109
int findBroadcast(const std::string &broadcastName) const override;
110110
int findBroadcastById(const std::string &broadcastId) const override;
111111

112+
void addGreenFlagScript(std::shared_ptr<Block> hatBlock) override;
112113
void addBroadcastScript(std::shared_ptr<Block> whenReceivedBlock, Broadcast *broadcast) override;
113114
void addCloneInitScript(std::shared_ptr<Block> hatBlock) override;
114115
void addKeyPressScript(std::shared_ptr<Block> hatBlock, std::string keyName) override;
@@ -193,6 +194,7 @@ class Engine : public IEngine
193194
std::vector<BlockFunc> m_functions;
194195
std::recursive_mutex m_eventLoopMutex;
195196

197+
std::unordered_map<Target *, std::vector<Script *>> m_greenFlagHats;
196198
std::unordered_map<Target *, std::vector<Script *>> m_broadcastHats;
197199
std::unordered_map<Target *, std::vector<Script *>> m_cloneInitHats;
198200
std::unordered_map<Target *, std::vector<Script *>> m_whenKeyPressedHats;

test/blocks/event_blocks_test.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ TEST_F(EventBlocksTest, CategoryVisible)
8383
TEST_F(EventBlocksTest, RegisterBlocks)
8484
{
8585
// Blocks
86-
EXPECT_CALL(m_engineMock, addHatBlock(m_section.get(), "event_whenflagclicked"));
86+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_whenflagclicked", &EventBlocks::compileWhenFlagClicked));
8787
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_broadcast", &EventBlocks::compileBroadcast));
8888
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_broadcastandwait", &EventBlocks::compileBroadcastAndWait));
8989
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_whenbroadcastreceived", &EventBlocks::compileWhenBroadcastReceived));
@@ -101,6 +101,26 @@ TEST_F(EventBlocksTest, RegisterBlocks)
101101
m_section->registerBlocks(&m_engineMock);
102102
}
103103

104+
TEST_F(EventBlocksTest, WhenFlagClicked)
105+
{
106+
Compiler compiler(&m_engineMock);
107+
108+
auto block = createEventBlock("a", "event_whenflagclicked");
109+
110+
compiler.init();
111+
112+
EXPECT_CALL(m_engineMock, addGreenFlagScript(block));
113+
compiler.setBlock(block);
114+
EventBlocks::compileWhenFlagClicked(&compiler);
115+
116+
compiler.end();
117+
118+
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_HALT }));
119+
ASSERT_TRUE(compiler.constValues().empty());
120+
ASSERT_TRUE(compiler.variables().empty());
121+
ASSERT_TRUE(compiler.lists().empty());
122+
}
123+
104124
TEST_F(EventBlocksTest, Broadcast)
105125
{
106126
Compiler compiler(&m_engineMock);

test/mocks/enginemock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class EngineMock : public IEngine
9191
MOCK_METHOD(int, findBroadcast, (const std::string &), (const, override));
9292
MOCK_METHOD(int, findBroadcastById, (const std::string &), (const, override));
9393

94+
MOCK_METHOD(void, addGreenFlagScript, (std::shared_ptr<Block>), (override));
9495
MOCK_METHOD(void, addBroadcastScript, (std::shared_ptr<Block>, Broadcast *), (override));
9596
MOCK_METHOD(void, addCloneInitScript, (std::shared_ptr<Block>), (override));
9697
MOCK_METHOD(void, addKeyPressScript, (std::shared_ptr<Block>, std::string), (override));

0 commit comments

Comments
 (0)