39 if (instanceDataClass)
44 constantStrings = NULL;
45 indexInOrderedNodes = ULONG_MAX - 1;
53 this->indexInOrderedNodes = indexInOrderedNodes;
61 return indexInOrderedNodes;
69 this->constantStrings = constantStrings;
73 vector<VuoPort *> ports;
74 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
75 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
76 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
99 vector<Value *> identifierParts;
100 identifierParts.push_back(compositionIdentifierValue);
101 identifierParts.push_back(constantStrings->
get(module,
"/" +
getIdentifier()));
118 const vector<VuoCompilerType *> &orderedTypes,
119 Function *compositionCreateContextForNode,
120 Function *compositionSetPortValueFunction, Function *compositionGetPortValueFunction,
121 Function *compositionFireTriggerPortEventFunction, Function *compositionReleasePortDataFunction)
127 compositionCreateContextForNode, compositionSetPortValueFunction,
128 compositionGetPortValueFunction, compositionFireTriggerPortEventFunction,
129 compositionReleasePortDataFunction);
133 vector<VuoPort *> ports;
134 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
135 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
136 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
140 Value *portIdentifierValue = constantStrings->
get(module, port->
getIdentifier());
149 vector<VuoCompilerType *>::const_iterator typeIter = find(orderedTypes.begin(), orderedTypes.end(), dataType->
getCompiler());
150 typeIndex = typeIter - orderedTypes.begin();
157 typeIndex = orderedTypes.size();
160 Value *initialValueValue = constantStrings->
get(module, initialValue);
163 portNameValue, typeIndex, initialValueValue);
166 if (subcompositionFunctionSrc)
175 CallInst::Create(subcompositionFunctionDst, arg,
"", block);
190 unsigned long publishedOutputPortCount = (isSubcomposition ?
199 vector<VuoPort *> ports;
200 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
201 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
202 vector<Value *> portContextValues;
203 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
208 portContextValues.push_back(portContextValue);
213 return nodeContextValue;
228 Value *compositionStateValue)
232 Value *nodeContextValue =
generateGetContext(module, currentBlock, compositionStateValue);
234 map<VuoCompilerEventPort *, Value *> portContextForEventPort;
237 vector<VuoPort *> ports;
238 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
239 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
240 for (vector<VuoPort *>::iterator i = ports.begin(); i != ports.end(); ++i)
244 portContextForEventPort[eventPort] = eventPort->
generateGetPortContext(module, currentBlock, nodeContextValue);
247 generateFunctionCall(functionSrc, module, currentBlock, compositionStateValue, nodeContextValue, portContextForEventPort);
253 vector<VuoPort *> nonBlockingInputPorts;
254 vector<VuoPort *> doorInputPorts;
255 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
259 nonBlockingInputPorts.push_back(*i);
261 doorInputPorts.push_back(*i);
265 portContextForEventPort);
266 Value *transmitForAllOutputPorts = eventHitNonBlockingInputPort;
268 BasicBlock *handleTransmissionBlock = NULL;
269 BasicBlock *nextBlock = NULL;
270 if (! doorInputPorts.empty())
272 handleTransmissionBlock = BasicBlock::Create(module->getContext(),
"handleTransmission",
function, 0);
273 nextBlock = BasicBlock::Create(module->getContext(),
"next",
function, 0);
276 portContextForEventPort);
278 Value *blockForAllOutputPorts = BinaryOperator::Create(Instruction::And,
279 BinaryOperator::CreateNot(eventHitNonBlockingInputPort,
"", currentBlock),
280 BinaryOperator::CreateNot(eventHitDoorInputPort,
"", currentBlock),
282 Value *handleTransmission = BinaryOperator::Create(Instruction::Or, transmitForAllOutputPorts, blockForAllOutputPorts,
"", currentBlock);
284 Constant *zeroValue = ConstantInt::get(transmitForAllOutputPorts->getType(), 0);
285 ICmpInst *handleTransmissionComparison =
new ICmpInst(*currentBlock, ICmpInst::ICMP_NE, handleTransmission, zeroValue,
"");
286 BranchInst::Create(handleTransmissionBlock, nextBlock, handleTransmissionComparison, currentBlock);
290 handleTransmissionBlock = currentBlock;
293 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
298 Value *portContextValue = portContextForEventPort[eventPort];
299 eventPort->
generateStoreEvent(module, handleTransmissionBlock, nodeContextValue, transmitForAllOutputPorts, portContextValue);
303 if (! doorInputPorts.empty())
305 BranchInst::Create(nextBlock, handleTransmissionBlock);
306 currentBlock = nextBlock;
325 CallInst *call = generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
329 instanceData->
generateStore(module, block, nodeContextValue, callCasted);
332 Value *instanceDataValue = instanceData->
generateLoad(module, block, nodeContextValue);
351 generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
354 Value *instanceDataValue = instanceData->
generateLoad(module, block, nodeContextValue);
372 generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
389 generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
406 generateFunctionCall(functionSrc, module, block, compositionStateValue, nodeContextValue);
418 CallInst * VuoCompilerNode::generateFunctionCall(Function *functionSrc, Module *module, BasicBlock *block,
419 Value *compositionStateValue, Value *nodeContextValue,
420 const map<VuoCompilerEventPort *, Value *> &portContextForEventPort)
424 vector<Value *> args(functionDst->getFunctionType()->getNumParams());
427 Value *subcompositionIdentifierValue = NULL;
428 Value *subcompositionStateValue = NULL;
429 if (
getBase()->getNodeClass()->getCompiler()->isSubcomposition())
440 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
445 bool isEventArgumentInFunction = isArgumentInFunction(eventPort, functionSrc);
446 bool isDataArgumentInFunction = data && isArgumentInFunction(data, functionSrc);
448 if (isEventArgumentInFunction || isDataArgumentInFunction)
450 map<VuoCompilerEventPort *, Value *>::const_iterator iter = portContextForEventPort.find(eventPort);
451 Value *portContextValue = (iter != portContextForEventPort.end() ?
455 if (isEventArgumentInFunction)
457 size_t index = getArgumentIndexInFunction(eventPort, functionSrc);
458 args[index] = eventPort->
generateLoadEvent(module, block, nodeContextValue, portContextValue);
461 if (isDataArgumentInFunction)
463 size_t index = getArgumentIndexInFunction(data, functionSrc);
464 Value *arg = eventPort->
generateLoadData(module, block, nodeContextValue, portContextValue);
465 Value *secondArg = NULL;
474 if (
getBase()->getNodeClass()->getCompiler()->isSubcomposition() &&
475 arg->getType()->isStructTy() &&
479 arg =
new BitCastInst(argAsPointer, functionSrc->getFunctionType()->getParamType(index),
"", block);
484 Value **secondArgIfNeeded = (isLoweredToTwoParameters ? &secondArg : NULL);
488 VUserLog(
"Warning: Couldn't convert argument for input port '%s' of function %s; not generating call.",
489 (*i)->getClass()->getName().c_str(),
490 functionDst->getName().str().c_str());
497 args[index + 1] = secondArg;
504 map<VuoCompilerOutputEventPort *, Value *> outputPortDataVariables;
505 map<VuoCompilerOutputEventPort *, AllocaInst *> outputPortEventVariables;
506 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
512 bool isEventArgumentInFunction = isArgumentInFunction(eventPort, functionSrc);
513 bool isDataArgumentInFunction = data && isArgumentInFunction(data, functionSrc);
515 if (isEventArgumentInFunction)
517 size_t index = getArgumentIndexInFunction(eventPort, functionSrc);
518 PointerType *eventPointerType =
static_cast<PointerType *
>( functionDst->getFunctionType()->getParamType(index) );
519 AllocaInst *arg =
new AllocaInst(eventPointerType->getElementType(),
"", block);
520 new StoreInst(ConstantInt::get(eventPointerType->getElementType(), 0), arg, block);
521 outputPortEventVariables[eventPort] = arg;
525 if (isDataArgumentInFunction)
527 map<VuoCompilerEventPort *, Value *>::const_iterator iter = portContextForEventPort.find(eventPort);
528 Value *portContextValue = (iter != portContextForEventPort.end() ?
532 size_t index = getArgumentIndexInFunction(data, functionSrc);
535 outputPortDataVariables[eventPort] = dataVariable;
540 VUserLog(
"Warning: Couldn't convert argument for output port '%s' of function %s; not generating call.",
541 (*i)->getClass()->getName().c_str(),
542 functionDst->getName().str().c_str());
551 if (isArgumentInFunction(triggerPort, functionSrc))
553 size_t index = getArgumentIndexInFunction(triggerPort, functionSrc);
560 Value *instanceDataVariable = NULL;
561 if (instanceData && isArgumentInFunction(instanceData, functionSrc))
566 size_t index = getArgumentIndexInFunction(instanceData, functionSrc);
567 Value *arg = instanceDataVariable;
571 VUserLog(
"Warning: Couldn't convert argument for instance data of function %s; not generating call.", functionDst->getName().str().c_str());
577 map<VuoCompilerOutputEventPort *, Value *> oldOutputDataValues;
578 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = outputPortDataVariables.begin(); i != outputPortDataVariables.end(); ++i)
581 Value *dataVariable = i->second;
583 oldOutputDataValues[eventPort] =
new LoadInst(dataVariable,
"",
false, block);
587 Value *oldInstanceDataValue = NULL;
588 if (instanceDataVariable)
590 oldInstanceDataValue =
new LoadInst(instanceDataVariable,
"",
false, block);
596 CallInst *call = CallInst::Create(functionDst, args,
"", block);
602 for (map<VuoCompilerOutputEventPort *, AllocaInst *>::iterator i = outputPortEventVariables.begin(); i != outputPortEventVariables.end(); ++i)
605 AllocaInst *eventVariable = i->second;
606 Value *eventValue =
new LoadInst(eventVariable,
"",
false, block);
611 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = outputPortDataVariables.begin(); i != outputPortDataVariables.end(); ++i)
614 Value *dataVariable = i->second;
616 Value *outputDataValue =
new LoadInst(dataVariable,
"",
false, block);
622 for (map<VuoCompilerOutputEventPort *, Value *>::iterator i = oldOutputDataValues.begin(); i != oldOutputDataValues.end(); ++i)
625 Value *oldOutputDataValue = i->second;
631 if (instanceDataVariable)
634 Value *instanceDataValue =
new LoadInst(instanceDataVariable,
"",
false, block);
641 if (
getBase()->getNodeClass()->getCompiler()->isSubcomposition())
659 if (
function ==
getBase()->getNodeClass()->getCompiler()->getEventFunction())
661 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getInitFunction())
663 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStartFunction())
665 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackUpdateFunction())
667 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStopFunction())
669 else if (instanceData == argument &&
670 (
function ==
getBase()->getNodeClass()->getCompiler()->getFiniFunction()))
684 if (
function ==
getBase()->getNodeClass()->getCompiler()->getEventFunction())
686 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getInitFunction())
688 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getFiniFunction())
689 return (
getBase()->getNodeClass()->getCompiler()->isSubcomposition() ? 1 : 0);
690 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStartFunction())
692 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackUpdateFunction())
694 else if (
function ==
getBase()->getNodeClass()->getCompiler()->getCallbackStopFunction())
711 vector<VuoPort *> selectedInputPorts,
712 const map<VuoCompilerEventPort *, Value *> &portContextForEventPort)
714 Value *conditionValue = ConstantInt::getFalse(block->getContext());
715 for (vector<VuoPort *>::iterator i = selectedInputPorts.begin(); i != selectedInputPorts.end(); ++i)
720 map<VuoCompilerEventPort *, Value *>::const_iterator iter = portContextForEventPort.find(eventPort);
721 Value *portContextValue = (iter != portContextForEventPort.end() ?
725 Value *pushValue = eventPort->
generateLoadEvent(module, block, nodeContextValue, portContextValue);
726 conditionValue = BinaryOperator::Create(Instruction::Or, conditionValue, pushValue,
"", block);
729 return conditionValue;
763 if (titleWithoutSpaces.empty())
766 return titleWithoutSpaces;
774 this->graphvizIdentifier = graphvizIdentifier;
782 return graphvizIdentifier;
790 VuoPort *manuallyFirableInputPort)
792 ostringstream declaration;
808 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
811 declaration <<
"|<" << portName <<
">" << portName <<
"\\l";
813 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
816 declaration <<
"|<" << portName <<
">" << portName <<
"\\r";
821 if (shouldPrintPosition)
822 declaration <<
" pos=\"" <<
getBase()->
getX()+xPositionOffset <<
"," <<
getBase()->
getY()+yPositionOffset <<
"\"";
826 declaration <<
" collapsed";
829 if (
getBase()->getTintColor() != VuoNode::TintNone)
833 for (vector<VuoPort *>::iterator i = inputPorts.begin(); i != inputPorts.end(); ++i)
842 declaration <<
" _" << port->
getClass()->
getName() <<
"=\"" << escapedPortConstant <<
"\"";
847 for (vector<VuoPort *>::iterator i = outputPorts.begin(); i != outputPorts.end(); ++i)
853 declaration <<
" _" << port->
getClass()->
getName() <<
"_eventThrottling=\"" << eventThrottling <<
"\"";
858 if (manuallyFirableInputPort)
859 declaration <<
" _" << manuallyFirableInputPort->
getClass()->
getName() <<
"_manuallyFirable";
863 return declaration.str();