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, int 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, unsigned idx, bool &changed, bool force)
61  {
62  // checkChangedSourceFlags() returns if input has an error, "changed"
63  // is updated.
64  if (!checkChangedSourceFlags(node, idx, changed))
65  return false;
66 
67  if (force || changed)
68  {
69  OP_Node * src = node.getInputFollowingOutputs(idx);
70 
71  setDuplicateCount(idx, src->getUniqueId(), src->getCookCount(), node.maxInputs());
72 
73  changed = true; // we may have entered with (force == true)
74  }
75  // else not forced, and not changed
76 
77  return true;
78  }
79 
80  /// Similar to useInput() except it doesn't affect the flags. It's used to
81  /// simply query whether the given input has changed. Returns false if
82  /// there's errors on the input. "changed" is updated.
83  bool checkChangedSourceFlags(const OP_Node &node, unsigned idx,
84  bool &changed)
85  {
86  OP_Node * src;
87 
88  src = node.getInputFollowingOutputs(idx);
89  if (!src || src->error() >= UT_ERROR_ABORT)
90  {
91  changed = true;
92  return false;
93  }
94 
95  changed = (src->getUniqueId() != getUniqueId(idx));
96  changed |= (src->getCookCount() != getDuplicateCount(idx));
97  return true;
98  }
99 
100  int64 getMemoryUsage(bool inclusive) const
101  {
102  int64 mem = inclusive ? sizeof(*this) : 0;
103  mem += myUniquesAndCounts.getMemoryUsage(false);
104  return mem;
105  }
106 
107 private:
108  int getDuplicateCount(int idx)
109  {
110  if (idx >= 0 && idx*2+1 < myUniquesAndCounts.entries())
111  return myUniquesAndCounts(idx*2 + 1);
112  return -1;
113  }
114  int getUniqueId(int idx)
115  {
116  if (idx >= 0 && idx*2 < myUniquesAndCounts.entries())
117  return myUniquesAndCounts(idx*2);
118  return -1;
119  }
120  void setDuplicateCount(int idx, int uniqueid, int count, int max_inputs)
121  {
122  if (idx >= 0 && idx < max_inputs)
123  {
124  int insertionidx = idx * 2;
125  while (insertionidx + 1 >= myUniquesAndCounts.entries())
126  myUniquesAndCounts.append(-1);
127  myUniquesAndCounts(insertionidx) = uniqueid;
128  myUniquesAndCounts(insertionidx+1) = count;
129  }
130  else // clear all duplicate counts
131  {
132  UT_ASSERT(!"Untested code path");
133  myUniquesAndCounts.entries(0);
134  }
135  }
136 
137 private:
138  // Pairs of unique ids and counts.
139  UT_IntArray myUniquesAndCounts;
140 };
141 
142 #endif // __OP_INPUTCHANGEHELPER_H__
int getUniqueId() const
Definition: OP_Node.h:712
void resetChangedSourceFlags()
Mark all inputs as dirty. This is the default.
virtual unsigned maxInputs() const
Maximum inputs that can be connected to a node.
bool useInput(const OP_Node &node, unsigned idx, bool &changed, bool force)
virtual OP_ERROR error(OP_Context &context)
void inputConnectChanged(const OP_Node &node, int which_input)
OP_Node * getInputFollowingOutputs(int input, DEP_MicroNode *depnode=0) const
long long int64
Definition: SYS_Types.h:116
int64 getMemoryUsage(bool inclusive) const
bool checkChangedSourceFlags(const OP_Node &node, unsigned idx, bool &changed)
SIM_API const UT_StringHolder force
#define OP_API
Definition: OP_API.h:10
int getCookCount() const
Definition: OP_Node.h:1932
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
GLint GLsizei count
Definition: glcorearb.h:405
GLenum src
Definition: glcorearb.h:1793