Skip to content

Commit 23b8a95

Browse files
authored
Merge pull request #514 from scratchcpp/block_section_init
Add onInit() method to IBlockSection
2 parents 279cd24 + 3fd4cc9 commit 23b8a95

File tree

9 files changed

+179
-53
lines changed

9 files changed

+179
-53
lines changed

include/scratchcpp/iblocksection.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ class LIBSCRATCHCPP_EXPORT IBlockSection
3636

3737
/*! Override this method to register blocks. */
3838
virtual void registerBlocks(IEngine *engine) = 0;
39+
40+
/*! This method is called when a project is loaded. */
41+
virtual void onInit(IEngine *engine) { }
3942
};
4043

4144
} // namespace libscratchcpp

src/blocks/soundblocks.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ void SoundBlocks::registerBlocks(IEngine *engine)
3333
engine->addInput(this, "VOLUME", VOLUME);
3434
}
3535

36+
void SoundBlocks::onInit(IEngine *engine)
37+
{
38+
m_waitingSounds.clear();
39+
// TODO: Remove stopped threads from m_waitingSounds
40+
}
41+
3642
bool SoundBlocks::compilePlayCommon(Compiler *compiler, bool untilDone, bool *byIndex)
3743
{
3844
Target *target = compiler->target();

src/blocks/soundblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class SoundBlocks : public IBlockSection
3636
std::string name() const override;
3737

3838
void registerBlocks(IEngine *engine) override;
39+
void onInit(IEngine *engine) override;
3940

4041
static bool compilePlayCommon(Compiler *compiler, bool untilDone, bool *byIndex = nullptr);
4142
static void compilePlay(Compiler *compiler);

src/engine/internal/engine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ void Engine::registerSection(std::shared_ptr<IBlockSection> section)
864864

865865
m_sections[section] = std::make_unique<BlockSectionContainer>();
866866
section->registerBlocks(this);
867+
section->onInit(this);
867868
}
868869
}
869870

test/engine/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
add_executable(
22
engine_test
33
engine_test.cpp
4-
testsection.cpp
5-
testsection.h
64
)
75

