HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_Port.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_PORT_H__
10 #define __PDG_PORT_H__
11 
12 #include "PDG_API.h"
13 
14 #include "PDG_Conditional.h"
15 #include "PDG_EvaluationContext.h"
16 #include "PDG_NodeTypes.h"
17 
18 #include <PDGT/PDGT_Value.h>
19 
20 #include <PY/PY_CPythonAPI.h>
21 #include <PY/PY_CompiledCode.h>
22 
23 #include <UT/UT_Array.h>
24 #include <UT/UT_StringArray.h>
25 #include <UT/UT_StringHolder.h>
26 #include <UT/UT_StringMap.h>
27 #include <UT/UT_UniquePtr.h>
28 #include <UT/UT_VectorTypes.h>
29 #include <UT/UT_WorkBuffer.h>
30 
31 #include <type_traits>
32 
33 class PDG_Node;
34 class PDG_NodeInterface;
36 
37 class UT_JSONWriter;
38 
40 {
41 public:
43  {
44  pdg_Connection(PDG_Port* port, bool is_ref)
45  : myConnectedPort(port)
46  , myIsReference(is_ref)
47  {
48  }
49 
52  };
53 
56 
64 
65 public:
67  const PDG_WorkItemDataType* data_type,
68  PDG_PortType portType,
69  const UT_StringHolder& name,
70  const UT_StringHolder& label,
71  int size,
72  bool ordered = true,
73  bool custom = false,
74  bool builtin = false);
75 
76  virtual ~PDG_Port();
77 
78  int64 getMemoryUsage(bool inclusive) const;
79 
80  void addTag(const UT_StringHolder& tag);
81 
82  bool connect(
83  PDG_Port* port,
84  bool reference,
85  bool inverse = true);
86  bool disconnect(PDG_Port* port, bool inverse = true);
87  bool disconnectAll();
88 
89  bool isConnected();
90  bool canConnectTo(PDG_Port* port) const;
91  bool isConnectedTo(
92  PDG_Port* port,
93  bool reference) const;
94 
95  void connectedNodes(
96  PDG_NodeArray& nodes,
97  bool filter_bypassed,
98  bool filter_reference) const;
99  int connectionCount(
100  bool filter_bypassed,
101  bool filter_reference) const;
102  const ConnectionArray& connections() const;
103  void connectedPorts(
104  PDG_PortArray& ports,
105  bool filter_bypassed,
106  bool filter_reference) const;
107 
108  PDG_NodeInterface* owner() const;
109  PDG_Node* node() const;
110 
111  const PDG_WorkItemDataType* workItemDataType() const;
112  void setWorkItemDataType(
113  const PDG_WorkItemDataType* data_type);
114  PDG_PortType portType() const;
115 
116  PDGT_Value* value(int index);
117  const PDGT_Value* value(int index) const;
118  PDGT_Value* defaultValue(int index);
119  const PDGT_Value* defaultValue(int index) const;
120 
121  void setExpression(int index,
122  const UT_StringHolder& expression,
123  bool multi);
124  void setIsAppParm(int index, bool app_parm);
125  const UT_StringHolder& expression(int index) const;
126  bool isAppParm(int index) const;
127  const ExpressionVars& expressionVars() const;
128  bool hasExpressionVars() const;
129  bool addExpressionVar(const UT_StringHolder& var_name,
130  const UT_StringHolder& var_type);
131  void setExpressionVars(const ExpressionVars& vars);
132 
133  bool multiExpression(int index) const;
134  bool hasExpression(int index) const;
135 
136  bool isEnabled() const;
137  void setIsEnabled(bool enabled);
138 
139  bool hasWorkItemExpression() const;
140  const UT_StringArray& expressionAttribs() const;
141  void resetExpressionAttribs();
142  void setExpressionAttribs(const UT_StringArray& attribs);
143 
144  int evaluationOrigin() const;
145  void setEvaluationOrigin(int origin);
146 
147  void setDisplayType(int display_type);
148  void addDisplayType(PDG_PortDisplayType display_type);
149  int displayType() const;
150  bool hasDisplayType(PDG_PortDisplayType display_type);
151 
152  void setDisplayMenuList(const UT_StringArray& list);
153  const UT_StringArray& displayMenuList() const;
154 
155  void setDisplayMenuScript(
156  const UT_StringHolder& script);
157  const UT_StringHolder& displayMenuScript() const;
158 
159  const UT_StringArray& tags() const;
160  const UT_StringHolder& name() const;
161  const UT_StringHolder& label() const;
162 
163  const PDG_Conditional& cookCondition() const;
164  void setCookCondition(const UT_StringHolder& pattern);
165 
166  const UT_StringHolder& disableCondition() const;
167  void setDisableCondition(
168  const UT_StringHolder& condition);
169 
170  bool hasTag(const UT_StringHolder& tag) const;
171 
172  void setDataType(PDGT_Value::DataType type);
174 
175  UT_StringArray resultTypeTags(bool strip_prefix) const;
176 
177  bool isOrdered() const;
178  bool isCustom() const;
179  bool isBuiltin() const;
180  int size() const;
181 
182  bool asJSON(
183  UT_JSONWriter& writer,
184  bool skip_defaults) const;
185  static bool fromJSON(
186  const UT_JSONValue* value,
187  PDG_NodeInterface* interface,
188  UT_WorkBuffer& errors);
189 
190  UT_StringHolder dataTypeAsString() const;
191 
192  static void splitName(const UT_StringHolder& full_name,
193  UT_StringHolder& node,
194  UT_StringHolder& port);
195 
196  bool evaluate(
197  int index,
198  fpreal& result,
199  const PDG_WorkItem* work_item,
200  UT_WorkBuffer& errors) const;
201  bool evaluate(
203  const PDG_WorkItem* work_item,
204  UT_WorkBuffer& errors) const;
205 
206  bool evaluate(
207  int index,
208  exint& result,
209  const PDG_WorkItem* work_item,
210  UT_WorkBuffer& errors) const;
211  bool evaluate(
212  int index,
213  bool& result,
214  const PDG_WorkItem* work_item,
215  UT_WorkBuffer& errors) const;
217  bool evaluate(
218  int index,
219  T& result,
220  const PDG_WorkItem* work_item,
221  UT_WorkBuffer& errors)
222  {
223  exint temp;
224  bool eval = evaluate(
225  index, temp, work_item, errors);
226 
227  if (eval)
228  {
229  result = (T)(temp);
230  return true;
231  }
232 
233  return false;
234  }
235 
236  bool evaluate(
238  const PDG_WorkItem* work_item,
239  UT_WorkBuffer& errors) const;
240 
241  bool evaluate(
242  int index,
244  const PDG_WorkItem* work_item,
245  UT_WorkBuffer& errors) const;
246  bool evaluate(
248  const PDG_WorkItem* work_item,
249  UT_WorkBuffer& errors) const;
250 
251  bool evaluateRaw(
252  int index,
254  const PDG_WorkItem* work_item,
255  UT_WorkBuffer& errors) const;
256  bool evaluateRaw(
258  const PDG_WorkItem* work_item,
259  UT_WorkBuffer& errors) const;
260 
261 
262  UT_StringHolder expressionFile(int index) const;
263 
264 private:
265  UT_StringHolder postReplace(const UT_StringHolder& input,
266  const PDG_WorkItem* work_item,
267  bool always_replace) const;
268  exint postReplace(exint input,
269  const PDG_WorkItem* work_item,
270  bool always_replace) const;
271  fpreal postReplace(fpreal input,
272  const PDG_WorkItem* work_item,
273  bool always_replace) const;
274 
275  bool appEval(const UT_StringHolder& name,
276  int index,
277  bool expand,
278  fpreal& result,
279  const PDG_WorkItem* work_item,
280  int thread,
281  UT_WorkBuffer& errors) const;
282  bool appEval(const UT_StringHolder& name,
283  int index,
284  bool expand,
285  exint& result,
286  const PDG_WorkItem* work_item,
287  int thread,
288  UT_WorkBuffer& errors) const;
289  bool appEval(const UT_StringHolder& name,
290  int index,
291  bool expand,
293  const PDG_WorkItem* work_item,
294  int thread,
295  UT_WorkBuffer& errors) const;
296 
297  bool canEvaluate(int index,
298  UT_WorkBuffer& errors) const;
299  bool isParent(const PDG_WorkItem* work_item) const;
300 
301  template <typename T>
302  bool evaluateTyped(int index,
303  bool expand,
304  T& result,
305  const PDG_WorkItem* work_item,
306  UT_WorkBuffer& errors) const
307  {
308  if (index < 0)
309  index += myPortValues.size();
310 
311  if (!canEvaluate(index, errors))
312  return false;
313 
314  const pdg_PortValue& val = myPortValues[index];
315  int thread = SYSgetSTID();
316  T temp;
317 
318  // set the scope parent state to true if we want to use
319  // a workitem that is not from this node.
321  thread, work_item, isParent(work_item));
322  const PDG_WorkItem* local_item =
323  PDG_EvaluationContext::activeWorkItem(thread);
324 
325  if (val.isAppParm())
326  {
327  if (!appEval(
328  myName, index, expand, result, local_item, thread, errors))
329  {
331  return false;
332  }
333 
334  return true;
335  }
336 
337  if (!val.hasExpression())
338  {
339  val.myValue.value(temp);
340  result = postReplace(temp, local_item, true);
341  return true;
342  }
343 
344  if (PDG_EvaluationContext::evaluate(thread, *val.myPyExpression,
345  temp, errors) != PDG_EvaluationContext::eResultSuccess)
346  {
347  errors.appendFormat(" ({})", expressionFile(index));
348  return false;
349  }
350 
351  result = postReplace(temp, local_item, true);
352  return true;
353  }
354 
355  template <typename T>
356  bool evaluateArray(bool expand,
357  UT_Array<T>& result,
358  const PDG_WorkItem* work_item,
359  UT_WorkBuffer& errors) const
360  {
361  if (myPortType != PDG_PortType::eParameter)
362  {
363  errors.appendFormat("Port '{}' is not a parameter", myName);
364  return false;
365  }
366 
367  int thread = SYSgetSTID();
369  thread, work_item, isParent(work_item));
370  const PDG_WorkItem* local_item =
372 
373  int index = 0;
374  for (auto&& port_val : myPortValues)
375  {
376  T temp;
377  if (port_val.isAppParm())
378  {
379  if (!appEval(myName, index, expand, temp,
380  local_item, thread, errors))
381  {
383  thread, true);
384  return false;
385  }
386  }
387  else if (!port_val.hasExpression())
388  port_val.myValue.value(temp);
389  else
390  {
392  thread,
393  *port_val.myPyExpression,
394  temp, errors) != PDG_EvaluationContext::eResultSuccess)
395  {
396  errors.appendFormat(" ({})", expressionFile(result.size()));
397  return false;
398  }
399  }
400  result.append(postReplace(temp, local_item, true));
401  index++;
402  }
403 
404  return true;
405  }
406 
407 private:
408  struct pdg_PortValue
409  {
410  pdg_PortValue()
411  : myPyExpression(nullptr)
412  , myMultiExpression(false)
413  , myIsAppParm(false)
414  {
415  }
416 
417  ~pdg_PortValue()
418  {
419  // If Python is no longer active, we need to leak the contents of
420  // the expression data since it won't be possible to safely free it
421  if (myPyExpression && !PY_Py_IsInitialized())
422  myPyExpression.release();
423  }
424 
425  int64 getMemoryUsage(bool inclusive) const
426  {
427  int64 mem = inclusive ? sizeof(*this) : 0;
428  mem += myExpression.getMemoryUsage(false);
429  if (myPyExpression)
430  mem += myPyExpression->getMemoryUsage(true);
431  return mem;
432  }
433 
434  inline bool hasExpression() const { return myExpression.length() > 0; }
435  inline bool isAppParm() const { return myIsAppParm; }
436 
437  PDGT_Value myValue;
438  UT_StringHolder myExpression;
440  myPyExpression;
441 
442  bool myMultiExpression;
443  bool myIsAppParm;
444  };
445 
446  PDG_NodeInterface* myOwner;
447  ConnectionArray myConnections;
448  const PDG_WorkItemDataType* myWorkItemDataType;
449 
450  PDG_Conditional myCookCondition;
451 
452  PDG_PortType myPortType;
453  UT_StringHolder myName;
454  UT_StringHolder myLabel;
455  UT_StringHolder myDisableCondition;
456 
457  UT_Array<pdg_PortValue> myPortValues;
458 
459  UT_StringArray myTags;
460  UT_StringArray myExpressionAttribs;
461  ExpressionVars myExpressionVars;
462 
463  int mySize;
464  int myEvaluationOrigin;
465 
466  bool myEnabledFlag;
467  bool myOrderedFlag;
468  bool myCustomFlag;
469  bool myBuiltinFlag;
470  bool myHasExpressionVars;
471 
472  PDGT_Value::DataType myDataType;
473  int myDisplayType;
474  UT_StringArray myDisplayMenuList;
475  UT_StringHolder myDisplayMenuScript;
476 };
477 
478 #endif /* __PDG_PORT_H__ */
static const UT_StringHolder theTypeKey
Definition: PDG_Port.h:58
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
GLsizei const GLfloat * value
Definition: glcorearb.h:824
static const UT_StringHolder theValueKey
Definition: PDG_Port.h:63
#define PDG_API
Definition: PDG_API.h:23
int64 exint
Definition: SYS_Types.h:125
PDG_Port * myConnectedPort
Definition: PDG_Port.h:50
static void updateParameterEvaluation(int thread, bool has_error)
Updates parameter error state.
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glcorearb.h:2539
**But if you need a result
Definition: thread.h:613
exint size() const
Definition: UT_Array.h:646
static const UT_StringHolder theSizeKey
Definition: PDG_Port.h:60
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
Scoped setter of local work item.
size_t appendFormat(const char *fmt, const Args &...args)
static const PDG_WorkItem * activeWorkItem(int thread)
The script succeeded without any exceptions.
static const UT_StringHolder theLabelKey
Definition: PDG_Port.h:59
static const UT_StringHolder theExpressionKey
Definition: PDG_Port.h:62
static const UT_StringHolder theNameKey
Definition: PDG_Port.h:57
long long int64
Definition: SYS_Types.h:116
static EvaluationResult evaluate(int thread, const PY_CompiledCode &expression, fpreal &result, UT_WorkBuffer &errors)
Primitive Python eval methods (loat, int, string)
HUSD_API bool eval(VtValue &val, T &ret_val)
GLuint const GLchar * name
Definition: glcorearb.h:786
GLushort pattern
Definition: glad.h:2583
static const UT_StringHolder theTagsKey
Definition: PDG_Port.h:61
exint append()
Definition: UT_Array.h:142
GLsizeiptr size
Definition: glcorearb.h:664
**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
SYS_API int SYSgetSTID()
pdg_Connection(PDG_Port *port, bool is_ref)
Definition: PDG_Port.h:44
fpreal64 fpreal
Definition: SYS_Types.h:277
GLuint index
Definition: glcorearb.h:786
GLuint GLfloat * val
Definition: glcorearb.h:1608
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
PDG_PortDisplayType
Definition: core.h:1131
bool evaluate(int index, T &result, const PDG_WorkItem *work_item, UT_WorkBuffer &errors)
Definition: PDG_Port.h:217
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate and *a name There is also one special expression reference
type
Definition: core.h:1059
HUSD_API const char * dataType()
PDG_PortType
Enumeration of node port types.