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  bool hasNoCopyTag() const;
164 
165  const PDG_Conditional& cookCondition() const;
166  void setCookCondition(const UT_StringHolder& pattern);
167 
168  const UT_StringHolder& disableCondition() const;
169  void setDisableCondition(
170  const UT_StringHolder& condition);
171 
172  bool hasTag(const UT_StringHolder& tag) const;
173 
174  void setDataType(PDGT_Value::DataType type);
176 
177  UT_StringArray resultTypeTags(bool strip_prefix) const;
178 
179  bool isOrdered() const;
180  bool isCustom() const;
181  bool isBuiltin() const;
182  int size() const;
183 
184  bool asJSON(
185  UT_JSONWriter& writer,
186  bool skip_defaults) const;
187  static bool fromJSON(
188  const UT_JSONValue* value,
189  PDG_NodeInterface* interface,
190  UT_WorkBuffer& errors);
191 
192  UT_StringHolder dataTypeAsString() const;
193 
194  static void splitName(const UT_StringHolder& full_name,
195  UT_StringHolder& node,
196  UT_StringHolder& port);
197 
198  bool evaluate(
199  int index,
200  fpreal& result,
201  const PDG_WorkItem* work_item,
202  UT_WorkBuffer& errors) const;
203  bool evaluate(
205  const PDG_WorkItem* work_item,
206  UT_WorkBuffer& errors) const;
207 
208  bool evaluate(
209  int index,
210  exint& result,
211  const PDG_WorkItem* work_item,
212  UT_WorkBuffer& errors) const;
213  bool evaluate(
214  int index,
215  bool& result,
216  const PDG_WorkItem* work_item,
217  UT_WorkBuffer& errors) const;
219  bool evaluate(
220  int index,
221  T& result,
222  const PDG_WorkItem* work_item,
223  UT_WorkBuffer& errors)
224  {
225  exint temp;
226  bool eval = evaluate(
227  index, temp, work_item, errors);
228 
229  if (eval)
230  {
231  result = (T)(temp);
232  return true;
233  }
234 
235  return false;
236  }
237 
238  bool evaluate(
240  const PDG_WorkItem* work_item,
241  UT_WorkBuffer& errors) const;
242 
243  bool evaluate(
244  int index,
246  const PDG_WorkItem* work_item,
247  UT_WorkBuffer& errors) const;
248  bool evaluate(
250  const PDG_WorkItem* work_item,
251  UT_WorkBuffer& errors) const;
252 
253  bool evaluateRaw(
254  int index,
256  const PDG_WorkItem* work_item,
257  UT_WorkBuffer& errors) const;
258  bool evaluateRaw(
260  const PDG_WorkItem* work_item,
261  UT_WorkBuffer& errors) const;
262 
263 
264  UT_StringHolder expressionFile(int index) const;
265 
266 private:
267  UT_StringHolder postReplace(const UT_StringHolder& input,
268  const PDG_WorkItem* work_item,
269  bool always_replace) const;
270  exint postReplace(exint input,
271  const PDG_WorkItem* work_item,
272  bool always_replace) const;
273  fpreal postReplace(fpreal input,
274  const PDG_WorkItem* work_item,
275  bool always_replace) const;
276 
277  bool appEval(const UT_StringHolder& name,
278  int index,
279  bool expand,
280  fpreal& result,
281  const PDG_WorkItem* work_item,
282  int thread,
283  UT_WorkBuffer& errors) const;
284  bool appEval(const UT_StringHolder& name,
285  int index,
286  bool expand,
287  exint& result,
288  const PDG_WorkItem* work_item,
289  int thread,
290  UT_WorkBuffer& errors) const;
291  bool appEval(const UT_StringHolder& name,
292  int index,
293  bool expand,
295  const PDG_WorkItem* work_item,
296  int thread,
297  UT_WorkBuffer& errors) const;
298 
299  bool canEvaluate(int index,
300  UT_WorkBuffer& errors) const;
301  bool isParent(const PDG_WorkItem* work_item) const;
302 
303  template <typename T>
304  bool evaluateTyped(int index,
305  bool expand,
306  T& result,
307  const PDG_WorkItem* work_item,
308  UT_WorkBuffer& errors) const
309  {
310  if (index < 0)
311  index += myPortValues.size();
312 
313  if (!canEvaluate(index, errors))
314  return false;
315 
316  const pdg_PortValue& val = myPortValues[index];
317  int thread = SYSgetSTID();
318  T temp;
319 
320  // set the scope parent state to true if we want to use
321  // a workitem that is not from this node.
323  thread, work_item, isParent(work_item));
324  const PDG_WorkItem* local_item =
325  PDG_EvaluationContext::activeWorkItem(thread);
326 
327  if (val.isAppParm())
328  {
329  if (!appEval(
330  myName, index, expand, result, local_item, thread, errors))
331  {
333  return false;
334  }
335 
336  return true;
337  }
338 
339  if (!val.hasExpression())
340  {
341  val.myValue.value(temp);
342  result = postReplace(temp, local_item, true);
343  return true;
344  }
345 
346  if (PDG_EvaluationContext::evaluate(thread, *val.myPyExpression,
347  temp, errors) != PDG_EvaluationContext::eResultSuccess)
348  {
349  errors.appendFormat(" ({})", expressionFile(index));
350  return false;
351  }
352 
353  result = postReplace(temp, local_item, true);
354  return true;
355  }
356 
357  template <typename T>
358  bool evaluateArray(bool expand,
359  UT_Array<T>& result,
360  const PDG_WorkItem* work_item,
361  UT_WorkBuffer& errors) const
362  {
363  if (myPortType != PDG_PortType::eParameter)
364  {
365  errors.appendFormat("Port '{}' is not a parameter", myName);
366  return false;
367  }
368 
369  int thread = SYSgetSTID();
371  thread, work_item, isParent(work_item));
372  const PDG_WorkItem* local_item =
374 
375  int index = 0;
376  for (auto&& port_val : myPortValues)
377  {
378  T temp;
379  if (port_val.isAppParm())
380  {
381  if (!appEval(myName, index, expand, temp,
382  local_item, thread, errors))
383  {
385  thread, true);
386  return false;
387  }
388  }
389  else if (!port_val.hasExpression())
390  port_val.myValue.value(temp);
391  else
392  {
394  thread,
395  *port_val.myPyExpression,
396  temp, errors) != PDG_EvaluationContext::eResultSuccess)
397  {
398  errors.appendFormat(" ({})", expressionFile(result.size()));
399  return false;
400  }
401  }
402  result.append(postReplace(temp, local_item, true));
403  index++;
404  }
405 
406  return true;
407  }
408 
409 private:
410  struct pdg_PortValue
411  {
412  pdg_PortValue()
413  : myPyExpression(nullptr)
414  , myMultiExpression(false)
415  , myIsAppParm(false)
416  {
417  }
418 
419  ~pdg_PortValue()
420  {
421  // If Python is no longer active, we need to leak the contents of
422  // the expression data since it won't be possible to safely free it
423  if (myPyExpression && !PY_Py_IsInitialized())
424  myPyExpression.release();
425  }
426 
427  int64 getMemoryUsage(bool inclusive) const
428  {
429  int64 mem = inclusive ? sizeof(*this) : 0;
430  mem += myExpression.getMemoryUsage(false);
431  if (myPyExpression)
432  mem += myPyExpression->getMemoryUsage(true);
433  return mem;
434  }
435 
436  inline bool hasExpression() const { return myExpression.length() > 0; }
437  inline bool isAppParm() const { return myIsAppParm; }
438 
439  PDGT_Value myValue;
440  UT_StringHolder myExpression;
442  myPyExpression;
443 
444  bool myMultiExpression;
445  bool myIsAppParm;
446  };
447 
448  PDG_NodeInterface* myOwner;
449  ConnectionArray myConnections;
450  const PDG_WorkItemDataType* myWorkItemDataType;
451 
452  PDG_Conditional myCookCondition;
453 
454  PDG_PortType myPortType;
455  UT_StringHolder myName;
456  UT_StringHolder myLabel;
457  UT_StringHolder myDisableCondition;
458 
459  UT_Array<pdg_PortValue> myPortValues;
460 
461  UT_StringArray myTags;
462  UT_StringArray myExpressionAttribs;
463  ExpressionVars myExpressionVars;
464 
465  int mySize;
466  int myEvaluationOrigin;
467 
468  bool myEnabledFlag;
469  bool myOrderedFlag;
470  bool myCustomFlag;
471  bool myBuiltinFlag;
472  bool myHasExpressionVars;
473 
474  PDGT_Value::DataType myDataType;
475  int myDisplayType;
476  UT_StringArray myDisplayMenuList;
477  UT_StringHolder myDisplayMenuScript;
478 };
479 
480 #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:622
exint size() const
Definition: UT_Array.h:653
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)
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
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:278
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
bool evaluate(int index, T &result, const PDG_WorkItem *work_item, UT_WorkBuffer &errors)
Definition: PDG_Port.h:219
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
HUSD_API const char * dataType()
PDG_PortType
Enumeration of node port types.