Vuo 2.4.4
Loading...
Searching...
No Matches
VuoProtocol.cc
Go to the documentation of this file.
1
10#include "VuoProtocol.hh"
11
12#include "VuoStringUtilities.hh"
13
14
15static dispatch_once_t VuoProtocolsCreated = 0;
16
17vector<VuoProtocol *> VuoProtocol::protocols;
18string VuoProtocol::imageFilter = "VuoImageFilter";
19string VuoProtocol::imageGenerator = "VuoImageGenerator";
20string VuoProtocol::imageTransition = "VuoImageTransition";
21
25vector<VuoProtocol *> VuoProtocol::getProtocols(void)
26{
27 dispatch_once(&VuoProtocolsCreated, ^{
28 VuoProtocol *imageFilterProtocol = new VuoProtocol(imageFilter, "Image Filter");
29 imageFilterProtocol->addInputPort("time", "VuoReal");
30 imageFilterProtocol->addInputPort("image", "VuoImage");
31 imageFilterProtocol->addOutputPort("outputImage", "VuoImage");
32 protocols.push_back(imageFilterProtocol);
33
34 VuoProtocol *imageGeneratorProtocol = new VuoProtocol(imageGenerator, "Image Generator");
35 imageGeneratorProtocol->addInputPort("time", "VuoReal");
36 imageGeneratorProtocol->addInputPort("width", "VuoInteger");
37 imageGeneratorProtocol->addInputPort("height", "VuoInteger");
38 imageGeneratorProtocol->addOutputPort("outputImage", "VuoImage");
39 protocols.push_back(imageGeneratorProtocol);
40
41 VuoProtocol *imageTransitionProtocol = new VuoProtocol(imageTransition, "Image Transition");
42 imageTransitionProtocol->addInputPort("time", "VuoReal");
43 imageTransitionProtocol->addInputPort("progress", "VuoReal");
44 imageTransitionProtocol->addInputPort("startImage", "VuoImage");
45 imageTransitionProtocol->addInputPort("endImage", "VuoImage");
46 imageTransitionProtocol->addOutputPort("outputImage", "VuoImage");
47 protocols.push_back(imageTransitionProtocol);
48 });
49
50 return protocols;
51}
52
57{
59
60 for (vector<VuoProtocol *>::iterator it = protocols.begin(); it != protocols.end(); ++it)
61 if ((*it)->getId() == id)
62 return *it;
63
64 VUserLog("Error: Couldn't find protocol '%s'.", id.c_str());
65
66 return NULL;
67}
68
75VuoProtocol::VuoProtocol(string id, string protocolName)
76{
77 this->id = id;
78 this->name = protocolName;
79}
80
85{
86 return id;
87}
88
93{
94 return name;
95}
96
101vector<pair<string, string> > VuoProtocol::getInputPortNamesAndTypes(void)
102{
103 return inputPortNamesAndTypes;
104}
105
110vector<pair<string, string> > VuoProtocol::getOutputPortNamesAndTypes(void)
111{
112 return outputPortNamesAndTypes;
113}
114
118bool VuoProtocol::hasInputPort(string portName)
119{
120 for (vector<pair<string, string> >::iterator i = inputPortNamesAndTypes.begin(); i != inputPortNamesAndTypes.end(); ++i)
121 {
122 string currentPortName = i->first;
123 if (currentPortName == portName)
124 return true;
125 }
126
127 return false;
128}
129
133bool VuoProtocol::hasOutputPort(string portName)
134{
135 for (vector<pair<string, string> >::iterator i = outputPortNamesAndTypes.begin(); i != outputPortNamesAndTypes.end(); ++i)
136 {
137 string currentPortName = i->first;
138 if (currentPortName == portName)
139 return true;
140 }
141
142 return false;
143}
144
148string VuoProtocol::getTypeForInputPort(string portName)
149{
150 for (vector<pair<string, string> >::iterator i = inputPortNamesAndTypes.begin(); i != inputPortNamesAndTypes.end(); ++i)
151 {
152 string currentPortName = i->first;
153 string currentPortType = i->second;
154 if (currentPortName == portName)
155 return currentPortType;
156 }
157
158 VUserLog("Error: Protocol '%s' has no input port with name '%s'.", this->name.c_str(), portName.c_str());
159 return NULL;
160}
161
166{
167 for (vector<pair<string, string> >::iterator i = outputPortNamesAndTypes.begin(); i != outputPortNamesAndTypes.end(); ++i)
168 {
169 string currentPortName = i->first;
170 string currentPortType = i->second;
171 if (currentPortName == portName)
172 return currentPortType;
173 }
174
175 VUserLog("Error: Protocol '%s' has no output port with name '%s'.", this->name.c_str(), portName.c_str());
176 return NULL;
177}
178
187bool VuoProtocol::isCompositionCompliant(string compositionAsString)
188{
189 __block int charNum = 0;
190 bool (^getNextLine)(string &linenumber) = ^(string &linenumber){
191 linenumber = "";
192 while (true)
193 {
194 char c = compositionAsString[charNum++];
195 if (c == '\n')
196 break;
197 if (c == 0)
198 return false;
199 linenumber += c;
200 }
201 return true;
202 };
203
204 // label="PublishedInputs|<image>image\r|<time>time\r"
205 string (^getLabel)(string linenumber) = ^(string linenumber){
206 string labelToken = "label=\"";
207 string::size_type labelLocation = linenumber.find(labelToken);
208 if (labelLocation == string::npos)
209 return (string)"";
210
211 labelLocation += labelToken.length();
212 string label;
213 while (labelLocation < linenumber.length() && linenumber[labelLocation] != '"')
214 label += linenumber[labelLocation++];
215
216 return label;
217 };
218
219 // |<image>image\r
220 bool (^getNextPort)(string &label, string &portID) = ^(string &label, string &portID){
221 portID = "";
222 string portToken = "|<";
223 string::size_type portLocation = label.find(portToken);
224 if (portLocation == string::npos)
225 return false;
226
227 portLocation += portToken.length();
228 while (portLocation < label.length() && label[portLocation] != '>')
229 portID += label[portLocation++];
230
231 label = label.substr(portLocation);
232
233 return true;
234 };
235
236 // _image_type="VuoImage"
237 string (^getType)(string linenumber, string portID) = ^(string linenumber, string portID){
238 string typeToken = "_" + portID + "_type=\"";
239 string::size_type typeLocation = linenumber.find(typeToken);
240 if (typeLocation == string::npos)
241 return (string)"";
242
243 typeLocation += typeToken.length();
244 string type;
245 while (typeLocation < linenumber.length() && linenumber[typeLocation] != '"')
246 type += linenumber[typeLocation++];
247
248 return type;
249 };
250
251
252 // portID => portType
253 vector<pair<string,string>> publishedInputs;
254 vector<pair<string,string>> publishedOutputs;
255 string linenumber;
256 while (getNextLine(linenumber))
257 {
258 // PublishedInputs [type="vuo.in" label="PublishedInputs|<image>image\r|<time>time\r" _image="" _image_type="VuoImage" _time="" _time_type="VuoReal"];
259 // PublishedOutputs [type="vuo.out" label="PublishedOutputs|<outputImage>outputImage\l" _outputImage_type="VuoImage"];
260 bool isPublishedInputs = false;
261 bool isPublishedOutputs = false;
262 if (VuoStringUtilities::beginsWith(linenumber, "PublishedInputs [type=\"vuo.in\" label=\"PublishedInputs|<"))
263 isPublishedInputs = true;
264 else if (VuoStringUtilities::beginsWith(linenumber, "PublishedOutputs [type=\"vuo.out\" label=\"PublishedOutputs|<"))
265 isPublishedOutputs = true;
266
267 if (!isPublishedInputs && !isPublishedOutputs)
268 continue;
269
270 string label = getLabel(linenumber);
271 if (label == "")
272 return false;
273
274 string portID;
275 while (getNextPort(label, portID))
276 {
277 if (isPublishedInputs)
278 publishedInputs.push_back({portID, getType(linenumber, portID)});
279 else
280 publishedOutputs.push_back({portID, getType(linenumber, portID)});
281 }
282 }
283
284 return arePublishedPortsCompliant(publishedInputs, publishedOutputs);
285}
286
290bool VuoProtocol::arePublishedPortsCompliant(const vector<pair<string, string>> &publishedInputNamesAndTypes,
291 const vector<pair<string, string>> &publishedOutputNamesAndTypes)
292{
293 vector<pair<string, string> > protocolInputs = getInputPortNamesAndTypes();
294 for (auto protocolInput : protocolInputs)
295 if (std::find(publishedInputNamesAndTypes.begin(), publishedInputNamesAndTypes.end(), protocolInput) == publishedInputNamesAndTypes.end())
296 return false;
297
298 vector<pair<string, string> > protocolOutputs = getOutputPortNamesAndTypes();
299 for (auto protocolOutput : protocolOutputs)
300 if (std::find(publishedOutputNamesAndTypes.begin(), publishedOutputNamesAndTypes.end(), protocolOutput) == publishedOutputNamesAndTypes.end())
301 return false;
302
303 return true;
304}
305
309vector<VuoProtocol *> VuoProtocol::getCompositionProtocols(string compositionAsString)
310{
311 vector<VuoProtocol *> allProtocols = VuoProtocol::getProtocols();
312 vector<VuoProtocol *> adheresToProtocols;
313 for (VuoProtocol *protocol : allProtocols)
314 if (protocol->isCompositionCompliant(compositionAsString))
315 adheresToProtocols.push_back(protocol);
316 return adheresToProtocols;
317}
318
322vector<VuoProtocol *> VuoProtocol::getCompositionProtocols(const vector<pair<string, string>> &publishedInputNamesAndTypes,
323 const vector<pair<string, string>> &publishedOutputNamesAndTypes)
324{
325 vector<VuoProtocol *> allProtocols = VuoProtocol::getProtocols();
326 vector<VuoProtocol *> adheresToProtocols;
327 for (VuoProtocol *protocol : allProtocols)
328 if (protocol->arePublishedPortsCompliant(publishedInputNamesAndTypes, publishedOutputNamesAndTypes))
329 adheresToProtocols.push_back(protocol);
330 return adheresToProtocols;
331}
332
339void VuoProtocol::addInputPort(string portName, string portType)
340{
341 pair<string, string> portNameAndType = make_pair(portName, portType);
342
343 for (vector<pair<string, string> >::iterator i = inputPortNamesAndTypes.begin(); i != inputPortNamesAndTypes.end(); ++i)
344 {
345 string currentPortName = i->first;
346 if (currentPortName == portName)
347 {
348 VUserLog("Error: Protocol '%s' already had an input port with name '%s'.", this->name.c_str(), portName.c_str());
349 return;
350 }
351 }
352
353 inputPortNamesAndTypes.push_back(portNameAndType);
354}
355
362void VuoProtocol::addOutputPort(string portName, string portType)
363{
364 pair<string, string> portNameAndType = make_pair(portName, portType);
365
366 for (vector<pair<string, string> >::iterator i = outputPortNamesAndTypes.begin(); i != outputPortNamesAndTypes.end(); ++i)
367 {
368 string currentPortName = i->first;
369 if (currentPortName == portName)
370 {
371 VUserLog("Error: Protocol '%s' already had an output port with name '%s'.", this->name.c_str(), portName.c_str());
372 return;
373 }
374 }
375
376 outputPortNamesAndTypes.push_back(portNameAndType);
377}