Vuo 2.4.4
Loading...
Searching...
No Matches
VuoCompilerPublishedInputNodeClass.cc
Go to the documentation of this file.
1
11#include "VuoCompiler.hh"
20#include "VuoCompilerType.hh"
21#include "VuoNode.hh"
22#include "VuoNodeClass.hh"
23#include "VuoPublishedPort.hh"
24#include "VuoStringUtilities.hh"
25#include "VuoType.hh"
26
27
28VuoCompilerPublishedInputNodeClass * VuoCompilerPublishedInputNodeClass::singleton = NULL;
29
33VuoCompilerPublishedInputNodeClass * VuoCompilerPublishedInputNodeClass::getSingleton(void)
34{
35 if (! singleton)
36 singleton = new VuoCompilerPublishedInputNodeClass(new VuoNodeClass(VuoNodeClass::publishedInputNodeClassName, vector<string>(), vector<string>()));
37
38 return singleton;
39}
40
44VuoCompilerPublishedInputNodeClass::VuoCompilerPublishedInputNodeClass(string nodeClassName, Module *module) :
45 VuoCompilerPublishedNodeClass(nodeClassName, module)
46{
47}
48
52VuoCompilerPublishedInputNodeClass::VuoCompilerPublishedInputNodeClass(VuoCompilerPublishedInputNodeClass *compilerNodeClass) :
53 VuoCompilerPublishedNodeClass(compilerNodeClass)
54{
55}
56
60VuoCompilerPublishedInputNodeClass::VuoCompilerPublishedInputNodeClass(VuoNodeClass *baseNodeClass) :
62{
63}
64
69VuoNodeClass * VuoCompilerPublishedInputNodeClass::newNodeClass(string nodeClassName, VuoCompiler *compiler, dispatch_queue_t llvmQueue)
70{
71 return VuoCompilerPublishedNodeClass::newNodeClass(nodeClassName, compiler, llvmQueue, getSingleton());
72}
73
77VuoNodeClass * VuoCompilerPublishedInputNodeClass::newNodeClass(vector<VuoPublishedPort *> publishedInputPorts, dispatch_queue_t llvmQueue)
78{
79 return VuoCompilerPublishedNodeClass::newNodeClass(publishedInputPorts, llvmQueue, getSingleton());
80}
81
87{
89 {
92 delete cnc;
93 return cnc2->getBase();
94 }
95
96 return nullptr;
97}
98
105VuoNodeClass * VuoCompilerPublishedInputNodeClass::newNodeClassWithImplementation(const string &nodeClassName,
106 const vector<string> &portNames, const vector<VuoType *> &types)
107{
108 Module *module = new Module(nodeClassName, *VuoCompiler::globalLLVMContext);
109
110 // VuoModuleMetadata({…});
111 json_object *metadata = json_object_new_object();
112 json_object_object_add(metadata, "title", json_object_new_string(VuoNodeClass::publishedInputNodeIdentifier.c_str()));
113 json_object_object_add(metadata, "version", json_object_new_string("1.0.0"));
114 json_object *specializedModuleDetails = getSingleton()->buildSpecializedModuleDetails(types);
115 json_object_object_add(metadata, "specializedModule", specializedModuleDetails);
116 string metadataStr = json_object_to_json_string(metadata);
117 json_object_put(metadata);
119
120 // For published ports a (data+event) and b (event):
121 //
122 // void nodeEvent
123 // (
124 // VuoInputData(<data type>,<default value>) a,
125 // VuoInputEvent({"eventBlocking":"door","data":"a"}) aEvent
126 // VuoInputEvent({"eventBlocking":"door"}) b,
127 // VuoOutputData(<data type>) aOut,
128 // VuoOutputEvent({"data":"aOut"}) aOutEvent,
129 // VuoOutputEvent() bOut
130 // )
131 // {
132 // if (aEvent)
133 // {
134 // *aOut = a;
135 // *aOutEvent = true;
136 // }
137 // if (b)
138 // {
139 // *bOut = true;
140 // }
141 // }
142
143
144 vector<VuoPort *> modelInputPorts;
145 for (size_t i = 0; i < portNames.size(); ++i)
146 {
147 VuoCompilerPublishedPort *modelPort = VuoCompilerPublishedPort::newPort(portNames.at(i), types.at(i));
148 modelInputPorts.push_back(modelPort->getBase());
149 }
150
151 vector<VuoPort *> modelOutputPorts;
152 for (size_t i = 0; i < portNames.size(); ++i)
153 {
154 VuoCompilerPublishedPort *modelPort = VuoCompilerPublishedPort::newPort(portNames.at(i) + "Out", types.at(i));
155 modelOutputPorts.push_back(modelPort->getBase());
156 }
157
158 map<VuoPort *, VuoPortClass::EventBlocking> eventBlockingForInputPorts;
159 for (VuoPort *modelInputPort : modelInputPorts)
160 eventBlockingForInputPorts[modelInputPort] = VuoPortClass::EventBlocking_Door;
161
162 map<VuoPort *, size_t> indexOfParameter;
163 map<VuoPort *, size_t> indexOfEventParameter;
164 VuoCompilerConstantsCache constantsCache(module);
165
166 Function *eventFunction = VuoCompilerCodeGenUtilities::getNodeEventFunction(module, "", false, false,
167 nullptr, modelInputPorts, modelOutputPorts,
168 map<VuoPort *, json_object *>(), map<VuoPort *, string>(),
169 map<VuoPort *, string>(), eventBlockingForInputPorts,
170 indexOfParameter, indexOfEventParameter, &constantsCache);
171
172 BasicBlock *initialBlock = &(eventFunction->getEntryBlock());
173 BasicBlock *currBlock = initialBlock;
174
175 for (size_t i = 0; i < portNames.size(); ++i)
176 {
177 BasicBlock *eventBlock = BasicBlock::Create(module->getContext(), "event", eventFunction);
178 BasicBlock *noEventBlock = BasicBlock::Create(module->getContext(), "noEvent", eventFunction);
179
180 VuoType *dataType = types.at(i);
181
182 // if (aEvent)
183
184 size_t inputEventArgIndex = (dataType ? indexOfEventParameter[ modelInputPorts[i] ] : indexOfParameter[ modelInputPorts[i] ]);
185 Value *inputEventArg = VuoCompilerCodeGenUtilities::getArgumentAtIndex(eventFunction, inputEventArgIndex);
186
187 Constant *falseValue = ConstantInt::get(inputEventArg->getType(), 0);
188 ICmpInst *inputEventIsTrue = new ICmpInst(*currBlock, ICmpInst::ICMP_NE, inputEventArg, falseValue);
189 BranchInst::Create(eventBlock, noEventBlock, inputEventIsTrue, currBlock);
190
191 // *aOutEvent = true;
192
193 size_t outputEventArgIndex = (dataType ? indexOfEventParameter[ modelOutputPorts[i] ] : indexOfParameter[ modelOutputPorts[i] ]);
194 Value *outputEventArg = VuoCompilerCodeGenUtilities::getArgumentAtIndex(eventFunction, outputEventArgIndex);
195
196 Constant *trueValue = ConstantInt::get(inputEventArg->getType(), 1);
197 new StoreInst(trueValue, outputEventArg, eventBlock);
198
199 // *aOut = a;
200
201 if (dataType)
202 {
203 size_t inputDataArgIndex = indexOfParameter[ modelInputPorts[i] ];
204 Value *inputDataPointer = dataType->getCompiler()->convertArgsToPortData(module, eventBlock, eventFunction, inputDataArgIndex);
205
206 size_t outputDataArgIndex = indexOfParameter[ modelOutputPorts[i] ];
207 Value *outputDataArg = VuoCompilerCodeGenUtilities::getArgumentAtIndex(eventFunction, outputDataArgIndex);
208
209 VuoCompilerCodeGenUtilities::generateMemoryCopy(module, eventBlock, inputDataPointer, outputDataArg, dataType->getCompiler());
210 }
211
212 BranchInst::Create(noEventBlock, eventBlock);
213 currBlock = noEventBlock;
214 }
215
216 ReturnInst::Create(module->getContext(), currBlock);
217
218
219 VuoCompilerPublishedInputNodeClass *dummyNodeClass = new VuoCompilerPublishedInputNodeClass(nodeClassName, module);
220 VuoCompilerNodeClass *nodeClass = new VuoCompilerPublishedInputNodeClass(dummyNodeClass);
221 delete dummyNodeClass;
222
223 return nodeClass->getBase();
224}
225
230VuoNodeClass * VuoCompilerPublishedInputNodeClass::newNodeClassWithoutImplementation(const string &nodeClassName,
231 const vector<string> &portNames, const vector<VuoType *> &types)
232{
233 vector<VuoPortClass *> inputPortClasses;
234 vector<VuoPortClass *> outputPortClasses;
235
236 VuoPortClass *refreshPortClass = (new VuoCompilerInputEventPortClass("refresh"))->getBase();
237 inputPortClasses.push_back(refreshPortClass);
238
239 for (size_t i = 0; i < portNames.size(); ++i)
240 {
241 VuoCompilerInputEventPortClass *inputPortClass = new VuoCompilerInputEventPortClass(portNames.at(i));
242 if (types.at(i))
243 {
245 inputPortClass->setDataClass(inputDataClass);
246 inputPortClass->setDataVuoType(types.at(i));
247 }
248
250
251 inputPortClasses.push_back(inputPortClass->getBase());
252 }
253
254 set<string> takenPortNames;
255 for (VuoPortClass *inputPortClass : inputPortClasses)
256 takenPortNames.insert(inputPortClass->getName());
257
258 for (size_t i = 0; i < portNames.size(); ++i)
259 {
260 string preferredName = portNames.at(i) + "Out";
261 string outputName = VuoStringUtilities::formUniqueIdentifier(takenPortNames, preferredName);
262
263 VuoCompilerInputEventPortClass *outputPortClass = new VuoCompilerInputEventPortClass(outputName);
264 if (types.at(i))
265 {
266 VuoCompilerInputDataClass *outputDataClass = new VuoCompilerInputDataClass("");
267 outputPortClass->setDataClass(outputDataClass);
268 outputPortClass->setDataVuoType(types.at(i));
269 }
270
271 outputPortClasses.push_back(outputPortClass->getBase());
272 }
273
274 VuoNodeClass *baseNodeClass = new VuoNodeClass(nodeClassName, refreshPortClass, inputPortClasses, outputPortClasses);
275 VuoCompilerNodeClass *nodeClass = new VuoCompilerPublishedInputNodeClass(baseNodeClass);
276
278
279 return nodeClass->getBase();
280}
281
286{
287 return VuoNodeClass::unreservedInputPortStartIndex + publishedInputPortIndex;
288}
289
294{
295 return VuoNodeClass::unreservedOutputPortStartIndex + publishedInputPortIndex;
296}
297
301string VuoCompilerPublishedInputNodeClass::buildNodeClassName(const vector<VuoPublishedPort *> &publishedInputPorts)
302{
303 return getSingleton()->buildNodeClassNameFromPorts(publishedInputPorts);
304}
305
309string VuoCompilerPublishedInputNodeClass::getNodeClassNamePrefix(void)
310{
312}
313
317set<string> VuoCompilerPublishedInputNodeClass::getReservedPortNames(void)
318{
319 set<string> names;
320 names.insert("refresh");
321 return names;
322}