33#include < scratchcpp/iengine.h>
44#include < scratchcpp/compiler.h>
55#include < scratchcpp/compilerconstant.h>
6+ #include < scratchcpp/block.h>
67#include < scratchcpp/field.h>
78#include < scratchcpp/list.h>
89
@@ -27,6 +28,8 @@ Rgb ListBlocks::color() const
2728
2829void ListBlocks::registerBlocks (IEngine *engine)
2930{
31+ // Blocks
32+ engine->addCompileFunction (this , " data_listcontents" , &compileListContents);
3033 engine->addCompileFunction (this , " data_addtolist" , &compileAddToList);
3134 engine->addCompileFunction (this , " data_deleteoflist" , &compileDeleteOfList);
3235 engine->addCompileFunction (this , " data_deletealloflist" , &compileDeleteAllOfList);
@@ -36,6 +39,24 @@ void ListBlocks::registerBlocks(IEngine *engine)
3639 engine->addCompileFunction (this , " data_itemnumoflist" , &compileItemNumOfList);
3740 engine->addCompileFunction (this , " data_lengthoflist" , &compileLengthOfList);
3841 engine->addCompileFunction (this , " data_listcontainsitem" , &compileListContainsItem);
42+
43+ // Monitor names
44+ engine->addMonitorNameFunction (this , " data_listcontents" , &listContentsMonitorName);
45+ }
46+
47+ CompilerValue *ListBlocks::compileListContents (Compiler *compiler)
48+ {
49+ auto list = compiler->field (" LIST" )->valuePtr ();
50+ assert (list);
51+
52+ // If this block is used in a list monitor, return the list pointer
53+ if (compiler->block ()->isMonitorBlock ()) {
54+ // TODO: Refactor this
55+ // List monitors expect a reference to the list
56+ // We don't have a list reference type, so cast the pointer to number
57+ return compiler->addConstValue ((uintptr_t )list.get ());
58+ } else
59+ return compiler->addListContents (static_cast <List *>(list.get ()));
3960}
4061
4162CompilerValue *ListBlocks::compileAddToList (Compiler *compiler)
@@ -194,3 +215,19 @@ CompilerValue *ListBlocks::compileListContainsItem(Compiler *compiler)
194215
195216 return nullptr ;
196217}
218+
219+ const std::string &ListBlocks::listContentsMonitorName (Block *block)
220+ {
221+ static const std::string empty = " " ;
222+ auto field = block->fieldAt (block->findField (" LIST" ));
223+
224+ if (!field)
225+ return empty;
226+
227+ List *list = dynamic_cast <List *>(field->valuePtr ().get ());
228+
229+ if (list)
230+ return list->name ();
231+ else
232+ return empty;
233+ }
0 commit comments