86
target_link_libraries(

test/engine/engine_test.cpp

Lines changed: 152 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
#include <audiooutputmock.h>
1818
#include <audioplayermock.h>
1919
#include <monitorhandlermock.h>
20+
#include <blocksectionmock.h>
2021
#include <thread>
2122

2223
#include "../common.h"
23-
#include "testsection.h"
2424
#include "engine/internal/engine.h"
2525
#include "engine/internal/clock.h"
2626

@@ -77,7 +77,9 @@ TEST(EngineTest, Clear)
7777
auto broadcast2 = std::make_shared<Broadcast>("", "");
7878
engine.setBroadcasts({ broadcast1, broadcast2 });
7979

80-
auto section = std::make_shared<TestSection>();
80+
auto section = std::make_shared<BlockSectionMock>();
81+
EXPECT_CALL(*section, registerBlocks);
82+
EXPECT_CALL(*section, onInit);
8183
engine.registerSection(section);
8284

8385
auto monitor1 = std::make_shared<Monitor>("", "");
@@ -126,7 +128,9 @@ TEST(EngineTest, CompileAndExecuteMonitors)
126128
m2->setSprite(sprite.get());
127129
engine.setMonitors({ m1, m2 });
128130

129-
auto section = std::make_shared<TestSection>();
131+
auto section = std::make_shared<BlockSectionMock>();
132+
EXPECT_CALL(*section, registerBlocks);
133+
EXPECT_CALL(*section, onInit);
130134
engine.registerSection(section);
131135
engine.addCompileFunction(section.get(), m1->opcode(), [](Compiler *compiler) { compiler->addConstValue(5.4); });
132136
engine.addCompileFunction(section.get(), m2->opcode(), [](Compiler *compiler) { compiler->addConstValue("test"); });
@@ -859,12 +863,19 @@ TEST(EngineTest, Sections)
859863
{
860864
Engine engine;
861865

862-
auto section1 = std::make_shared<TestSection>();
866+
auto section1 = std::make_shared<BlockSectionMock>();
867+
EXPECT_CALL(*section1, registerBlocks(&engine));
868+
EXPECT_CALL(*section1, onInit(&engine));
863869
engine.registerSection(section1);
864870

865-
auto section2 = std::make_shared<TestSection>();
871+
auto section2 = std::make_shared<BlockSectionMock>();
872+
EXPECT_CALL(*section2, registerBlocks(&engine));
873+
EXPECT_CALL(*section2, onInit(&engine));
866874
engine.registerSection(section2);
867875

876+
EXPECT_CALL(*section1, name()).WillOnce(Return("test"));
877+
EXPECT_CALL(*section1, registerBlocks).Times(0);
878+
EXPECT_CALL(*section1, onInit).Times(0);
868879
engine.registerSection(section1); // register existing section
869880

870881
ASSERT_EQ(engine.registeredSections().size(), 2);
@@ -908,15 +919,19 @@ TEST(EngineTest, CompileFunctions)
908919
{
909920
Engine engine;
910921

911-
auto section1 = std::make_shared<TestSection>();
922+
auto section1 = std::make_shared<BlockSectionMock>();
923+
EXPECT_CALL(*section1, registerBlocks);
924+
EXPECT_CALL(*section1, onInit);
912925
engine.registerSection(section1);
913926
auto container1 = engine.blockSectionContainer(section1.get());
914927

915-
auto section2 = std::make_shared<TestSection>();
928+
auto section2 = std::make_shared<BlockSectionMock>();
929+
EXPECT_CALL(*section2, registerBlocks);
930+
EXPECT_CALL(*section2, onInit);
916931
engine.registerSection(section2);
917932
auto container2 = engine.blockSectionContainer(section2.get());
918933

919-
TestSection section3;
934+
BlockSectionMock section3;
920935

921936
engine.addCompileFunction(section1.get(), "test1", &compileTest1);
922937
engine.addCompileFunction(section2.get(), "test2", &compileTest2);
@@ -929,19 +944,123 @@ TEST(EngineTest, CompileFunctions)
929944
ASSERT_EQ(container2->resolveBlockCompileFunc("test2"), &compileTest2);
930945
}
931946

947+
TEST(EngineTest, HatPredicateCompileFunctions)
948+
{
949+
Engine engine;
950+
951+
auto section1 = std::make_shared<BlockSectionMock>();
952+
EXPECT_CALL(*section1, registerBlocks);
953+
EXPECT_CALL(*section1, onInit);
954+
engine.registerSection(section1);
955+
auto container1 = engine.blockSectionContainer(section1.get());
956+
957+
auto section2 = std::make_shared<BlockSectionMock>();
958+
EXPECT_CALL(*section2, registerBlocks);
959+
EXPECT_CALL(*section2, onInit);
960+
engine.registerSection(section2);
961+
auto container2 = engine.blockSectionContainer(section2.get());
962+
963+
BlockSectionMock section3;
964+
965+
engine.addHatPredicateCompileFunction(section1.get(), "test1", &compileTest1);
966+
engine.addHatPredicateCompileFunction(section2.get(), "test2", &compileTest2);
967+
engine.addHatPredicateCompileFunction(section1.get(), "test1", &compileTest1);
968+
engine.addHatPredicateCompileFunction(&section3, "test1", &compileTest1);
969+
970+
ASSERT_EQ(container1->resolveHatPredicateCompileFunc("test1"), &compileTest1);
971+
ASSERT_EQ(container1->resolveHatPredicateCompileFunc("test2"), nullptr);
972+
ASSERT_EQ(container2->resolveHatPredicateCompileFunc("test1"), nullptr);
973+
ASSERT_EQ(container2->resolveHatPredicateCompileFunc("test2"), &compileTest2);
974+
}
975+
976+
TEST(EngineTest, MonitorNameFunctions)
977+
{
978+
Engine engine;
979+
980+
auto section1 = std::make_shared<BlockSectionMock>();
981+
EXPECT_CALL(*section1, registerBlocks);
982+
EXPECT_CALL(*section1, onInit);
983+
engine.registerSection(section1);
984+
auto container1 = engine.blockSectionContainer(section1.get());
985+
986+
auto section2 = std::make_shared<BlockSectionMock>();
987+
EXPECT_CALL(*section2, registerBlocks);
988+
EXPECT_CALL(*section2, onInit);
989+
engine.registerSection(section2);
990+
auto container2 = engine.blockSectionContainer(section2.get());
991+
992+
BlockSectionMock section3;
993+
994+
MonitorNameFunc f1 = [](Block *) -> const std::string & {
995+
static const std::string ret;
996+
return ret;
997+
};
998+
999+
MonitorNameFunc f2 = [](Block *) -> const std::string & {
1000+
static const std::string ret;
1001+
return ret;
1002+
};
1003+
1004+
engine.addMonitorNameFunction(section1.get(), "test1", f1);
1005+
engine.addMonitorNameFunction(section2.get(), "test2", f2);
1006+
engine.addMonitorNameFunction(section1.get(), "test1", f1);
1007+
engine.addMonitorNameFunction(&section3, "test1", f1);
1008+
1009+
ASSERT_EQ(container1->resolveMonitorNameFunc("test1"), f1);
1010+
ASSERT_EQ(container1->resolveMonitorNameFunc("test2"), nullptr);
1011+
ASSERT_EQ(container2->resolveMonitorNameFunc("test1"), nullptr);
1012+
ASSERT_EQ(container2->resolveMonitorNameFunc("test2"), f2);
1013+
}
1014+
1015+
TEST(EngineTest, MonitorChangeFunctions)
1016+
{
1017+
Engine engine;
1018+
1019+
auto section1 = std::make_shared<BlockSectionMock>();
1020+
EXPECT_CALL(*section1, registerBlocks);
1021+
EXPECT_CALL(*section1, onInit);
1022+
engine.registerSection(section1);
1023+
auto container1 = engine.blockSectionContainer(section1.get());
1024+
1025+
auto section2 = std::make_shared<BlockSectionMock>();
1026+
EXPECT_CALL(*section2, registerBlocks);
1027+
EXPECT_CALL(*section2, onInit);
1028+
engine.registerSection(section2);
1029+
auto container2 = engine.blockSectionContainer(section2.get());
1030+
1031+
BlockSectionMock section3;
1032+
1033+
MonitorChangeFunc f1 = [](Block *, const Value &) {};
1034+
MonitorChangeFunc f2 = [](Block *, const Value &) {};
1035+
1036+
engine.addMonitorChangeFunction(section1.get(), "test1", f1);
1037+
engine.addMonitorChangeFunction(section2.get(), "test2", f2);
1038+
engine.addMonitorChangeFunction(section1.get(), "test1", f1);
1039+
engine.addMonitorChangeFunction(&section3, "test1", f1);
1040+
1041+
ASSERT_EQ(container1->resolveMonitorChangeFunc("test1"), f1);
1042+
ASSERT_EQ(container1->resolveMonitorChangeFunc("test2"), nullptr);
1043+
ASSERT_EQ(container2->resolveMonitorChangeFunc("test1"), nullptr);
1044+
ASSERT_EQ(container2->resolveMonitorChangeFunc("test2"), f2);
1045+
}
1046+
9321047
TEST(EngineTest, HatBlocks)
9331048
{
9341049
Engine engine;
9351050

936-
auto section1 = std::make_shared<TestSection>();
1051+
auto section1 = std::make_shared<BlockSectionMock>();
1052+
EXPECT_CALL(*section1, registerBlocks);
1053+
EXPECT_CALL(*section1, onInit);
9371054
engine.registerSection(section1);
9381055
auto container1 = engine.blockSectionContainer(section1.get());
9391056

940-
auto section2 = std::make_shared<TestSection>();
1057+
auto section2 = std::make_shared<BlockSectionMock>();
1058+
EXPECT_CALL(*section2, registerBlocks);
1059+
EXPECT_CALL(*section2, onInit);
9411060
engine.registerSection(section2);
9421061
auto container2 = engine.blockSectionContainer(section2.get());
9431062

944-
TestSection section3;
1063+
BlockSectionMock section3;
9451064

9461065
engine.addHatBlock(section1.get(), "test1");
9471066
engine.addHatBlock(section2.get(), "test2");
@@ -958,15 +1077,19 @@ TEST(EngineTest, Inputs)
9581077
{
9591078
Engine engine;
9601079

961-
auto section1 = std::make_shared<TestSection>();
1080+
auto section1 = std::make_shared<BlockSectionMock>();
1081+
EXPECT_CALL(*section1, registerBlocks);
1082+
EXPECT_CALL(*section1, onInit);
9621083
engine.registerSection(section1);
9631084
auto container1 = engine.blockSectionContainer(section1.get());
9641085

965-
auto section2 = std::make_shared<TestSection>();
1086+
auto section2 = std::make_shared<BlockSectionMock>();
1087+
EXPECT_CALL(*section2, registerBlocks);
1088+
EXPECT_CALL(*section2, onInit);
9661089
engine.registerSection(section2);
9671090
auto container2 = engine.blockSectionContainer(section2.get());
9681091

969-
TestSection section3;
1092+
BlockSectionMock section3;
9701093

9711094
engine.addInput(section1.get(), "VALUE1", 1);
9721095
engine.addInput(section2.get(), "VALUE2", 2);
@@ -985,15 +1108,19 @@ TEST(EngineTest, Fields)
9851108
{
9861109
Engine engine;
9871110

988-
auto section1 = std::make_shared<TestSection>();
1111+
auto section1 = std::make_shared<BlockSectionMock>();
1112+
EXPECT_CALL(*section1, registerBlocks);
1113+
EXPECT_CALL(*section1, onInit);
9891114
engine.registerSection(section1);
9901115
auto container1 = engine.blockSectionContainer(section1.get());
9911116

992-
auto section2 = std::make_shared<TestSection>();
1117+
auto section2 = std::make_shared<BlockSectionMock>();
1118+
EXPECT_CALL(*section2, registerBlocks);
1119+
EXPECT_CALL(*section2, onInit);
9931120
engine.registerSection(section2);
9941121
auto container2 = engine.blockSectionContainer(section2.get());
9951122

996-
TestSection section3;
1123+
BlockSectionMock section3;
9971124

9981125
engine.addField(section1.get(), "VALUE1", 1);
9991126
engine.addField(section2.get(), "VALUE2", 2);
@@ -1012,19 +1139,23 @@ TEST(EngineTest, FieldValues)
10121139
{
10131140
Engine engine;
10141141

1015-
auto section1 = std::make_shared<TestSection>();
1142+
auto section1 = std::make_shared<BlockSectionMock>();
1143+
EXPECT_CALL(*section1, registerBlocks);
1144+
EXPECT_CALL(*section1, onInit);
10161145
engine.registerSection(section1);
10171146
auto container1 = engine.blockSectionContainer(section1.get());
10181147

1019-
auto section2 = std::make_shared<TestSection>();
1148+
auto section2 = std::make_shared<BlockSectionMock>();
1149+
EXPECT_CALL(*section2, registerBlocks);
1150+
EXPECT_CALL(*section2, onInit);
10201151
engine.registerSection(section2);
10211152
auto container2 = engine.blockSectionContainer(section2.get());
10221153

1023-
TestSection section3;
1154+
BlockSectionMock section3;
10241155

10251156
engine.addFieldValue(section1.get(), "value1", 1);
10261157
engine.addFieldValue(section2.get(), "value2", 2);
1027-
engine.addFieldValue(section1.get(), "value1", 3); // change ID of existing field
1158+
engine.addFieldValue(section1.get(), "value1", 3); // change ID of existing field value
10281159
engine.addFieldValue(&section3, "value3", 4);
10291160

10301161
ASSERT_EQ(container1->resolveFieldValue("value1"), 3);

test/engine/testsection.cpp

Lines changed: 0 additions & 14 deletions
This file was deleted.

test/engine/testsection.h

Lines changed: 0 additions & 16 deletions
This file was deleted.

test/mocks/blocksectionmock.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <scratchcpp/iblocksection.h>
4+
#include <gmock/gmock.h>
5+
6+
using namespace libscratchcpp;
7+
8+
class BlockSectionMock : public IBlockSection
9+
{
10+
public:
11+
MOCK_METHOD(std::string, name, (), (const, override));
12+
MOCK_METHOD(bool, categoryVisible, (), (const, override));
13+
14+
MOCK_METHOD(void, registerBlocks, (IEngine *), (override));
15+
MOCK_METHOD(void, onInit, (IEngine *), (override));
16+
};

0 commit comments

Comments
 (0)