Skip to content

Commit 6af2b4d

Browse files
committed
Implement data_hidelist block
1 parent 6cd46a7 commit 6af2b4d

File tree

3 files changed

+236
-0
lines changed

3 files changed

+236
-0
lines changed

src/blocks/listblocks.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ void ListBlocks::registerBlocks(IEngine *engine)
4242
engine->addCompileFunction(this, "data_lengthoflist", &compileLengthOfList);
4343
engine->addCompileFunction(this, "data_listcontainsitem", &compileListContainsItem);
4444
engine->addCompileFunction(this, "data_showlist", &compileShowList);
45+
engine->addCompileFunction(this, "data_hidelist", &compileHideList);
4546

4647
// Monitor names
4748
engine->addMonitorNameFunction(this, "data_listcontents", &listContentsMonitorName);
@@ -229,6 +230,19 @@ CompilerValue *ListBlocks::compileShowList(Compiler *compiler)
229230
return nullptr;
230231
}
231232

233+
CompilerValue *ListBlocks::compileHideList(Compiler *compiler)
234+
{
235+
Field *field = compiler->field("LIST");
236+
assert(field);
237+
List *list = static_cast<List *>(field->valuePtr().get());
238+
assert(list);
239+
240+
CompilerConstant *listPtr = compiler->addConstValue(list);
241+
compiler->addTargetFunctionCall("data_hidelist", Compiler::StaticType::Void, { Compiler::StaticType::Pointer }, { listPtr });
242+
243+
return nullptr;
244+
}
245+
232246
const std::string &ListBlocks::listContentsMonitorName(Block *block)
233247
{
234248
static const std::string empty = "";
@@ -261,3 +275,11 @@ extern "C" void data_showlist(Target *target, List *list)
261275

262276
monitor->setVisible(true);
263277
}
278+
279+
extern "C" void data_hidelist(Target *target, List *list)
280+
{
281+
Monitor *monitor = list->monitor();
282+
283+
if (monitor)
284+
monitor->setVisible(false);
285+
}

src/blocks/listblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class ListBlocks : public IExtension
3333
static CompilerValue *compileLengthOfList(Compiler *compiler);
3434
static CompilerValue *compileListContainsItem(Compiler *compiler);
3535
static CompilerValue *compileShowList(Compiler *compiler);
36+
static CompilerValue *compileHideList(Compiler *compiler);
3637

3738
static const std::string &listContentsMonitorName(Block *block);
3839
};

