Vuo  2.3.1
VuoRunner.hh
Go to the documentation of this file.
1 
10 #pragma once
11 
12 #include <map>
13 #include <set>
14 
15 #include "VuoMacOSSDKWorkaround.h"
16 #include <dispatch/dispatch.h>
17 #include "VuoTelemetry.h"
18 class VuoRunnerDelegate;
20 
21 #pragma clang diagnostic push
22 #pragma clang diagnostic ignored "-Wdocumentation"
23 #include "json-c/json.h"
24 #pragma clang diagnostic pop
25 
26 
89 class VuoRunner
90 {
91 public:
92  class Port;
93  static VuoRunner * newSeparateProcessRunnerFromExecutable(string executablePath, string sourceDir, bool continueIfRunnerDies, bool deleteExecutableWhenFinished);
94  static VuoRunner * newSeparateProcessRunnerFromDynamicLibrary(string compositionLoaderPath, string compositionDylibPath, const std::shared_ptr<VuoRunningCompositionLibraries> &runningCompositionLibraries, string sourceDir, bool continueIfRunnerDies = false, bool deleteDylibsWhenFinished = false);
95  static VuoRunner * newCurrentProcessRunnerFromDynamicLibrary(string dylibPath, string sourceDir, bool deleteDylibWhenFinished = false);
96  ~VuoRunner(void);
97  void setRuntimeChecking(bool runtimeCheckingEnabled);
98  void start(void);
99  void startPaused(void);
100  void runOnMainThread(void);
101  void drainMainDispatchQueue(void);
102  void pause(void);
103  void unpause(void);
104  void replaceComposition(string compositionDylibPath, string compositionDiff);
105  void stop(void);
106  void waitUntilStopped(void);
107  void setPublishedInputPortValues(map<Port *, json_object *> portsAndValues);
108  void firePublishedInputPortEvent(Port *port);
109  void firePublishedInputPortEvent(const set<Port *> &ports);
113  vector<Port *> getPublishedInputPorts(void);
114  vector<Port *> getPublishedOutputPorts(void);
115  Port * getPublishedInputPortWithName(string name);
116  Port * getPublishedOutputPortWithName(string name);
117  void setInputPortValue(string compositionIdentifier, string portIdentifier, json_object *value);
118  void fireTriggerPortEvent(string compositionIdentifier, string portIdentifier);
119  json_object * getInputPortValue(string compositionIdentifier, string portIdentifier);
120  json_object * getOutputPortValue(string compositionIdentifier, string portIdentifier);
121  string getInputPortSummary(string compositionIdentifier, string portIdentifier);
122  string getOutputPortSummary(string compositionIdentifier, string portIdentifier);
123  string subscribeToInputPortTelemetry(string compositionIdentifier, string portIdentifier);
124  string subscribeToOutputPortTelemetry(string compositionIdentifier, string portIdentifier);
125  void unsubscribeFromInputPortTelemetry(string compositionIdentifier, string portIdentifier);
126  void unsubscribeFromOutputPortTelemetry(string compositionIdentifier, string portIdentifier);
127  void subscribeToEventTelemetry(string compositionIdentifier);
128  void unsubscribeFromEventTelemetry(string compositionIdentifier);
129  void subscribeToAllTelemetry(string compositionIdentifier);
130  void unsubscribeFromAllTelemetry(string compositionIdentifier);
131  bool isStopped(void);
132  void setDelegate(VuoRunnerDelegate *delegate);
133  pid_t getCompositionPid();
134 
142  class Port
143  {
144  public:
145  Port(string name, string type, json_object *details);
146  string getName(void);
147  string getType(void);
148  json_object *getDetails(void);
149 
150  friend class VuoRunner;
151 
152  private:
153  string name;
154  string type;
155  json_object *details;
156  };
157 
158 private:
159  string executablePath;
160  string dylibPath;
161  void *dylibHandle;
162  std::shared_ptr<VuoRunningCompositionLibraries> dependencyLibraries;
163  bool shouldContinueIfRunnerDies;
164  bool shouldDeleteBinariesWhenFinished;
165  string sourceDir;
166  bool isRuntimeCheckingEnabled;
167  bool paused;
168  bool stopped;
169  bool lostContact;
170  string listenError;
171  bool listenCanceled;
172  dispatch_semaphore_t stoppedSemaphore;
173  dispatch_semaphore_t terminatedZMQContextSemaphore;
174  dispatch_semaphore_t beganListeningSemaphore;
175  dispatch_semaphore_t endedListeningSemaphore;
176  dispatch_semaphore_t lastFiredEventSemaphore;
177  bool lastFiredEventSignaled;
178  dispatch_queue_t controlQueue;
179  pid_t compositionPid;
180  int runnerReadCompositionWritePipe[2];
181 
182  void *ZMQContext;
183  void *ZMQSelfReceive;
184  void *ZMQSelfSend;
185  void *ZMQControl;
186  void *ZMQTelemetry;
187  void *ZMQLoaderControl;
188  string ZMQControlURL;
189  string ZMQLoaderControlURL;
190  string ZMQTelemetryURL;
191 
192  VuoRunnerDelegate *delegate;
193  dispatch_queue_t delegateQueue;
194 
195  vector<Port *> publishedInputPorts;
196  vector<Port *> publishedOutputPorts;
197  bool arePublishedInputPortsCached;
198  bool arePublishedOutputPortsCached;
199 
200  class Private;
201  Private *p;
202 
203  void saturating_semaphore_signal(dispatch_semaphore_t dsema, bool *sent);
204  void saturating_semaphore_wait(dispatch_semaphore_t dsema, bool *sent);
205 
206  VuoRunner(void);
207  void startInternal(void);
208  void listen();
209  void setUpConnections(void);
210  void cleanUpConnections(void);
211  void vuoControlRequestSend(enum VuoControlRequest request, zmq_msg_t *messages, unsigned int messageCount);
212  void vuoLoaderControlRequestSend(enum VuoLoaderControlRequest request, zmq_msg_t *messages, unsigned int messageCount);
213  void vuoControlReplyReceive(enum VuoControlReply expectedReply);
214  void vuoLoaderControlReplyReceive(enum VuoLoaderControlReply expectedReply);
215  string receiveString(string fallbackIfNull);
216  vector<string> receiveListOfStrings(void);
217  vector<Port *> getCachedPublishedPorts(bool input);
218  vector<Port *> refreshPublishedPorts(bool input);
219  bool isInCurrentProcess(void);
220  bool isUsingCompositionLoader(void);
221  void stopBecauseLostContact(string errorMessage);
222  void copyDylibAndChangeId(string dylibPath, string &outputDylibPath);
223 
224  friend void *VuoRunner_listen(void *context);
225  friend class TestControlAndTelemetry;
226  friend class TestVuoRunner;
227 };
228 
229 
247 {
248 public:
255  virtual void receivedTelemetryStats(unsigned long utime, unsigned long stime) = 0;
256 
263  virtual void receivedTelemetryNodeExecutionStarted(string compositionIdentifier, string nodeIdentifier) = 0;
264 
271  virtual void receivedTelemetryNodeExecutionFinished(string compositionIdentifier, string nodeIdentifier) = 0;
272 
282  virtual void receivedTelemetryInputPortUpdated(string compositionIdentifier, string portIdentifier, bool receivedEvent, bool receivedData, string dataSummary) = 0;
283 
293  virtual void receivedTelemetryOutputPortUpdated(string compositionIdentifier, string portIdentifier, bool sentEvent, bool sentData, string dataSummary) = 0;
294 
301  virtual void receivedTelemetryPublishedOutputPortUpdated(VuoRunner::Port *port, bool sentData, string dataSummary) = 0;
302 
309  virtual void receivedTelemetryEventDropped(string compositionIdentifier, string portIdentifier) = 0;
310 
315  virtual void receivedTelemetryError(string message) = 0;
316 
321  virtual void lostContactWithComposition(void) = 0;
322 
323  virtual ~VuoRunnerDelegate() = 0; // Fixes "virtual functions but non-virtual destructor" warning
324 };
325 
329 #define VUO_UNUSED_VARIABLE __attribute__((unused))
330 
337 {
338 private:
339  virtual void receivedTelemetryStats(unsigned long VUO_UNUSED_VARIABLE utime, unsigned long VUO_UNUSED_VARIABLE stime) { }
340  virtual void receivedTelemetryNodeExecutionStarted(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE nodeIdentifier) { }
341  virtual void receivedTelemetryNodeExecutionFinished(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE nodeIdentifier) { }
342  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) { }
343  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) { }
344  virtual void receivedTelemetryPublishedOutputPortUpdated(VuoRunner::Port VUO_UNUSED_VARIABLE *port, bool VUO_UNUSED_VARIABLE sentData, string VUO_UNUSED_VARIABLE dataSummary) { }
345  virtual void receivedTelemetryEventDropped(string VUO_UNUSED_VARIABLE compositionIdentifier, string VUO_UNUSED_VARIABLE portIdentifier) { }
346  virtual void receivedTelemetryError(string VUO_UNUSED_VARIABLE message) { }
347  virtual void lostContactWithComposition(void) { }
348 };