Vuo 2.4.4
Loading...
Searching...
No Matches
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
18struct 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;
26
27 if (isTrigger)
28 {
29 portContext->triggerQueue = dispatch_queue_create(triggerQueueName, VuoEventLoop_getDispatchInteractiveAttribute());
30 portContext->triggerSemaphore = dispatch_semaphore_create(1);
31 }
32 else
33 {
34 portContext->triggerQueue = NULL;
35 portContext->triggerSemaphore = NULL;
36 }
37
38 return portContext;
39}
40
44struct NodeContext * vuoCreateNodeContext(bool hasInstanceData, bool isComposition, size_t outputEventCount)
45{
46 struct NodeContext *nodeContext = (struct NodeContext *)malloc(sizeof(struct NodeContext));
47 nodeContext->portContexts = NULL;
48 nodeContext->portContextCount = 0;
49 nodeContext->nodeMutex = new std::mutex();
50 nodeContext->nodeConditionVariable = new std::condition_variable();
51 nodeContext->claimingEventId = 0;
52
53 if (isComposition)
54 {
55 nodeContext->executingEventIds = new vector<unsigned long>();
56 nodeContext->executingGroup = dispatch_group_create();
57 nodeContext->outputEvents = (bool *)calloc(outputEventCount, sizeof(bool));
58 nodeContext->executingEventIdsSync = new std::mutex();
59 }
60 else
61 {
62 nodeContext->executingEventIds = NULL;
63 nodeContext->executingGroup = NULL;
64 nodeContext->outputEvents = NULL;
65 nodeContext->executingEventIdsSync = NULL;
66 }
67
68 if (hasInstanceData)
69 {
70 void **instanceData = (void **)malloc(sizeof(void *));
71 *instanceData = NULL;
72 nodeContext->instanceData = (void *)instanceData;
73 }
74 else
75 nodeContext->instanceData = NULL;
76
77 return nodeContext;
78}
79
83void vuoFreePortContext(struct PortContext *portContext)
84{
85 if (! portContext->dataRetained)
86 free(portContext->data);
87 if (portContext->triggerQueue)
88 dispatch_release(portContext->triggerQueue);
89 if (portContext->triggerSemaphore)
90 dispatch_release(portContext->triggerSemaphore);
91 free(portContext);
92}
93
97void vuoFreeNodeContext(struct NodeContext *nodeContext)
98{
99 for (size_t i = 0; i < nodeContext->portContextCount; ++i)
100 vuoFreePortContext(nodeContext->portContexts[i]);
101
102 free(nodeContext->portContexts);
103 free(nodeContext->instanceData);
104 delete static_cast<std::mutex *>(nodeContext->nodeMutex);
105 delete static_cast<std::condition_variable *>(nodeContext->nodeConditionVariable);
106 delete static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
107 if (nodeContext->executingGroup)
108 dispatch_release(nodeContext->executingGroup);
109 free(nodeContext->outputEvents);
110 delete static_cast<std::mutex *>(nodeContext->executingEventIdsSync);
111 free(nodeContext);
112}
113
117void vuoSetPortContextEvent(struct PortContext *portContext, bool event)
118{
119 portContext->event = event;
120}
121
125void vuoSetPortContextData(struct PortContext *portContext, void *data)
126{
127 portContext->data = data;
128}
129
133void vuoSetPortContextTriggerFunction(struct PortContext *portContext, void *triggerFunction)
134{
135 portContext->triggerFunction = triggerFunction;
136}
137
142{
143 portContext->eventBlocking = eventBlocking;
144}
145
149bool vuoGetPortContextEvent(struct PortContext *portContext)
150{
151 return portContext->event;
152}
153
157void * vuoGetPortContextData(struct PortContext *portContext)
158{
159 return portContext->data;
160}
161
165dispatch_queue_t vuoGetPortContextTriggerQueue(struct PortContext *portContext)
166{
167 return portContext->triggerQueue;
168}
169
173dispatch_semaphore_t vuoGetPortContextTriggerSemaphore(struct PortContext *portContext)
174{
175 return portContext->triggerSemaphore;
176}
177
182{
183 return portContext->triggerFunction;
184}
185
189void vuoRetainPortContextData(struct PortContext *portContext)
190{
191 portContext->dataRetained = true;
192}
193
198{
199 nodeContext->portContexts = portContexts;
200 nodeContext->portContextCount = portContextCount;
201}
202
207{
208 free(nodeContext->instanceData);
209 nodeContext->instanceData = instanceData;
210}
211
215void vuoSetNodeContextClaimingEventId(struct NodeContext *nodeContext, unsigned long claimingEventId)
216{
217 nodeContext->claimingEventId = claimingEventId;
218}
219
223void vuoSetNodeContextOutputEvent(struct NodeContext *nodeContext, size_t index, bool event)
224{
225 nodeContext->outputEvents[index] = event;
226}
227
231struct PortContext * vuoGetNodeContextPortContext(struct NodeContext *nodeContext, size_t index)
232{
233 return nodeContext->portContexts[index];
234}
235
240{
241 return nodeContext->instanceData;
242}
243
247unsigned long vuoGetNodeContextClaimingEventId(struct NodeContext *nodeContext)
248{
249 return nodeContext->claimingEventId;
250}
251
255dispatch_group_t vuoGetNodeContextExecutingGroup(struct NodeContext *nodeContext)
256{
257 return nodeContext->executingGroup;
258}
259
263bool vuoGetNodeContextOutputEvent(struct NodeContext *nodeContext, size_t index)
264{
265 return nodeContext->outputEvents[index];
266}
267
272{
273 for (unsigned long i = 0; i < nodeContext->portContextCount; ++i)
274 {
275 PortContext *portContext = nodeContext->portContexts[i];
276 if (portContext->eventBlocking != PortContext_EventBlocking_NotApplicable && portContext->event)
277 return true;
278 }
279
280 return false;
281}
282
286bool vuoEventHitInputPort(NodeContext *nodeContext, PortContext_EventBlocking eligibleEventBlocking)
287{
288 for (unsigned long i = 0; i < nodeContext->portContextCount; ++i)
289 {
290 PortContext *portContext = nodeContext->portContexts[i];
291 if (portContext->eventBlocking == eligibleEventBlocking && portContext->event)
292 return true;
293 }
294
295 return false;
296}
297
305{
306 bool eventHitNonBlockingInput = vuoEventHitInputPort(nodeContext, PortContext_EventBlocking_None);
307 bool eventHitDoorInput = vuoEventHitInputPort(nodeContext, PortContext_EventBlocking_Door);
308
309 if (eventHitNonBlockingInput || ! eventHitDoorInput)
310 {
311 for (unsigned long i = 0; i < nodeContext->portContextCount; ++i)
312 {
313 PortContext *portContext = nodeContext->portContexts[i];
315 portContext->event = eventHitNonBlockingInput;
316 }
317 }
318}
319
323void vuoResetNodeContextEvents(struct NodeContext *nodeContext)
324{
325 for (size_t i = 0; i < nodeContext->portContextCount; ++i)
326 nodeContext->portContexts[i]->event = false;
327}
328
332void vuoStartedExecutingEvent(struct NodeContext *nodeContext, unsigned long eventId)
333{
334 std::lock_guard<std::mutex> guard(*static_cast<std::mutex *>(nodeContext->executingEventIdsSync));
335
336 vector<unsigned long> *executingEventIds = static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
337 executingEventIds->clear();
338 executingEventIds->push_back(eventId);
339}
340
344void vuoSpunOffExecutingEvent(struct NodeContext *nodeContext, unsigned long eventId)
345{
346 std::lock_guard<std::mutex> guard(*static_cast<std::mutex *>(nodeContext->executingEventIdsSync));
347
348 vector<unsigned long> *executingEventIds = static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
349 if (! executingEventIds->empty())
350 executingEventIds->push_back(eventId);
351}
352
357bool vuoFinishedExecutingEvent(struct NodeContext *nodeContext, unsigned long eventId)
358{
359 std::lock_guard<std::mutex> guard(*static_cast<std::mutex *>(nodeContext->executingEventIdsSync));
360
361 vector<unsigned long> *executingEventIds = static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
362 auto found = find(executingEventIds->begin(), executingEventIds->end(), eventId);
363 if (found != executingEventIds->end())
364 {
365 executingEventIds->erase(found);
366 return executingEventIds->empty();
367 }
368 return false;
369}
370
375unsigned long vuoGetOneExecutingEvent(struct NodeContext *nodeContext)
376{
377 std::lock_guard<std::mutex> guard(*static_cast<std::mutex *>(nodeContext->executingEventIdsSync));
378
379 vector<unsigned long> *executingEventIds = static_cast< vector<unsigned long> *>(nodeContext->executingEventIds);
380 return executingEventIds->at(0);
381}