Vuo  2.3.2
VuoRuntimeContext.cc
Go to the documentation of this file.
1 
10 #include "VuoRuntimeContext.hh"
11 #include "VuoEventLoop.h"
12 #include <mutex>
13 #include <condition_variable>
14 
18 struct PortContext * vuoCreatePortContext(void *data, bool isTrigger, const char *triggerQueueName)
19 {
20  struct PortContext *portContext = (struct PortContext *)malloc(sizeof(struct PortContext));
21  portContext->event = false;
22  portContext->data = data;
23  portContext->dataRetained = false;
24  portContext->triggerFunction = NULL;
25 
26  if (isTrigger)
27  {
28  portContext->triggerQueue = dispatch_queue_create(triggerQueueName, VuoEventLoop_getDispatchInteractiveAttribute());
29  portContext->triggerSemaphore = dispatch_semaphore_create(1);
30  }
31  else
32  {
33  portContext->triggerQueue = NULL;
34  portContext->triggerSemaphore = NULL;
35  }
36 
37  return portContext;
38 }
39 
43 struct NodeContext * vuoCreateNodeContext(bool hasInstanceData, bool isComposition, size_t outputEventCount)
44 {
45  struct NodeContext *nodeContext = (struct NodeContext *)malloc(sizeof(struct NodeContext));
46  nodeContext->portContexts = NULL;
47  nodeContext->portContextCount = 0;
48  nodeContext->nodeMutex = new std::mutex();
49  nodeContext->nodeConditionVariable = new std::condition_variable();
50  nodeContext->claimingEventId = 0;
51 
52  if (isComposition)
53  {
54  nodeContext->executingEventIds = new vector<unsigned long>();
55  nodeContext->executingGroup = dispatch_group_create();
56  nodeContext->outputEvents = (bool *)calloc(outputEventCount, sizeof(bool));
57  nodeContext->executingEventIdsSync = new std::mutex();
58  }
59  else
60  {
61  nodeContext->executingEventIds = NULL;
62  nodeContext->executingGroup = NULL;
63  nodeContext->outputEvents = NULL;
64  nodeContext->executingEventIdsSync = NULL;
65  }
66 
67  if (hasInstanceData)
68  {
69  void **instanceData = (void **)malloc(sizeof(void *));
70  *instanceData = NULL;
71  nodeContext->instanceData = (void *)instanceData;
72  }
73  else
74  nodeContext->instanceData = NULL;
75 
76  return nodeContext;
77 }
78 
82 void vuoFreePortContext(struct PortContext *portContext)
83 {
84  if (! portContext->dataRetained)
85  free(portContext->data);
86  if (portContext->triggerQueue)
87  dispatch_release(portContext->triggerQueue);
88  if (portContext->triggerSemaphore)
89  dispatch_release(portContext->triggerSemaphore);
90  free(portContext);
91 }
92 
96 void vuoFreeNodeContext(struct NodeContext *nodeContext)
97 {
98  for (size_t i = 0; i < nodeContext->portContextCount; ++i)
99  vuoFreePortContext(nodeContext->portContexts[i]);
100 
101  free(nodeContext->portContexts);
102  free(nodeContext->instanceData);
103  delete static_cast<std::mutex *>(nodeContext->nodeMutex);
104  delete static_cast<std::condition_variable *>(nodeContext->nodeConditionVariable);
105  delete static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
106  if (nodeContext->executingGroup)
107  dispatch_release(nodeContext->executingGroup);
108  free(nodeContext->outputEvents);
109  delete static_cast<std::mutex *>(nodeContext->executingEventIdsSync);
110  free(nodeContext);
111 }
112 
116 void vuoSetPortContextEvent(struct PortContext *portContext, bool event)
117 {
118  portContext->event = event;
119 }
120 
124 void vuoSetPortContextData(struct PortContext *portContext, void *data)
125 {
126  portContext->data = data;
127 }
128 
132 void vuoSetPortContextTriggerFunction(struct PortContext *portContext, void *triggerFunction)
133 {
134  portContext->triggerFunction = triggerFunction;
135 }
136 
140 bool vuoGetPortContextEvent(struct PortContext *portContext)
141 {
142  return portContext->event;
143 }
144 
148 void * vuoGetPortContextData(struct PortContext *portContext)
149 {
150  return portContext->data;
151 }
152 
156 dispatch_queue_t vuoGetPortContextTriggerQueue(struct PortContext *portContext)
157 {
158  return portContext->triggerQueue;
159 }
160 
164 dispatch_semaphore_t vuoGetPortContextTriggerSemaphore(struct PortContext *portContext)
165 {
166  return portContext->triggerSemaphore;
167 }
168 
173 {
174  return portContext->triggerFunction;
175 }
176 
180 void vuoRetainPortContextData(struct PortContext *portContext)
181 {
182  portContext->dataRetained = true;
183 }
184 
188 void vuoSetNodeContextPortContexts(struct NodeContext *nodeContext, struct PortContext **portContexts, unsigned long portContextCount)
189 {
190  nodeContext->portContexts = portContexts;
191  nodeContext->portContextCount = portContextCount;
192 }
193 
198 {
199  free(nodeContext->instanceData);
200  nodeContext->instanceData = instanceData;
201 }
202 
206 void vuoSetNodeContextClaimingEventId(struct NodeContext *nodeContext, unsigned long claimingEventId)
207 {
208  nodeContext->claimingEventId = claimingEventId;
209 }
210 
214 void vuoSetNodeContextOutputEvent(struct NodeContext *nodeContext, size_t index, bool event)
215 {
216  nodeContext->outputEvents[index] = event;
217 }
218 
222 struct PortContext * vuoGetNodeContextPortContext(struct NodeContext *nodeContext, size_t index)
223 {
224  return nodeContext->portContexts[index];
225 }
226 
230 void * vuoGetNodeContextInstanceData(struct NodeContext *nodeContext)
231 {
232  return nodeContext->instanceData;
233 }
234 
238 unsigned long vuoGetNodeContextClaimingEventId(struct NodeContext *nodeContext)
239 {
240  return nodeContext->claimingEventId;
241 }
242 
246 dispatch_group_t vuoGetNodeContextExecutingGroup(struct NodeContext *nodeContext)
247 {
248  return nodeContext->executingGroup;
249 }
250 
254 bool vuoGetNodeContextOutputEvent(struct NodeContext *nodeContext, size_t index)
255 {
256  return nodeContext->outputEvents[index];
257 }
258 
262 void vuoResetNodeContextEvents(struct NodeContext *nodeContext)
263 {
264  for (size_t i = 0; i < nodeContext->portContextCount; ++i)
265  nodeContext->portContexts[i]->event = false;
266 }
267 
271 void vuoStartedExecutingEvent(struct NodeContext *nodeContext, unsigned long eventId)
272 {
273  std::lock_guard<std::mutex> guard(*static_cast<std::mutex *>(nodeContext->executingEventIdsSync));
274 
275  vector<unsigned long> *executingEventIds = static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
276  executingEventIds->clear();
277  executingEventIds->push_back(eventId);
278 }
279 
283 void vuoSpunOffExecutingEvent(struct NodeContext *nodeContext, unsigned long eventId)
284 {
285  std::lock_guard<std::mutex> guard(*static_cast<std::mutex *>(nodeContext->executingEventIdsSync));
286 
287  vector<unsigned long> *executingEventIds = static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
288  if (! executingEventIds->empty())
289  executingEventIds->push_back(eventId);
290 }
291 
296 bool vuoFinishedExecutingEvent(struct NodeContext *nodeContext, unsigned long eventId)
297 {
298  std::lock_guard<std::mutex> guard(*static_cast<std::mutex *>(nodeContext->executingEventIdsSync));
299 
300  vector<unsigned long> *executingEventIds = static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
301  auto found = find(executingEventIds->begin(), executingEventIds->end(), eventId);
302  if (found != executingEventIds->end())
303  {
304  executingEventIds->erase(found);
305  return executingEventIds->empty();
306  }
307  return false;
308 }
309 
314 unsigned long vuoGetOneExecutingEvent(struct NodeContext *nodeContext)
315 {
316  std::lock_guard<std::mutex> guard(*static_cast<std::mutex *>(nodeContext->executingEventIdsSync));
317 
318  vector<unsigned long> *executingEventIds = static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
319  return executingEventIds->at(0);
320 }