37 INPUT_DATA_ABSENT = 1 << 0,
38 INPUT_DATA_PRESENT = 1 << 1,
39 OUTPUT_DATA_ABSENT = 1 << 2,
40 OUTPUT_DATA_PRESENT = 1 << 3,
41 INPUT_EVENT_ABSENT = 1 << 4,
42 INPUT_EVENT_PRESENT = 1 << 5,
43 OUTPUT_EVENT_ABSENT = 1 << 6,
44 OUTPUT_EVENT_PRESENT = 1 << 7,
45 OUTPUT_TRIGGER_ABSENT = 1 << 8,
46 OUTPUT_TRIGGER_PRESENT = 1 << 9,
47 INSTANCE_DATA_ABSENT = 1 << 10,
48 INSTANCE_DATA_PRESENT = 1 << 11
59 instanceDataClass = NULL;
62 callbackStartFunction = NULL;
63 callbackUpdateFunction = NULL;
64 callbackStopFunction = NULL;
65 _isSubcomposition =
false;
78 compilerNodeClass->getBase()->getClassName(),
79 compilerNodeClass->getBase()->getRefreshPortClass(),
80 compilerNodeClass->getBase()->getInputPortClasses(),
81 compilerNodeClass->getBase()->getOutputPortClasses())),
91 setDependsOnPro(compilerNodeClass->dependsOnPro());
98 this->eventFunction = compilerNodeClass->eventFunction;
99 this->initFunction = compilerNodeClass->initFunction;
100 this->finiFunction = compilerNodeClass->finiFunction;
101 this->callbackStartFunction = compilerNodeClass->callbackStartFunction;
102 this->callbackUpdateFunction = compilerNodeClass->callbackUpdateFunction;
103 this->callbackStopFunction = compilerNodeClass->callbackStopFunction;
104 this->instanceDataClass = compilerNodeClass->instanceDataClass;
105 this->triggerDescriptions = compilerNodeClass->triggerDescriptions;
106 this->compatibleSpecializedForGenericTypeName = compilerNodeClass->compatibleSpecializedForGenericTypeName;
107 this->portsWithExplicitEventBlockingNone = compilerNodeClass->portsWithExplicitEventBlockingNone;
108 this->sourcePath = compilerNodeClass->sourcePath;
109 this->sourceCode = compilerNodeClass->sourceCode;
110 this->containedNodes = compilerNodeClass->containedNodes;
115 compilerNodeClass->instanceDataClass = NULL;
117 _isSubcomposition =
false;
118 updateSubcompositionStatus();
130 instanceDataClass = NULL;
131 eventFunction = NULL;
134 callbackStartFunction = NULL;
135 callbackUpdateFunction = NULL;
136 callbackStopFunction = NULL;
137 _isSubcomposition =
false;
145 delete instanceDataClass;
148 for (vector<VuoPortClass *>::iterator i = inputPortClasses.begin(); i != inputPortClasses.end(); ++i)
149 delete (*i)->getCompiler();
152 for (vector<VuoPortClass *>::iterator i = outputPortClasses.begin(); i != outputPortClasses.end(); ++i)
153 delete (*i)->getCompiler();
165 instantiateCompilerNode(n);
175 instantiateCompilerNode(n);
184 void VuoCompilerNodeClass::instantiateCompilerNode(
VuoNode *node)
189 vector<VuoPort *> ports;
190 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
191 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
193 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
218 if (! isNodeClass(
module, nodeClassName))
233 bool VuoCompilerNodeClass::isNodeClass(Module *module,
string moduleKey)
242 void VuoCompilerNodeClass::parse(
void)
246 parseEventFunction();
247 if (instanceDataClass)
251 parseCallbackStartFunction();
252 parseCallbackUpdateFunction();
253 parseCallbackStopFunction();
257 vector<VuoPortClass *> portClasses;
260 portClasses.insert(portClasses.end(), inputPortClasses.begin(), inputPortClasses.end());
261 portClasses.insert(portClasses.end(), outputPortClasses.begin(), outputPortClasses.end());
262 for (vector<VuoPortClass *>::iterator i = portClasses.begin(); i != portClasses.end(); ++i)
274 updateSubcompositionStatus();
280 set<string> VuoCompilerNodeClass::globalsToRename(
void)
283 globals.insert(
"nodeEvent");
284 globals.insert(
"nodeInstanceEvent");
285 globals.insert(
"nodeInstanceInit");
286 globals.insert(
"nodeInstanceFini");
287 globals.insert(
"nodeInstanceTriggerStart");
288 globals.insert(
"nodeInstanceTriggerUpdate");
289 globals.insert(
"nodeInstanceTriggerStop");
296 void VuoCompilerNodeClass::parseMetadata(
void)
301 if (json_object_object_get_ex(
moduleDetails,
"node", &nodeDetails))
311 if (json_object_object_get_ex(nodeDetails,
"triggers", &triggersArray))
315 if (json_object_object_get_ex(nodeDetails,
"nodes", &nodesObj))
317 json_object_object_foreach(nodesObj, nodeIdentifier, nodeClassNameObj)
319 string nodeClassName = json_object_get_string(nodeClassNameObj);
320 containedNodes.insert(make_pair(nodeIdentifier, nodeClassName));
334 map<string, string> &defaultSpecializedForGenericTypeName,
335 map<
string, vector<string> > &compatibleSpecializedForGenericTypeName)
338 if (json_object_object_get_ex(
moduleDetails,
"genericTypes", &genericTypeDetails))
340 json_object_object_foreach(genericTypeDetails, genericTypeName, genericTypeDetailsForOneType)
343 if (! defaultType.empty())
347 if (! compatibleTypes.empty())
348 compatibleSpecializedForGenericTypeName[genericTypeName] = compatibleTypes;
359 void VuoCompilerNodeClass::parseEventFunction(
void)
367 acceptsInstanceData = INSTANCE_DATA_PRESENT;
371 VUserLog(
"Error: Node class '%s' is missing function nodeEvent or nodeInstanceEvent.",
getBase()->getClassName().c_str());
376 parseParameters(eventFunction,
377 INPUT_DATA_ABSENT | INPUT_DATA_PRESENT |
378 OUTPUT_DATA_ABSENT | OUTPUT_DATA_PRESENT |
379 INPUT_EVENT_ABSENT | INPUT_EVENT_PRESENT |
380 OUTPUT_EVENT_ABSENT | OUTPUT_EVENT_PRESENT |
381 OUTPUT_TRIGGER_ABSENT | OUTPUT_TRIGGER_PRESENT |
382 acceptsInstanceData);
391 void VuoCompilerNodeClass::parseInitFunction(
void)
397 parseParameters(initFunction,
398 INPUT_DATA_ABSENT | INPUT_DATA_PRESENT |
401 OUTPUT_EVENT_ABSENT |
402 OUTPUT_TRIGGER_ABSENT |
403 INSTANCE_DATA_ABSENT);
409 void VuoCompilerNodeClass::parseFiniFunction(
void)
423 void VuoCompilerNodeClass::parseCallbackStartFunction(
void)
426 if (! callbackStartFunction)
429 parseParameters(callbackStartFunction,
430 INPUT_DATA_ABSENT | INPUT_DATA_PRESENT |
433 OUTPUT_EVENT_ABSENT |
434 OUTPUT_TRIGGER_ABSENT | OUTPUT_TRIGGER_PRESENT |
435 INSTANCE_DATA_PRESENT);
447 void VuoCompilerNodeClass::parseCallbackUpdateFunction(
void)
450 if (! callbackUpdateFunction)
453 parseParameters(callbackUpdateFunction,
454 INPUT_DATA_ABSENT | INPUT_DATA_PRESENT |
457 OUTPUT_EVENT_ABSENT |
458 OUTPUT_TRIGGER_ABSENT | OUTPUT_TRIGGER_PRESENT |
459 INSTANCE_DATA_PRESENT);
465 void VuoCompilerNodeClass::parseCallbackStopFunction(
void)
468 if (! callbackStopFunction)
471 parseParameters(callbackStopFunction,
475 OUTPUT_EVENT_ABSENT |
476 OUTPUT_TRIGGER_ABSENT | OUTPUT_TRIGGER_PRESENT |
477 INSTANCE_DATA_PRESENT);
487 void VuoCompilerNodeClass::parseParameters(Function *
function,
unsigned long acceptanceFlags)
491 vector<VuoCompilerNodeArgumentClass *> inputArgumentClasses;
492 vector<VuoCompilerNodeArgumentClass *> outputArgumentClasses;
493 map<string, VuoType *> vuoTypeForArgumentName;
494 map<string, json_object *> detailsForArgumentName;
495 map<string, VuoCompilerPortClass *> portClassForArgumentName;
496 map<string, VuoCompilerDataClass *> dataClassForArgumentName;
498 bool sawInputData =
false;
499 bool sawOutputData =
false;
500 bool sawInputEvent =
false;
501 bool sawOutputEvent =
false;
502 bool sawOutputTrigger =
false;
503 bool sawInstanceData =
false;
506 for (vector<pair<Argument *, string> >::iterator i = annotatedArguments.begin(); i != annotatedArguments.end(); ++i)
508 Argument *argument = i->first;
509 string annotation = i->second;
517 if ((argumentClass = parseInputDataParameter(annotation, argument)) != NULL)
519 existingPortClass = getExistingPortClass(argumentClass,
true);
520 if (! existingPortClass)
522 inputArgumentClasses.push_back(argumentClass);
528 else if ((argumentClass = parseOutputDataParameter(annotation, argument)) != NULL)
530 existingPortClass = getExistingPortClass(argumentClass,
false);
531 if (! existingPortClass)
533 outputArgumentClasses.push_back(argumentClass);
537 sawOutputData =
true;
539 else if ((argumentClass = parseInputEventParameter(annotation, argument)) != NULL)
541 existingPortClass = getExistingPortClass(argumentClass,
true);
542 if (! existingPortClass)
544 inputArgumentClasses.push_back(argumentClass);
548 sawInputEvent =
true;
550 else if ((argumentClass = parseOutputEventParameter(annotation, argument)) != NULL)
552 existingPortClass = getExistingPortClass(argumentClass,
false);
553 if (! existingPortClass)
555 outputArgumentClasses.push_back(argumentClass);
559 sawOutputEvent =
true;
561 else if ((argumentClass = parseTriggerParameter(annotation, argument)) != NULL)
563 existingPortClass = getExistingPortClass(argumentClass,
false);
564 if (! existingPortClass)
566 outputArgumentClasses.push_back(argumentClass);
570 sawOutputTrigger =
true;
572 else if ((argumentClass = parseInstanceDataParameter(annotation, argument)) != NULL)
574 if (instanceDataClass)
575 existingPortClass = instanceDataClass->
getBase();
579 sawInstanceData =
true;
581 else if ((type = parseTypeParameter(annotation)) != NULL)
583 vuoTypeForArgumentName[argumentName] = type;
585 else if ((details = parseDetailsParameter(annotation)) != NULL)
587 detailsForArgumentName[argumentName] = details;
591 if (argumentClassInNodeClass)
593 size_t argumentIndex = argument->getArgNo();
594 if (
function == eventFunction)
596 else if (
function == initFunction)
598 else if (
function == callbackStartFunction)
600 else if (
function == callbackUpdateFunction)
602 else if (
function == callbackStopFunction)
606 if (existingPortClass)
607 delete argumentClass;
612 string functionName =
function->getName().str();
613 string wronglyAbsentMessage =
" is required in " + functionName;
614 string wronglyPresentMessage =
" is not allowed in " + functionName;
616 if (sawInputData && ! (acceptanceFlags & INPUT_DATA_PRESENT))
617 VUserLog(
"Error: %s", (
"VuoInputData" + wronglyPresentMessage).c_str());
618 if (sawOutputData && ! (acceptanceFlags & OUTPUT_DATA_PRESENT))
619 VUserLog(
"Error: %s", (
"VuoOutputData" + wronglyPresentMessage).c_str());
620 if (sawInputEvent && ! (acceptanceFlags & INPUT_EVENT_PRESENT))
621 VUserLog(
"Error: %s", (
"VuoInputEvent" + wronglyPresentMessage).c_str());
622 if (sawOutputEvent && ! (acceptanceFlags & OUTPUT_EVENT_PRESENT))
623 VUserLog(
"Error: %s", (
"VuoOutputEvent" + wronglyPresentMessage).c_str());
624 if (sawOutputTrigger && ! (acceptanceFlags & OUTPUT_TRIGGER_PRESENT))
625 VUserLog(
"Error: %s", (
"VuoOutputTrigger" + wronglyPresentMessage).c_str());
626 if (sawInstanceData && ! (acceptanceFlags & INSTANCE_DATA_PRESENT))
627 VUserLog(
"Error: %s", (
"VuoInstanceData" + wronglyPresentMessage).c_str());
629 if (! sawInputData && ! (acceptanceFlags & INPUT_DATA_ABSENT))
630 VUserLog(
"Error: %s", (
"VuoInputData" + wronglyAbsentMessage).c_str());
631 if (! sawOutputData && ! (acceptanceFlags & OUTPUT_DATA_ABSENT))
632 VUserLog(
"Error: %s", (
"VuoOutputData" + wronglyAbsentMessage).c_str());
633 if (! sawInputEvent && ! (acceptanceFlags & INPUT_EVENT_ABSENT))
634 VUserLog(
"Error: %s", (
"VuoInputEvent" + wronglyAbsentMessage).c_str());
635 if (! sawOutputEvent && ! (acceptanceFlags & OUTPUT_EVENT_ABSENT))
636 VUserLog(
"Error: %s", (
"VuoOutputEvent" + wronglyAbsentMessage).c_str());
637 if (! sawOutputTrigger && ! (acceptanceFlags & OUTPUT_TRIGGER_ABSENT))
638 VUserLog(
"Error: %s", (
"VuoOutputTrigger" + wronglyAbsentMessage).c_str());
639 if (! sawInstanceData && ! (acceptanceFlags & INSTANCE_DATA_ABSENT))
640 VUserLog(
"Error: %s", (
"VuoInstanceData" + wronglyAbsentMessage).c_str());
644 map<string, VuoCompilerInputEventPortClass *> inputEventPortClassForDataClassName;
645 for (map<string, VuoCompilerPortClass *>::iterator i = portClassForArgumentName.begin(); i != portClassForArgumentName.end(); ++i)
647 string argumentName = i->first;
652 bool isDataInDetails =
false;
657 inputEventPortClassForDataClassName[dataPortName] = eventPortClass;
661 map<string, VuoCompilerOutputEventPortClass *> outputEventPortClassForDataClassName;
662 for (map<string, VuoCompilerPortClass *>::iterator i = portClassForArgumentName.begin(); i != portClassForArgumentName.end(); ++i)
664 string argumentName = i->first;
669 bool isDataInDetails =
false;
674 outputEventPortClassForDataClassName[dataPortName] = eventPortClass;
680 vector<VuoPortClass *> addedInputPortClasses;
681 for (vector<VuoCompilerNodeArgumentClass *>::iterator i = inputArgumentClasses.begin(); i != inputArgumentClasses.end(); ++i)
688 if (! eventPortClass)
692 addedInputPortClasses.push_back(eventPortClass->
getBase());
697 vector<VuoPortClass *>::iterator oldBase = find(addedInputPortClasses.begin(), addedInputPortClasses.end(), eventPortClass->
getBase());
699 if (oldBase != addedInputPortClasses.end())
701 addedInputPortClasses.insert(oldBase,eventPortClass->
getBase());
702 addedInputPortClasses.erase(oldBase);
709 vector<VuoPortClass *> addedOutputPortClasses;
710 for (vector<VuoCompilerNodeArgumentClass *>::iterator i = outputArgumentClasses.begin(); i != outputArgumentClasses.end(); ++i)
716 if (! eventPortClass)
720 addedOutputPortClasses.push_back(eventPortClass->
getBase());
725 vector<VuoPortClass *>::iterator oldBase = find(addedOutputPortClasses.begin(), addedOutputPortClasses.end(), eventPortClass->
getBase());
727 if (oldBase != addedOutputPortClasses.end())
729 addedOutputPortClasses.insert(oldBase,eventPortClass->
getBase());
730 addedOutputPortClasses.erase(oldBase);
739 if (!
getBase()->getRefreshPortClass()->hasCompiler())
745 inputPortClasses.erase(inputPortClasses.begin());
750 addedInputPortClasses.insert(addedInputPortClasses.begin(), refreshPortClass);
755 inputPortClasses.insert(inputPortClasses.end(), addedInputPortClasses.begin(), addedInputPortClasses.end());
758 outputPortClasses.insert(outputPortClasses.end(), addedOutputPortClasses.begin(), addedOutputPortClasses.end());
762 vector<VuoPortClass *> portClasses;
763 portClasses.insert(portClasses.end(), addedInputPortClasses.begin(), addedInputPortClasses.end());
764 portClasses.insert(portClasses.end(), addedOutputPortClasses.begin(), addedOutputPortClasses.end());
765 for (vector<VuoPortClass *>::iterator i = portClasses.begin(); i != portClasses.end(); ++i)
774 map<string, VuoType *>::iterator vuoTypeIter = vuoTypeForArgumentName.find(dataClassName);
775 if (vuoTypeIter != vuoTypeForArgumentName.end())
778 vuoTypeForArgumentName.erase(vuoTypeIter);
784 if (triggerPortClass)
787 map<string, VuoType *>::iterator vuoTypeIter = vuoTypeForArgumentName.find(triggerName);
788 if (vuoTypeIter != vuoTypeForArgumentName.end())
791 vuoTypeForArgumentName.erase(vuoTypeIter);
795 for (map<string, VuoType *>::iterator i = vuoTypeForArgumentName.begin(); i != vuoTypeForArgumentName.end(); ++i)
799 for (map<string, json_object *>::iterator i = detailsForArgumentName.begin(); i != detailsForArgumentName.end(); ++i)
801 string argumentName = i->first;
816 for (vector<VuoPortClass *>::iterator i = addedInputPortClasses.begin(); i != addedInputPortClasses.end(); ++i)
819 bool isEventBlockingInDetails =
false;
821 if (isEventBlockingInDetails)
824 if (eventBlockingStr ==
"none")
826 else if (eventBlockingStr ==
"door")
828 else if (eventBlockingStr ==
"wall")
832 VUserLog(
"Error: Unknown option for \"eventBlocking\": %s", eventBlockingStr.c_str());
838 portsWithExplicitEventBlockingNone.insert(eventPortClass);
843 for (vector<VuoPortClass *>::iterator i = addedOutputPortClasses.begin(); i != addedOutputPortClasses.end(); ++i)
846 if (triggerPortClass)
848 bool isEventThrottlingInDetails =
false;
850 if (isEventThrottlingInDetails)
853 if (eventThrottlingStr ==
"enqueue")
855 else if (eventThrottlingStr ==
"drop")
859 VUserLog(
"Error: Unknown option for \"throttling\": %s", eventThrottlingStr.c_str());
868 for (vector<VuoPortClass *>::iterator i = inputPortClasses.begin(); i != inputPortClasses.end(); ++i)
874 bool isPortActionInDetails =
false;
877 if (isPortActionInDetails)
880 portsWithExplicitEventBlockingNone.find(eventPortClass) != portsWithExplicitEventBlockingNone.end())
891 if (annotation !=
"vuoInputData")
898 isLoweredToTwoParameters);
907 if (annotation !=
"vuoOutputData")
911 if (! a->getType()->isPointerTy())
913 VUserLog(
"Error: Output port data %s must be a pointer.", argumentName.c_str());
918 ((PointerType *)a->getType())->getElementType());
946 if (! a->getType()->isPointerTy())
948 VUserLog(
"Error: Output port %s must be a pointer.", argumentName.c_str());
953 ((PointerType *)a->getType())->getElementType());
966 if (! a->getType()->isPointerTy())
968 VUserLog(
"Error: Output trigger %s must be a pointer.", argumentName.c_str());
973 (PointerType *)a->getType());
982 if (annotation !=
"vuoInstanceData")
986 if (! a->getType()->isPointerTy())
988 VUserLog(
"Error: Node instance data %s must be a pointer.", argumentName.c_str());
993 ((PointerType *)a->getType())->getElementType());
994 return instanceDataClass;
1000 VuoType * VuoCompilerNodeClass::parseTypeParameter(
string annotation)
1008 if (typeName ==
"void")
1015 vector<string> compatibleTypes;
1016 map<string, vector<string> >::iterator compatibleTypesIter = compatibleSpecializedForGenericTypeName.find(innermostTypeName);
1017 if (compatibleTypesIter != compatibleSpecializedForGenericTypeName.end())
1020 vector<string> innermostCompatibleTypes = compatibleTypesIter->second;
1021 for (vector<string>::iterator i = innermostCompatibleTypes.begin(); i != innermostCompatibleTypes.end(); ++i)
1022 compatibleTypes.push_back(prefix + *i);
1037 json_object * VuoCompilerNodeClass::parseDetailsParameter(
string annotation)
1044 if (details.find_first_not_of(
' ') != string::npos)
1046 detailsObj = json_tokener_parse(details.c_str());
1048 VUserLog(
"Error: Couldn't parse vuoDetails for `%s`: %s",
getBase()->getClassName().c_str(), details.c_str());
1062 if (existingInputPortClass || existingOutputPortClass)
1066 if (! existingOutputPortClass)
1069 else if ((isInput && existingOutputPortClass) || (! isInput && existingInputPortClass))
1071 VUserLog(
"Error: Port %s is declared as an input port in one function and an output port in another function.", argumentName.c_str());
1075 VuoPortClass *existingPortClass = (existingInputPortClass ? existingInputPortClass : existingOutputPortClass);
1079 return existingPortClass;
1104 return eventFunction;
1112 return initFunction;
1120 return finiFunction;
1128 return callbackStartFunction;
1136 return callbackUpdateFunction;
1144 return callbackStopFunction;
1184 return triggerDescriptions;
1193 for (vector<VuoPortClass *>::iterator i = inputPortClasses.begin(); i != inputPortClasses.end(); ++i)
1194 if ((*i)->getName() == portName)
1206 for (vector<VuoPortClass *>::iterator i = outputPortClasses.begin(); i != outputPortClasses.end(); ++i)
1207 if ((*i)->getName() == portName)
1218 return instanceDataClass;
1226 ostringstream documentation;
1228 documentation <<
"/**" << endl;
1233 if (!description.empty())
1235 documentation <<
" * " << description << endl;
1236 documentation <<
" * " << endl;
1242 vector< pair<string, VuoPortClass *> > portClasses;
1243 for (vector<VuoPortClass *>::iterator i = inputPortClasses.begin(); i != inputPortClasses.end(); ++i)
1245 portClasses.push_back( make_pair(
"in", *i) );
1247 for (vector<VuoPortClass *>::iterator i = outputPortClasses.begin(); i != outputPortClasses.end(); ++i)
1250 portClasses.push_back( make_pair(isTrigger ?
"gen" :
"out", *i) );
1253 for (vector< pair<string, VuoPortClass *> >::iterator i = portClasses.begin(); i != portClasses.end(); ++i)
1255 string portKind = i->first;
1259 string portTypeName = (portType ? portType->
getModuleKey() :
"event");
1260 string portClassName = portClass->
getName();
1261 documentation <<
" * @param[" << portKind <<
"] " << portTypeName <<
" " << portClassName << endl;
1264 documentation <<
" */";
1266 return documentation.str();
1277 return typeNameIter->second;
1290 vector<string> keywords;
1293 bool nodeHasTriggerPort =
false;
1295 for (vector<VuoPortClass *>::iterator i = outputPortClasses.begin(); i != outputPortClasses.end(); ++i)
1299 nodeHasTriggerPort =
true;
1304 if (nodeHasTriggerPort)
1306 keywords.push_back(
"bang");
1307 keywords.push_back(
"events");
1308 keywords.push_back(
"trigger");
1309 keywords.push_back(
"fire");
1315 if (nodeTitleBeginsWithSend || nodeTitleBeginsWithReceive)
1317 keywords.push_back(
"i/o");
1318 keywords.push_back(
"interface");
1320 if (nodeTitleBeginsWithSend)
1322 keywords.push_back(
"output");
1323 keywords.push_back(
"consumer");
1326 if (nodeTitleBeginsWithReceive)
1328 keywords.push_back(
"input");
1329 keywords.push_back(
"provider");
1334 keywords.push_back(
"conversion");
1337 keywords.push_back(
"subcomposition");
1340 keywords.push_back(
"filter");
1343 keywords.push_back(
"generator");
1346 keywords.push_back(
"transition");
1351 keywords.push_back(
"premium");
1352 keywords.push_back(
"pro");
1395 int imagePortCount = 0;
1400 string name = p->getName();
1401 std::transform(name.begin(), name.end(), name.begin(), ::tolower);
1402 if (isInput && (name ==
"mask"))
1415 return imagePortCount;
1423 return (instanceDataClass != NULL);
1431 return _isSubcomposition;
1434 void VuoCompilerNodeClass::updateSubcompositionStatus()
1444 string dir, file, ext;
1454 this->sourcePath = sourcePath;
1470 this->sourceCode = sourceCode;
1486 return containedNodes;