HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_ApplicationShim.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * COMMENTS:
7  */
8 
9 #ifndef __PDG_APPLICATION_SHIM_H__
10 #define __PDG_APPLICATION_SHIM_H__
11 
12 #include "PDG_API.h"
13 
14 #include "PDG_EvaluationContext.h"
15 #include "PDG_NodeTypes.h"
16 
17 #include <UT/UT_ConcurrentQueue.h>
18 #include <UT/UT_NonCopyable.h>
19 #include <UT/UT_SharedPtr.h>
20 #include <UT/UT_StringHolder.h>
21 
22 #include <SYS/SYS_Types.h>
23 
24 class PDG_FileUtils;
25 class PDG_GraphContext;
26 class PDG_Node;
27 class PDG_Port;
28 class PDG_WorkItem;
29 
31 
32 class UT_WorkBuffer;
33 
34 /**
35  * Shim class for integrating PDG with another application, e.g. Houdini. A
36  * single subclass of this should be installed statically with PDG using
37  * PDG_ApplicationShim::setShim.
38  */
40 {
41 public:
42  /**
43  * Geometry class for binding a PDG geometry attribute to an application-
44  * specific geometry object
45  */
47  {
48  public:
49  Geometry() {}
50  virtual ~Geometry() {}
52 
53  /// Returns the memory usage of the geometry
54  virtual int64 getMemoryUsage(bool inclusive) const = 0;
55 
56  /// Clones the object into a new instance
57  virtual Geometry* copy() const = 0;
58 
59  /// Returns a brief description of the geometry, for UI display
60  virtual UT_StringHolder desc() const = 0;
61  };
62 
63  /**
64  * Node class for binding a PDG node to an application-specific node, such
65  * as a TOP node.
66  */
68  {
69  public:
70  Node() {}
71  virtual ~Node() {}
72  UT_NON_COPYABLE(Node)
73 
74  /// Returns the icon name of the application specific node
75  virtual UT_StringHolder iconName() const = 0;
76 
77  /// Returns a unique id for the application specific node
78  virtual PDG_NodeID nodeID() const = 0;
79 
80  /// Returns true if the app node has cooked at least once, using its
81  /// own definition of cooked
82  virtual bool hasCooked() const = 0;
83 
84  /// Pushes the application specific node as a the active node, for the
85  /// specified thread
86  virtual bool push(int thread) = 0;
87 
88  /// Pops the application specific active node
89  virtual bool pop(int thread) = 0;
90 
91 
92  /// Evaluates an integer parameter on the node
93  virtual bool parmEval(const PDG_Port* port,
94  const PDG_WorkItem* work_item,
95  int index,
96  exint& result,
97  int thread,
98  UT_WorkBuffer& errors) const = 0;
99 
100  /// Evaluates a float parameter on the node
101  virtual bool parmEval(const PDG_Port* port,
102  const PDG_WorkItem* work_item,
103  int index,
104  fpreal& result,
105  int thread,
106  UT_WorkBuffer& errors) const = 0;
107 
108  /// Evaluates a string parameter on the node
109  virtual bool parmEval(const PDG_Port* port,
110  const PDG_WorkItem* work_item,
111  int index,
112  bool expand,
113  UT_StringHolder& result,
114  int thread,
115  UT_WorkBuffer& errors) const = 0;
116 
117  /// Returns the path to the node
118  virtual void path(UT_WorkBuffer& buffer) const = 0;
119  };
120 
121  /**
122  * Graph class for binding a PDG node to an application-specific graph, such
123  * as a TOP parent.
124  */
126  {
127  public:
128  Graph() {}
129  virtual ~Graph() {}
130  UT_NON_COPYABLE(Graph)
131 
132  /// Called when a graph cook begins
133  virtual void startCook(const PDGE_EvaluationOptions&) = 0;
134 
135  /// Called when a graph cook should update progress. Returns true if
136  /// a blocking cook should cancel.
137  virtual bool tickCook(const PDGE_EvaluationOptions&) = 0;
138 
139  /// Called when a graph cook completes
140  virtual void stopCook(
141  const PDGE_EvaluationOptions&,
142  bool canceled) = 0;
143 
144  /// Called to determine the default label for a work item
145  virtual bool defaultWorkItemLabel(
146  UT_StringHolder& label) const = 0;
147  };
148 
149  /**
150  * Base class for a task that can be queued. Should be subclassed to
151  * implement a concrete task type that stores data and logic.
152  */
154  {
155  public:
156  DeferredTask(
157  PDG_GraphContext* context,
158  const PDG_Node* node,
159  const PDG_WorkItem* work_item,
161  virtual ~DeferredTask() {}
162 
163  /// Evaluates the task
164  void execute();
165 
166  /// Waits for the task to execute. Returns true if the task completed,
167  /// or false if it was interupted for some reason.
168  bool wait();
169 
170  protected:
171  /// Called when the task is evaluated
172  virtual void evaluate() = 0;
173 
174  protected:
176  const PDG_Node* myNode;
178 
181  int myCookId;
183  };
184 
185  /// Managed pointer to a deferred task
187  using DeferredQueue = UT_ConcurrentQueue<TaskPtr>;
188 
189 public:
190  /// Adds a new Python search path to the PDG type system
191  static void addPythonPath(const UT_StringHolder& path);
192 
193  /// Returns true if the integration is allowed to use farm schedulers
194  static bool canUseFarm();
195 
196  /// Returns true if the application-specific work item dependency is
197  /// dirty
198  static bool areDependenciesDirty(fpreal t);
199 
200  /// Notifies the application that the global PDG work item has been changed
201  static void dirtyDependencies(fpreal t, const UT_StringHolder& name);
202 
203  /// Adds a dependency on the global PDG work item for the specified thread
204  static void addDependency(int thread, const UT_StringHolder& name);
205 
206  /// Queries the name of the evaluating channel for the specified thread
207  static bool evaluatingChannel(UT_WorkBuffer& buffer,
208  bool full_path,
209  int thread);
210 
211  /// Queries the value of a global variable
212  static bool getVariable(const char* name, UT_StringHolder& value);
213 
214  /// Sets the value of a global variable
215  static void setVariable(const char* name, const UT_StringHolder& value);
216 
217  /// Returns true if the file in the specified path is cached
218  static bool checkCached(const PDG_FileUtils& file_utils,
219  const UT_StringHolder& path,
220  const UT_StringHolder& tag);
221 
222  /// Queue a task with the deferred processing queue, to be run on the
223  /// main thread.
224  template <typename Task, typename... Args>
225  static TaskPtr pushDeferred(Args&&... args)
226  {
227  TaskPtr new_task = UTmakeShared<Task>(
228  std::forward<Args>(args)...);
229  pushDeferredTask(new_task);
230  return new_task;
231  }
232 
233  /// Runs a functor with the application unlocked.
234  template <typename Func>
235  static void unlockedExecute(const Func& func)
236  {
237  bool did_unlock = false;
238  if (theAppShim)
239  did_unlock = theAppShim->unlockApp();
240 
241  func();
242 
243  if (did_unlock)
244  theAppShim->lockApp();
245  }
246 
247  /// Runs the application shims logic for a main thread event tick. The
248  /// base application instance will drain pending deferred events from the
249  /// queue and run some of them.
250  static bool tickMainThread();
251 
252  /// Enable experimental features
253  static bool isExperimental();
254 
255  /// Saves the current application scene. Returns false if the application
256  /// wants to abort the current operationi because of save conflict or a
257  /// request to cancel, otherwise returns true.
258  static bool trySaveScene();
259 
260  /// Sets the shared static shim instance. This can only be called once
261  /// during the lifetime of the program.
262  static void setShim(PDG_ApplicationShim* shim);
263 
264  /// Constructs a new application shim and caches configuration vars
266  virtual ~PDG_ApplicationShim() {}
267 
268 protected:
269  virtual void addAppPythonPath(const UT_StringHolder& path) const = 0;
270 
271  virtual bool canAppUseFarm() const = 0;
272  virtual bool areAppDependenciesDirty(fpreal t) const = 0;
273  virtual void dirtyAppDependencies(fpreal t,
274  const UT_StringHolder& name) = 0;
275  virtual void addAppDependency(int thread,
276  const UT_StringHolder& name) = 0;
277  virtual bool evaluatingAppChannel(UT_WorkBuffer& buffer,
278  bool full_path,
279  int thread) = 0;
280  virtual bool getAppVariable(const char* name,
281  UT_StringHolder& value) const = 0;
282  virtual void setAppVariable(const char* name,
283  const UT_StringHolder& value) = 0;
284  virtual bool checkAppCached(const PDG_FileUtils& file_utils,
285  const UT_StringHolder& path,
286  const UT_StringHolder& tag) const = 0;
287  virtual bool tickAppMainThread();
288 
289  virtual bool unlockApp() const = 0;
290  virtual bool lockApp() const = 0;
291 
292  virtual bool trySaveAppScene() const = 0;
293 
294 private:
295  static void pushDeferredTask(TaskPtr& ptr);
296 
297 private:
298  static PDG_ApplicationShim* theAppShim;
299 
300  DeferredQueue myDeferredTasks;
301  bool myIsExperimental;
302 };
303 
304 #endif
*pool push(my_func, arg1,...)
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:623
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
#define PDG_API
Definition: PDG_API.h:23
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
State
Evaluation context state.
static TaskPtr pushDeferred(Args &&...args)
int64 exint
Definition: SYS_Types.h:125
**But if you need a result
Definition: thread.h:613
PDG_EvaluationContext::State myState
UT_ConcurrentQueue< TaskPtr > DeferredQueue
static void unlockedExecute(const Func &func)
Runs a functor with the application unlocked.
Definition: core.h:760
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
UT_SharedPtr< DeferredTask > TaskPtr
Managed pointer to a deferred task.
long long int64
Definition: SYS_Types.h:116
GLuint const GLchar * name
Definition: glcorearb.h:786
GLdouble t
Definition: glad.h:2397
*tasks wait()
**Note that the tasks the is the thread number *for the or if it s being executed by a non pool thread(this *can happen in cases where the whole pool is occupied and the calling *thread contributes to running the work load).**Thread pool.Have fun
GLenum func
Definition: glcorearb.h:783
fpreal64 fpreal
Definition: SYS_Types.h:277
int PDG_NodeID
Node ID type.
Definition: PDG_NodeTypes.h:29
GLuint index
Definition: glcorearb.h:786
auto ptr(T p) -> const void *
Definition: format.h:2448
**If you just want to fire and args
Definition: thread.h:609
Definition: core.h:1131