Vuo  2.2.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, const std::shared_ptr<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  std::shared_ptr<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  class Private;
206  Private *p;
207 
208  void saturating_semaphore_signal(dispatch_semaphore_t dsema, bool *sent);
209  void saturating_semaphore_wait(dispatch_semaphore_t dsema, bool *sent);
210 
211  VuoRunner(void);
212  void startInternal(void);
213  void listen();
214  void setUpConnections(void);
215  void cleanUpConnections(void);
216  void vuoControlRequestSend(enum VuoControlRequest request, zmq_msg_t *messages, unsigned int messageCount);
217  void vuoLoaderControlRequestSend(enum VuoLoaderControlRequest request, zmq_msg_t *messages, unsigned int messageCount);
218  void vuoControlReplyReceive(enum VuoControlReply expectedReply);
219  void vuoLoaderControlReplyReceive(enum VuoLoaderControlReply expectedReply);
220  string receiveString(string fallbackIfNull);
221  vector<string> receiveListOfStrings(void);
222  vector<Port *> getCachedPublishedPorts(bool input);
223  vector<Port *> refreshPublishedPorts(bool input);
224  bool isInCurrentProcess(void);
225  bool isUsingCompositionLoader(void);
226  void stopBecauseLostContact(string errorMessage);
227  void copyDylibAndChangeId(string dylibPath, string &outputDylibPath);
228 
229  friend void *VuoRunner_listen(void *context);
230  friend class TestControlAndTelemetry;
231  friend class TestVuoRunner;
232 };
233 
234 
252 {
253 public:
260  virtual void receivedTelemetryStats(unsigned long utime, unsigned long stime) = 0;
261 
268  virtual void receivedTelemetryNodeExecutionStarted(string compositionIdentifier, string nodeIdentifier) = 0;
269 
276  virtual void receivedTelemetryNodeExecutionFinished(string compositionIdentifier, string nodeIdentifier) = 0;
277 
287  virtual void receivedTelemetryInputPortUpdated(string compositionIdentifier, string portIdentifier, bool receivedEvent, bool receivedData, string dataSummary) = 0;
288 
298  virtual void receivedTelemetryOutputPortUpdated(string compositionIdentifier, string portIdentifier, bool sentEvent, bool sentData, string dataSummary) = 0;
299 
306  virtual void receivedTelemetryPublishedOutputPortUpdated(VuoRunner::Port *port, bool sentData, string dataSummary) = 0;
307 
314  virtual void receivedTelemetryEventDropped(string compositionIdentifier, string portIdentifier) = 0;
315 
320  virtual void receivedTelemetryError(string message) = 0;
321 
326  virtual void lostContactWithComposition(void) = 0;
327 
328  virtual ~VuoRunnerDelegate() = 0; // Fixes "virtual functions but non-virtual destructor" warning
329 };
330 
334 #define VUO_UNUSED_VARIABLE __attribute__((unused))
335 
342 {
343 private:
344  virtual void receivedTelemetryStats(unsigned long VUO_UNUSED_VARIABLE utime, unsigned long VUO_UNUSED_VARIABLE stime) { }
345  virtual void receivedTelemetryNodeExecutionStarted(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE nodeIdentifier) { }
346  virtual void receivedTelemetryNodeExecutionFinished(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE nodeIdentifier) { }
347  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) { }
348  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) { }
349  virtual void receivedTelemetryPublishedOutputPortUpdated(VuoRunner::Port VUO_UNUSED_VARIABLE *port, bool VUO_UNUSED_VARIABLE sentData, string VUO_UNUSED_VARIABLE dataSummary) { }
350  virtual void receivedTelemetryEventDropped(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE portIdentifier) { }
351  virtual void receivedTelemetryError(string VUO_UNUSED_VARIABLE message) { }
352  virtual void lostContactWithComposition(void) { }
353 };