30 const string VuoCompilerMakeListNodeClass::makeListNodeClassNamePrefix =
"vuo.list.make.";
33 const string VuoCompilerMakeListNodeClass::makeListNodeClassDescription =
"Creates a list from the given items.";
39 VuoCompilerMakeListNodeClass::VuoCompilerMakeListNodeClass(
string nodeClassName, Module *module) :
57 VuoCompilerMakeListNodeClass::VuoCompilerMakeListNodeClass(
VuoNodeClass *baseNodeClass) :
66 void VuoCompilerMakeListNodeClass::initialize(
void)
83 unsigned long itemCount;
85 bool parsedOk = parseNodeClassName(nodeClassName, itemCount, itemTypeStr);
91 if (! itemType || ! listType)
102 Type *itemParamSecondType = NULL;
106 Module *
module =
new Module(
"", getGlobalContext());
120 vector<VuoPort *> modelInputPorts;
121 for (
unsigned long i = 0; i < itemCount; ++i)
125 string portName = oss.str();
133 modelInputPorts.push_back( modelItemPort->
getBase() );
141 vector<VuoPort *> modelOutputPorts( 1, modelListPort->
getBase() );
142 map<VuoPort *, size_t> indexOfParameter;
143 map<VuoPort *, size_t> indexOfEventParameter;
147 nullptr, modelInputPorts, modelOutputPorts,
148 map<VuoPort *, json_object *>(), map<VuoPort *, string>(),
149 map<VuoPort *, string>(), map<VuoPort *, VuoPortClass::EventBlocking>(),
150 indexOfParameter, indexOfEventParameter, constantStrings);
160 BasicBlock *block = &(eventFunction->getEntryBlock());
161 PointerType *voidPointerType = PointerType::get(IntegerType::get(
module->getContext(), 8), 0);
163 string itemBackingTypeName;
170 itemBackingTypeName = itemTypeStr;
173 string listCreateFunctionName =
"VuoListCreate_" + itemBackingTypeName;
174 Function *listCreateFunction =
module->getFunction(listCreateFunctionName);
175 if (! listCreateFunction)
177 vector<Type *> functionParams;
178 FunctionType *functionType = FunctionType::get(voidPointerType, functionParams,
false);
179 listCreateFunction = Function::Create(functionType, GlobalValue::ExternalLinkage, listCreateFunctionName,
module);
182 string listAppendFunctionName =
"VuoListAppendValue_" + itemBackingTypeName;
183 Function *listAppendFunction =
module->getFunction(listAppendFunctionName);
184 if (! listAppendFunction)
186 vector<Type *> functionParams;
187 functionParams.push_back(voidPointerType);
188 functionParams.push_back(itemParamType);
189 if (itemParamSecondType)
191 functionParams.push_back(itemParamSecondType);
193 FunctionType *functionType = FunctionType::get(Type::getVoidTy(
module->getContext()), functionParams,
false);
194 listAppendFunction = Function::Create(functionType, GlobalValue::ExternalLinkage, listAppendFunctionName,
module);
199 vector<Value *> itemValues;
200 for (
VuoPort *itemPort : modelInputPorts)
202 size_t argIndex = indexOfParameter[itemPort];
204 itemValues.push_back(itemValue);
205 if (itemParamSecondType)
208 itemValues.push_back(itemSecondValue);
211 size_t listArgIndex = indexOfParameter[modelListPort->
getBase()];
214 CallInst *listValue = CallInst::Create(listCreateFunction,
"", block);
216 new StoreInst(listValueAsStruct, listVariable,
false, block);
218 for (
unsigned long i = 0; i < itemCount; ++i)
220 int itemValuesIndex = (itemParamSecondType ? 2*i : i);
221 vector<Value *> listAppendParams;
222 listAppendParams.push_back(listValue);
223 listAppendParams.push_back(itemValues[itemValuesIndex]);
224 if (itemParamSecondType)
226 listAppendParams.push_back(itemValues[itemValuesIndex + 1]);
228 CallInst *call = CallInst::Create(listAppendFunction, listAppendParams,
"", block);
233 ReturnInst::Create(
module->getContext(), block);
236 for (vector<VuoPort *>::iterator i = modelInputPorts.begin(); i != modelInputPorts.end(); ++i)
238 delete (*i)->getClass()->getCompiler();
241 delete modelListPort;
242 delete modelListPortClass;
249 delete dummyNodeClass;
258 vector<VuoPortClass *> inputPortClasses;
259 inputPortClasses.push_back(refreshPortClass);
260 for (
int i = 1; i <= itemCount; ++i)
268 inputPortClasses.push_back(portClass->
getBase());
271 vector<VuoPortClass *> outputPortClasses;
277 outputPortClasses.push_back(portClass->
getBase());
280 VuoNodeClass *baseNodeClass =
new VuoNodeClass(nodeClassName, refreshPortClass, inputPortClasses, outputPortClasses);
284 nodeClass->itemCount = itemCount;
285 nodeClass->listType = listType;
289 nodeClass->getBase()->setDescription(makeListNodeClassDescription);
290 nodeClass->getBase()->setVersion(
"2.0.0");
292 return nodeClass->getBase();
319 bool VuoCompilerMakeListNodeClass::parseNodeClassName(
string nodeClassName,
unsigned long &itemCount,
string &itemTypeName)
322 size_t dotPos = itemCountAndType.find(
".");
323 if (dotPos == string::npos || dotPos == 0 || dotPos == itemCountAndType.length() - 1)
326 string itemCountStr = itemCountAndType.substr(0, dotPos);
327 itemCount = atol(itemCountStr.c_str());
328 itemTypeName = itemCountAndType.substr(dotPos + 1);
339 string itemCountStr = oss.str();
341 return makeListNodeClassNamePrefix + itemCountStr +
"." + itemTypeName;
377 return "vuo.list.make";
385 return makeListNodeClassDescription;
402 bool foundDataAndEvent =
false;
403 for (set<VuoPortClass *>::iterator i = portClassesToUnspecialize.begin(); i != portClassesToUnspecialize.end(); ++i)
405 foundDataAndEvent =
true;
407 if (! foundDataAndEvent)
419 unsigned long itemCount = 0;
421 parseNodeClassName(
getBase()->getClassName(), itemCount, itemTypeName);
423 string specializedItemTypeName = (itemTypeName == genericTypeName ? specializedTypeName : itemTypeName);