HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OP_InputChangeHelper.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  * NAME: OP_InputChangeHelper.h (OP Library, C++)
7  *
8  * COMMENTS: Helper class for keeping track of whether node inputs have
9  * changed.
10  *
11  * HOW TO USE THIS CLASS
12  * =====================
13  *
14  * SETUP:
15  * - Override OP_Node::inputConnectChanged() to call
16  * OP_InputChangeHelper::inputConnectChanged() as well. Don't forget to
17  * delegate to the base class.
18  * - In the OP_Node::deleteCookedData() and OP_Node::bypassMe() overrides,
19  * call OP_InputChangeHelper::resetChangedSourceFlags(). Any other calls
20  * to delete the node's data should also call resetChangedSourceFlags().
21  *
22  * Now, when you want to mark an input as being used, call useInput(). To query
23  * if an input is dirty without clearing it, use checkChangedSourceFlags().
24  */
25 
26 #ifndef __OP_INPUTCHANGEHELPER_H__
27 #define __OP_INPUTCHANGEHELPER_H__
28 
29 #include "OP_API.h"
30 #include <UT/UT_Assert.h>
31 #include <UT/UT_IntArray.h>
32 #include "OP_Node.h"
33 
35 {
36 public:
37 
38  /// Mark all inputs as dirty. This is the default.
40  {
41  myUniquesAndCounts.setCapacity(0);
42  }
43 
44  /// Mark the given input as dirty.
45  /// NOTE: Users of this class should override
46  /// OP_Node::inputConnectChanged() to call this.
47  void inputConnectChanged(const OP_Node &node, OP_InputIdx which_input)
48  {
49  if (which_input >= 0)
50  setDuplicateCount(which_input, -1, -1, node.maxInputs());
51  else
52  resetChangedSourceFlags();
53  }
54 
55  /// Use the given input on the node. This updates source flags to mark the
56  /// input as now clean, returning whether the input changes.
57  /// If force is true, then we treat the input as always dirty.
58  /// Returns false if input has errors and we'll add an input error in that
59  /// case.
60  bool useInput(const OP_Node &node, OP_InputIdx idx, bool &changed,
61  bool force)
62  {
63  // checkChangedSourceFlags() returns if input has an error, "changed"
64  // is updated.
65  if (!checkChangedSourceFlags(node, idx, changed))
66  return false;
67 
68  if (force || changed)
69  {
70  OP_Node * src = node.getInputFollowingOutputs(idx);
71 
72  setDuplicateCount(idx, src->getUniqueId(), src->getCookCount(), node.maxInputs());
73 
74  changed = true; // we may have entered with (force == true)
75  }
76  // else not forced, and not changed
77 
78  return true;
79  }
80 
81  /// Similar to useInput() except it doesn't affect the flags. It's used to
82  /// simply query whether the given input has changed. Returns false if
83  /// there's errors on the input. "changed" is updated.
85  bool &changed)
86  {
87  OP_Node * src;
88 
89  src = node.getInputFollowingOutputs(idx);
90  if (!src || src->error() >= UT_ERROR_ABORT)
91  {
92  changed = true;
93  return false;
94  }
95 
96  changed = (src->getUniqueId() != getUniqueId(idx));
97  changed |= (src->getCookCount() != getDuplicateCount(idx));
98  return true;
99  }
100 
101  int64 getMemoryUsage(bool inclusive) const
102  {
103  int64 mem = inclusive ? sizeof(*this) : 0;
104  mem += myUniquesAndCounts.getMemoryUsage(false);
105  return mem;
106  }
107 
108 private:
109  int getDuplicateCount(OP_InputIdx idx)
110  {
111  if (idx >= 0 && idx*2+1 < myUniquesAndCounts.entries())
112  return myUniquesAndCounts(idx*2 + 1);
113  return -1;
114  }
115  int getUniqueId(OP_InputIdx idx)
116  {
117  if (idx >= 0 && idx*2 < myUniquesAndCounts.entries())
118  return myUniquesAndCounts(idx*2);
119  return -1;
120  }
121  void setDuplicateCount(OP_InputIdx idx, int uniqueid, int count,
122  int max_inputs)
123  {
124  if (idx >= 0 && idx < max_inputs)
125  {
126  exint insertionidx = idx * 2;
127  while (insertionidx + 1 >= myUniquesAndCounts.entries())
128  myUniquesAndCounts.append(-1);
129  myUniquesAndCounts(insertionidx) = uniqueid;
130  myUniquesAndCounts(insertionidx+1) = count;
131  }
132  else // clear all duplicate counts
133  {
134  UT_ASSERT(!"Untested code path");
135  myUniquesAndCounts.entries(0);
136  }
137  }
138 
139 private:
140  // Pairs of unique ids and counts.
141  UT_IntArray myUniquesAndCounts;
142 };
143 
144 #endif // __OP_INPUTCHANGEHELPER_H__
int getUniqueId() const
Definition: OP_Node.h:750
void resetChangedSourceFlags()
Mark all inputs as dirty. This is the default.
void inputConnectChanged(const OP_Node &node, OP_InputIdx which_input)
virtual unsigned maxInputs() const
Maximum inputs that can be connected to a node.
int OP_InputIdx
Definition: OP_DataTypes.h:184
int64 exint
Definition: SYS_Types.h:125
virtual OP_ERROR error(OP_Context &context)
OP_Node * getInputFollowingOutputs(OP_InputIdx input, DEP_MicroNode *depnode=nullptr) const
bool checkChangedSourceFlags(const OP_Node &node, OP_InputIdx idx, bool &changed)
long long int64
Definition: SYS_Types.h:116
int64 getMemoryUsage(bool inclusive) const
bool useInput(const OP_Node &node, OP_InputIdx idx, bool &changed, bool force)
SIM_API const UT_StringHolder force
#define OP_API
Definition: OP_API.h:10
int getCookCount() const
Definition: OP_Node.h:2061
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
GLint GLsizei count
Definition: glcorearb.h:405
GLenum src
Definition: glcorearb.h:1793