Vuo  2.3.2
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 
28 VuoCompilerPublishedInputNodeClass * VuoCompilerPublishedInputNodeClass::singleton = NULL;
29 
33 VuoCompilerPublishedInputNodeClass * 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 
44 VuoCompilerPublishedInputNodeClass::VuoCompilerPublishedInputNodeClass(string nodeClassName, Module *module) :
45  VuoCompilerPublishedNodeClass(nodeClassName, module)
46 {
47 }
48 
52 VuoCompilerPublishedInputNodeClass::VuoCompilerPublishedInputNodeClass(VuoCompilerPublishedInputNodeClass *compilerNodeClass) :
53  VuoCompilerPublishedNodeClass(compilerNodeClass)
54 {
55 }
56 
60 VuoCompilerPublishedInputNodeClass::VuoCompilerPublishedInputNodeClass(VuoNodeClass *baseNodeClass) :
61  VuoCompilerPublishedNodeClass(baseNodeClass)
62 {
63 }
64 
69 VuoNodeClass * VuoCompilerPublishedInputNodeClass::newNodeClass(string nodeClassName, VuoCompiler *compiler, dispatch_queue_t llvmQueue)
70 {
71  return VuoCompilerPublishedNodeClass::newNodeClass(nodeClassName, compiler, llvmQueue, getSingleton());
72 }
73 
77 VuoNodeClass * VuoCompilerPublishedInputNodeClass::newNodeClass(vector<VuoPublishedPort *> publishedInputPorts, dispatch_queue_t llvmQueue)
78 {
79  return VuoCompilerPublishedNodeClass::newNodeClass(publishedInputPorts, llvmQueue, getSingleton());
80 }
81 
88 VuoNodeClass * VuoCompilerPublishedInputNodeClass::newNodeClassWithImplementation(const string &nodeClassName,
89  const vector<string> &portNames, const vector<VuoType *> &types)
90 {
91  Module *module = new Module(nodeClassName, *VuoCompiler::globalLLVMContext);
92 
93  // VuoModuleMetadata({});
95 
96  // For published ports a (data+event) and b (event):
97  //
98  // void nodeEvent
99  // (
100  // VuoInputData(<data type>,<default value>) a,
101  // VuoInputEvent({"eventBlocking":"door","data":"a"}) aEvent
102  // VuoInputEvent({"eventBlocking":"door"}) b,
103  // VuoOutputData(<data type>) aOut,
104  // VuoOutputEvent({"data":"aOut"}) aOutEvent,
105  // VuoOutputEvent() bOut
106  // )
107  // {
108  // if (aEvent)
109  // {
110  // *aOut = a;
111  // *aOutEvent = true;
112  // }
113  // if (b)
114  // {
115  // *bOut = true;
116  // }
117  // }
118 
119 
120  vector<VuoPort *> modelInputPorts;
121  for (size_t i = 0; i < portNames.size(); ++i)
122  {
123  VuoCompilerPublishedPort *modelPort = VuoCompilerPublishedPort::newPort(portNames.at(i), types.at(i));
124  modelInputPorts.push_back(modelPort->getBase());
125  }
126 
127  vector<VuoPort *> modelOutputPorts;
128  for (size_t i = 0; i < portNames.size(); ++i)
129  {
130  VuoCompilerPublishedPort *modelPort = VuoCompilerPublishedPort::newPort(portNames.at(i) + "Out", types.at(i));
131  modelOutputPorts.push_back(modelPort->getBase());
132  }
133 
134  map<VuoPort *, VuoPortClass::EventBlocking> eventBlockingForInputPorts;
135  for (VuoPort *modelInputPort : modelInputPorts)
136  eventBlockingForInputPorts[modelInputPort] = VuoPortClass::EventBlocking_Door;
137 
138  map<VuoPort *, size_t> indexOfParameter;
139  map<VuoPort *, size_t> indexOfEventParameter;
140  VuoCompilerConstantsCache constantsCache(module);
141 
142  Function *eventFunction = VuoCompilerCodeGenUtilities::getNodeEventFunction(module, "", false, false,
143  nullptr, modelInputPorts, modelOutputPorts,
144  map<VuoPort *, json_object *>(), map<VuoPort *, string>(),
145  map<VuoPort *, string>(), eventBlockingForInputPorts,
146  indexOfParameter, indexOfEventParameter, &constantsCache);
147 
148  BasicBlock *initialBlock = &(eventFunction->getEntryBlock());
149  BasicBlock *currBlock = initialBlock;
150 
151  for (size_t i = 0; i < portNames.size(); ++i)
152  {
153  BasicBlock *eventBlock = BasicBlock::Create(module->getContext(), "event", eventFunction);
154  BasicBlock *noEventBlock = BasicBlock::Create(module->getContext(), "noEvent", eventFunction);
155 
156  VuoType *dataType = types.at(i);
157 
158  // if (aEvent)
159 
160  size_t inputEventArgIndex = (dataType ? indexOfEventParameter[ modelInputPorts[i] ] : indexOfParameter[ modelInputPorts[i] ]);
161  Value *inputEventArg = VuoCompilerCodeGenUtilities::getArgumentAtIndex(eventFunction, inputEventArgIndex);
162 
163  Constant *falseValue = ConstantInt::get(inputEventArg->getType(), 0);
164  ICmpInst *inputEventIsTrue = new ICmpInst(*currBlock, ICmpInst::ICMP_NE, inputEventArg, falseValue);
165  BranchInst::Create(eventBlock, noEventBlock, inputEventIsTrue, currBlock);
166 
167  // *aOutEvent = true;
168 
169  size_t outputEventArgIndex = (dataType ? indexOfEventParameter[ modelOutputPorts[i] ] : indexOfParameter[ modelOutputPorts[i] ]);
170  Value *outputEventArg = VuoCompilerCodeGenUtilities::getArgumentAtIndex(eventFunction, outputEventArgIndex);
171 
172  Constant *trueValue = ConstantInt::get(inputEventArg->getType(), 1);
173  new StoreInst(trueValue, outputEventArg, eventBlock);
174 
175  // *aOut = a;
176 
177  if (dataType)
178  {
179  size_t inputDataArgIndex = indexOfParameter[ modelInputPorts[i] ];
180  Value *inputDataPointer = dataType->getCompiler()->convertArgsToPortData(module, eventBlock, eventFunction, inputDataArgIndex);
181 
182  size_t outputDataArgIndex = indexOfParameter[ modelOutputPorts[i] ];
183  Value *outputDataArg = VuoCompilerCodeGenUtilities::getArgumentAtIndex(eventFunction, outputDataArgIndex);
184 
185  VuoCompilerCodeGenUtilities::generateMemoryCopy(module, eventBlock, inputDataPointer, outputDataArg, dataType->getCompiler()->getSize(module));
186  }
187 
188  BranchInst::Create(noEventBlock, eventBlock);
189  currBlock = noEventBlock;
190  }
191 
192  ReturnInst::Create(module->getContext(), currBlock);
193 
194 
196  VuoCompilerNodeClass *nodeClass = new VuoCompilerPublishedInputNodeClass(dummyNodeClass);
197  delete dummyNodeClass;
198 
200  nodeClass->getBase()->setVersion("1.0.0");
201 
202  return nodeClass->getBase();
203 }
204 
209 VuoNodeClass * VuoCompilerPublishedInputNodeClass::newNodeClassWithoutImplementation(const string &nodeClassName,
210  const vector<string> &portNames, const vector<VuoType *> &types)
211 {
212  vector<VuoPortClass *> inputPortClasses;
213  vector<VuoPortClass *> outputPortClasses;
214 
215  VuoPortClass *refreshPortClass = (new VuoCompilerInputEventPortClass("refresh"))->getBase();
216  inputPortClasses.push_back(refreshPortClass);
217 
218  for (size_t i = 0; i < portNames.size(); ++i)
219  {
220  VuoCompilerInputEventPortClass *inputPortClass = new VuoCompilerInputEventPortClass(portNames.at(i));
221  if (types.at(i))
222  {
223  VuoCompilerInputDataClass *inputDataClass = new VuoCompilerInputDataClass("");
224  inputPortClass->setDataClass(inputDataClass);
225  inputPortClass->setDataVuoType(types.at(i));
226  }
227 
229 
230  inputPortClasses.push_back(inputPortClass->getBase());
231  }
232 
233  set<string> takenPortNames;
234  for (VuoPortClass *inputPortClass : inputPortClasses)
235  takenPortNames.insert(inputPortClass->getName());
236 
237  for (size_t i = 0; i < portNames.size(); ++i)
238  {
239  string preferredName = portNames.at(i) + "Out";
240  string outputName = VuoStringUtilities::formUniqueIdentifier(takenPortNames, preferredName);
241 
242  VuoCompilerInputEventPortClass *outputPortClass = new VuoCompilerInputEventPortClass(outputName);
243  if (types.at(i))
244  {
245  VuoCompilerInputDataClass *outputDataClass = new VuoCompilerInputDataClass("");
246  outputPortClass->setDataClass(outputDataClass);
247  outputPortClass->setDataVuoType(types.at(i));
248  }
249 
250  outputPortClasses.push_back(outputPortClass->getBase());
251  }
252 
253  VuoNodeClass *baseNodeClass = new VuoNodeClass(nodeClassName, refreshPortClass, inputPortClasses, outputPortClasses);
254  VuoCompilerNodeClass *nodeClass = new VuoCompilerPublishedInputNodeClass(baseNodeClass);
255 
257 
258  return nodeClass->getBase();
259 }
260 
265 {
266  return VuoNodeClass::unreservedInputPortStartIndex + publishedInputPortIndex;
267 }
268 
273 {
274  return VuoNodeClass::unreservedOutputPortStartIndex + publishedInputPortIndex;
275 }
276 
280 string VuoCompilerPublishedInputNodeClass::buildNodeClassName(const vector<VuoPublishedPort *> &publishedInputPorts)
281 {
282  return getSingleton()->buildNodeClassNameFromPorts(publishedInputPorts);
283 }
284 
288 string VuoCompilerPublishedInputNodeClass::getNodeClassNamePrefix(void)
289 {
291 }
292 
296 set<string> VuoCompilerPublishedInputNodeClass::getReservedPortNames(void)
297 {
298  set<string> names;
299  names.insert("refresh");
300  return names;
301 }