test/blocks/list_blocks_test.cpp

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,3 +797,216 @@ TEST_F(ListBlocksTest, ShowList_Local_FromClone)
797797
ASSERT_FALSE(clone->listAt(0)->monitor());
798798
ASSERT_FALSE(clone->listAt(1)->monitor());
799799
}
800+
801+
TEST_F(ListBlocksTest, HideList_Global_Existent)
802+
{
803+
auto stage = std::make_shared<Stage>();
804+
auto list1 = std::make_shared<List>("a", "list1");
805+
list1->append("item1");
806+
list1->append("item2");
807+
stage->addList(list1);
808+
auto list2 = std::make_shared<List>("b", "list2");
809+
list2->append("Hello");
810+
list2->append("world");
811+
stage->addList(list2);
812+
813+
auto monitor1 = std::make_shared<Monitor>("monitor", "data_listcontents");
814+
monitor1->block()->addField(std::make_shared<Field>("LIST", list1->name(), list1));
815+
monitor1->setVisible(true);
816+
817+
auto monitor2 = std::make_shared<Monitor>("monitor", "data_listcontents");
818+
monitor2->block()->addField(std::make_shared<Field>("LIST", list2->name(), list2));
819+
monitor2->setVisible(false);
820+
821+
m_engine->setMonitors({ monitor1, monitor2 });
822+
list1->setMonitor(monitor1.get());
823+
list2->setMonitor(monitor2.get());
824+
825+
m_engine->setTargets({ stage });
826+
827+
ScriptBuilder builder1(m_extension.get(), m_engine, stage);
828+
builder1.addBlock("data_hidelist");
829+
builder1.addEntityField("LIST", list1);
830+
831+
ScriptBuilder builder2(m_extension.get(), m_engine, stage);
832+
builder2.addBlock("data_hidelist");
833+
builder2.addEntityField("LIST", list2);
834+
835+
ScriptBuilder::buildMultiple({ &builder1, &builder2 });
836+
837+
builder1.run();
838+
ASSERT_FALSE(monitor1->visible());
839+
ASSERT_FALSE(monitor2->visible());
840+
841+
builder2.run();
842+
ASSERT_FALSE(monitor1->visible());
843+
ASSERT_FALSE(monitor2->visible());
844+
}
845+
846+
TEST_F(ListBlocksTest, HideList_Global_Nonexistent)
847+
{
848+
auto stage = std::make_shared<Stage>();
849+
auto list1 = std::make_shared<List>("a", "list1");
850+
list1->append("item1");
851+
list1->append("item2");
852+
stage->addList(list1);
853+
auto list2 = std::make_shared<List>("b", "list2");
854+
list2->append("Hello");
855+
list2->append("world");
856+
stage->addList(list2);
857+
858+
m_engine->setTargets({ stage });
859+
860+
ScriptBuilder builder1(m_extension.get(), m_engine, stage);
861+
builder1.addBlock("data_hidelist");
862+
builder1.addEntityField("LIST", list1);
863+
864+
ScriptBuilder builder2(m_extension.get(), m_engine, stage);
865+
builder2.addBlock("data_hidelist");
866+
builder2.addEntityField("LIST", list2);
867+
868+
ScriptBuilder::buildMultiple({ &builder1, &builder2 });
869+
870+
// Missing monitors should NOT be created
871+
builder1.run();
872+
ASSERT_FALSE(list1->monitor());
873+
874+
builder2.run();
875+
ASSERT_FALSE(list2->monitor());
876+
}
877+
878+
TEST_F(ListBlocksTest, HideList_Local_Existent)
879+
{
880+
auto stage = std::make_shared<Stage>();
881+
auto sprite = std::make_shared<Sprite>();
882+
883+
auto list1 = std::make_shared<List>("a", "list1");
884+
list1->append("item1");
885+
list1->append("item2");
886+
sprite->addList(list1);
887+
auto list2 = std::make_shared<List>("b", "list2");
888+
list2->append("Hello");
889+
list2->append("world");
890+
sprite->addList(list2);
891+
892+
auto monitor1 = std::make_shared<Monitor>("monitor", "data_listcontents");
893+
monitor1->block()->addField(std::make_shared<Field>("LIST", list1->name(), list1));
894+
monitor1->setVisible(true);
895+
896+
auto monitor2 = std::make_shared<Monitor>("monitor", "data_listcontents");
897+
monitor2->block()->addField(std::make_shared<Field>("LIST", list2->name(), list2));
898+
monitor2->setVisible(false);
899+
900+
m_engine->setMonitors({ monitor1, monitor2 });
901+
list1->setMonitor(monitor1.get());
902+
list2->setMonitor(monitor2.get());
903+
904+
m_engine->setTargets({ stage, sprite });
905+
906+
ScriptBuilder builder1(m_extension.get(), m_engine, sprite);
907+
builder1.addBlock("data_hidelist");
908+
builder1.addEntityField("LIST", list1);
909+
910+
ScriptBuilder builder2(m_extension.get(), m_engine, sprite);
911+
builder2.addBlock("data_hidelist");
912+
builder2.addEntityField("LIST", list2);
913+
914+
ScriptBuilder::buildMultiple({ &builder1, &builder2 });
915+
916+
builder1.run();
917+
ASSERT_FALSE(monitor1->visible());
918+
ASSERT_FALSE(monitor2->visible());
919+
920+
builder2.run();
921+
ASSERT_FALSE(monitor1->visible());
922+
ASSERT_FALSE(monitor2->visible());
923+
}
924+
925+
TEST_F(ListBlocksTest, HideList_Local_Nonexistent)
926+
{
927+
auto stage = std::make_shared<Stage>();
928+
auto sprite = std::make_shared<Sprite>();
929+
930+
auto list1 = std::make_shared<List>("a", "list1");
931+
list1->append("item1");
932+
list1->append("item2");
933+
sprite->addList(list1);
934+
auto list2 = std::make_shared<List>("b", "list2");
935+
list2->append("Hello");
936+
list2->append("world");
937+
sprite->addList(list2);
938+
939+
m_engine->setTargets({ stage, sprite });
940+
941+
ScriptBuilder builder1(m_extension.get(), m_engine, sprite);
942+
builder1.addBlock("data_hidelist");
943+
builder1.addEntityField("LIST", list1);
944+
945+
ScriptBuilder builder2(m_extension.get(), m_engine, sprite);
946+
builder2.addBlock("data_hidelist");
947+
builder2.addEntityField("LIST", list2);
948+
949+
ScriptBuilder::buildMultiple({ &builder1, &builder2 });
950+
m_engine->run();
951+
952+
// Missing monitors should NOT be created
953+
builder1.run();
954+
ASSERT_FALSE(list1->monitor());
955+
956+
builder2.run();
957+
ASSERT_FALSE(list2->monitor());
958+
}
959+
960+
TEST_F(ListBlocksTest, HideList_Local_FromClone)
961+
{
962+
auto stage = std::make_shared<Stage>();
963+
auto sprite = std::make_shared<Sprite>();
964+
965+
auto list1 = std::make_shared<List>("a", "list1");
966+
list1->append("item1");
967+
list1->append("item2");
968+
sprite->addList(list1);
969+
auto list2 = std::make_shared<List>("b", "list2");
970+
list2->append("Hello");
971+
list2->append("world");
972+
sprite->addList(list2);
973+
974+
auto monitor1 = std::make_shared<Monitor>("monitor", "data_listcontents");
975+
monitor1->block()->addField(std::make_shared<Field>("LIST", list1->name(), list1));
976+
monitor1->setVisible(true);
977+
978+
auto monitor2 = std::make_shared<Monitor>("monitor", "data_listcontents");
979+
monitor2->block()->addField(std::make_shared<Field>("LIST", list2->name(), list2));
980+
monitor2->setVisible(false);
981+
982+
m_engine->setMonitors({ monitor1, monitor2 });
983+
list1->setMonitor(monitor1.get());
984+
list2->setMonitor(monitor2.get());
985+
986+
sprite->setEngine(m_engine);
987+
auto clone = sprite->clone();
988+
989+
m_engine->setTargets({ stage, sprite, clone });
990+
991+
ScriptBuilder builder1(m_extension.get(), m_engine, clone);
992+
builder1.addBlock("data_hidelist");
993+
builder1.addEntityField("LIST", list1);
994+
995+
ScriptBuilder builder2(m_extension.get(), m_engine, clone);
996+
builder2.addBlock("data_hidelist");
997+
builder2.addEntityField("LIST", list2);
998+
999+
ScriptBuilder::buildMultiple({ &builder1, &builder2 });
1000+
1001+
// The clone root lists should be used
1002+
builder1.run();
1003+
ASSERT_FALSE(monitor1->visible());
1004+
ASSERT_FALSE(monitor2->visible());
1005+
1006+
builder2.run();
1007+
ASSERT_FALSE(monitor1->visible());
1008+
ASSERT_FALSE(monitor2->visible());
1009+
1010+
ASSERT_FALSE(clone->listAt(0)->monitor());
1011+
ASSERT_FALSE(clone->listAt(1)->monitor());
1012+
}

0 commit comments

Comments
 (0)