Vuo  2.0.0
VuoRunner.hh
Go to the documentation of this file.
1 
10 #pragma once
11 
12 #include <map>
13 #include <set>
14 
15 #include <dispatch/dispatch.h>
16 #include "VuoTelemetry.h"
17 class VuoRunnerDelegate;
19 
20 #if (__clang_major__ == 3 && __clang_minor__ >= 2) || __clang_major__ > 3
21  #define VUO_CLANG_32_OR_LATER
22 #endif
23 
24 #pragma clang diagnostic push
25 #ifdef VUO_CLANG_32_OR_LATER
26  #pragma clang diagnostic ignored "-Wdocumentation"
27 #endif
28 #include "json-c/json.h"
29 #pragma clang diagnostic pop
30 
31 
94 class VuoRunner
95 {
96 public:
97  class Port;
98  static VuoRunner * newSeparateProcessRunnerFromExecutable(string executablePath, string sourceDir, bool continueIfRunnerDies, bool deleteExecutableWhenFinished);
99  static VuoRunner * newSeparateProcessRunnerFromDynamicLibrary(string compositionLoaderPath, string compositionDylibPath, VuoRunningCompositionLibraries *runningCompositionLibraries, string sourceDir, bool continueIfRunnerDies = false, bool deleteDylibsWhenFinished = false);
100  static VuoRunner * newCurrentProcessRunnerFromDynamicLibrary(string dylibPath, string sourceDir, bool deleteDylibWhenFinished = false);
101  ~VuoRunner(void);
102  void setRuntimeChecking(bool runtimeCheckingEnabled);
103  void start(void);
104  void startPaused(void);
105  void runOnMainThread(void);
106  void drainMainDispatchQueue(void);
107  void pause(void);
108  void unpause(void);
109  void replaceComposition(string compositionDylibPath, string compositionDiff);
110  void stop(void);
111  void waitUntilStopped(void);
112  void setPublishedInputPortValues(map<Port *, json_object *> portsAndValues);
113  void firePublishedInputPortEvent(Port *port);
114  void firePublishedInputPortEvent(const set<Port *> &ports);
118  vector<Port *> getPublishedInputPorts(void);
119  vector<Port *> getPublishedOutputPorts(void);
120  Port * getPublishedInputPortWithName(string name);
121  Port * getPublishedOutputPortWithName(string name);
122  void setInputPortValue(string compositionIdentifier, string portIdentifier, json_object *value);
123  void fireTriggerPortEvent(string compositionIdentifier, string portIdentifier);
124  json_object * getInputPortValue(string compositionIdentifier, string portIdentifier);
125  json_object * getOutputPortValue(string compositionIdentifier, string portIdentifier);
126  string getInputPortSummary(string compositionIdentifier, string portIdentifier);
127  string getOutputPortSummary(string compositionIdentifier, string portIdentifier);
128  string subscribeToInputPortTelemetry(string compositionIdentifier, string portIdentifier);
129  string subscribeToOutputPortTelemetry(string compositionIdentifier, string portIdentifier);
130  void unsubscribeFromInputPortTelemetry(string compositionIdentifier, string portIdentifier);
131  void unsubscribeFromOutputPortTelemetry(string compositionIdentifier, string portIdentifier);
132  void subscribeToEventTelemetry(string compositionIdentifier);
133  void unsubscribeFromEventTelemetry(string compositionIdentifier);
134  void subscribeToAllTelemetry(string compositionIdentifier);
135  void unsubscribeFromAllTelemetry(string compositionIdentifier);
136  bool isStopped(void);
137  void setDelegate(VuoRunnerDelegate *delegate);
138  pid_t getCompositionPid();
139 
147  class Port
148  {
149  public:
150  Port(string name, string type, json_object *details);
151  string getName(void);
152  string getType(void);
153  json_object *getDetails(void);
154 
155  friend class VuoRunner;
156 
157  private:
158  string name;
159  string type;
160  json_object *details;
161  };
162 
163 private:
164  string executablePath;
165  string dylibPath;
166  void *dylibHandle;
167  VuoRunningCompositionLibraries *dependencyLibraries;
168  bool shouldContinueIfRunnerDies;
169  bool shouldDeleteBinariesWhenFinished;
170  string sourceDir;
171  bool isRuntimeCheckingEnabled;
172  bool paused;
173  bool stopped;
174  bool lostContact;
175  string listenError;
176  bool listenCanceled;
177  dispatch_semaphore_t stoppedSemaphore;
178  dispatch_semaphore_t terminatedZMQContextSemaphore;
179  dispatch_semaphore_t beganListeningSemaphore;
180  dispatch_semaphore_t endedListeningSemaphore;
181  dispatch_semaphore_t lastFiredEventSemaphore;
182  bool lastFiredEventSignaled;
183  dispatch_queue_t controlQueue;
184  pid_t compositionPid;
185  int runnerReadCompositionWritePipe[2];
186 
187  void *ZMQContext;
188  void *ZMQSelfReceive;
189  void *ZMQSelfSend;
190  void *ZMQControl;
191  void *ZMQTelemetry;
192  void *ZMQLoaderControl;
193  string ZMQControlURL;
194  string ZMQLoaderControlURL;
195  string ZMQTelemetryURL;
196 
197  VuoRunnerDelegate *delegate;
198  dispatch_queue_t delegateQueue;
199 
200  vector<Port *> publishedInputPorts;
201  vector<Port *> publishedOutputPorts;
202  bool arePublishedInputPortsCached;
203  bool arePublishedOutputPortsCached;
204 
205  void saturating_semaphore_signal(dispatch_semaphore_t dsema, bool *sent);
206  void saturating_semaphore_wait(dispatch_semaphore_t dsema, bool *sent);
207 
208  VuoRunner(void);
209  void startInternal(void);
210  void listen();
211  void setUpConnections(void);
212  void cleanUpConnections(void);
213  void vuoControlRequestSend(enum VuoControlRequest request, zmq_msg_t *messages, unsigned int messageCount);
214  void vuoLoaderControlRequestSend(enum VuoLoaderControlRequest request, zmq_msg_t *messages, unsigned int messageCount);
215  void vuoControlReplyReceive(enum VuoControlReply expectedReply);
216  void vuoLoaderControlReplyReceive(enum VuoLoaderControlReply expectedReply);
217  string receiveString(string fallbackIfNull);
218  vector<string> receiveListOfStrings(void);
219  vector<Port *> getCachedPublishedPorts(bool input);
220  vector<Port *> refreshPublishedPorts(bool input);
221  bool isInCurrentProcess(void);
222  bool isUsingCompositionLoader(void);
223  void stopBecauseLostContact(string errorMessage);
224  void copyDylibAndChangeId(string dylibPath, string &outputDylibPath);
225 
226  friend void *VuoRunner_listen(void *context);
227  friend class TestControlAndTelemetry;
228  friend class TestVuoRunner;
229 };
230 
231 
249 {
250 public:
257  virtual void receivedTelemetryStats(unsigned long utime, unsigned long stime) = 0;
258 
265  virtual void receivedTelemetryNodeExecutionStarted(string compositionIdentifier, string nodeIdentifier) = 0;
266 
273  virtual void receivedTelemetryNodeExecutionFinished(string compositionIdentifier, string nodeIdentifier) = 0;
274 
284  virtual void receivedTelemetryInputPortUpdated(string compositionIdentifier, string portIdentifier, bool receivedEvent, bool receivedData, string dataSummary) = 0;
285 
295  virtual void receivedTelemetryOutputPortUpdated(string compositionIdentifier, string portIdentifier, bool sentEvent, bool sentData, string dataSummary) = 0;
296 
303  virtual void receivedTelemetryPublishedOutputPortUpdated(VuoRunner::Port *port, bool sentData, string dataSummary) = 0;
304 
311  virtual void receivedTelemetryEventDropped(string compositionIdentifier, string portIdentifier) = 0;
312 
317  virtual void receivedTelemetryError(string message) = 0;
318 
323  virtual void lostContactWithComposition(void) = 0;
324 
325  virtual ~VuoRunnerDelegate() = 0; // Fixes "virtual functions but non-virtual destructor" warning
326 };
327 
331 #define VUO_UNUSED_VARIABLE __attribute__((unused))
332 
339 {
340 private:
341  virtual void receivedTelemetryStats(unsigned long VUO_UNUSED_VARIABLE utime, unsigned long VUO_UNUSED_VARIABLE stime) { }
342  virtual void receivedTelemetryNodeExecutionStarted(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE nodeIdentifier) { }
343  virtual void receivedTelemetryNodeExecutionFinished(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE nodeIdentifier) { }
344  virtual void receivedTelemetryInputPortUpdated(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE portIdentifier, bool VUO_UNUSED_VARIABLE receivedEvent, bool VUO_UNUSED_VARIABLE receivedData, string VUO_UNUSED_VARIABLE dataSummary) { }
345  virtual void receivedTelemetryOutputPortUpdated(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE portIdentifier, bool VUO_UNUSED_VARIABLE sentEvent, bool VUO_UNUSED_VARIABLE sentData, string VUO_UNUSED_VARIABLE dataSummary) { }
346  virtual void receivedTelemetryPublishedOutputPortUpdated(VuoRunner::Port VUO_UNUSED_VARIABLE *port, bool VUO_UNUSED_VARIABLE sentData, string VUO_UNUSED_VARIABLE dataSummary) { }
347  virtual void receivedTelemetryEventDropped(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE portIdentifier) { }
348  virtual void receivedTelemetryError(string VUO_UNUSED_VARIABLE message) { }
349  virtual void lostContactWithComposition(void) { }
350 };