HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_Compiled.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: SOP_Compiled.h ( SOP Library, C++)
7  *
8  * COMMENTS:
9  * Compiles chains of nodes into a single object
10  * that can be evaluated.
11  */
12 
13 #ifndef __SOP_Compiled_h__
14 #define __SOP_Compiled_h__
15 
16 #include "SOP_API.h"
17 #include "SOP_Node.h"
18 #include "SOP_NodeVerb.h"
19 #include <DEP/DEP_TimedMicroNode.h>
20 #include <CE/CE_Error.h>
21 
23 {
24 public:
25  SOP_Compiled();
26  virtual ~SOP_Compiled();
27 
29  {
33  };
34 
36  {
37  public:
38  DelayedCook(SOP_Node *cooknode, const OP_Context &context)
39  : myCookNode(cooknode)
40  , myContext(context)
41  {
42  }
43 
46  };
47 
48  class TaskState
49  {
50  public:
52  {
53  myDirty = true;
54  myCooking = false;
55  myUseCount = 0;
56  myLocked = false;
57  myCECache = false;
58  myTimeDependent = false;
59  myNodeCache = 0;
60  myNodeParms = 0;
61  myNodeParmsOrig = 0;
62  myParmsDirty = true;
63  myDependsOnExprInputs = true;
64  myDelayedCook = 0;
65  }
67  {
68  delete myNodeCache;
69  delete myNodeParms;
70  delete myNodeParmsOrig;
71  delete myDelayedCook;
72  }
73 
75  bool myDirty;
76  bool myCECache;
78  bool myCooking; // recursion flag.
80  bool myLocked;
81  bool myParmsDirty; // Whether node parms current
82  bool myDependsOnExprInputs; // If expr inputs used.
85  SOP_NodeParms *myNodeParmsOrig; // Pre-vexpression cache
87  };
88 
90 
92  {
93  bool executeInputs(TaskStateArray &state, const OP_Context &context, UT_ErrorManager &errors, DEP_MicroNode *depnode);
94 
95  public:
96  ExecuteParms(TaskStateArray &state, UnloadMode unloadmode,
97  const OP_Context &context,
98  UT_ErrorManager &errors, DEP_MicroNode *depnode,
99  SOP_NodeVerb::ForbiddenNodeMap &forbiddennodes,
100  UT_Array<GU_DetailHandle> *recyclingbin)
101  : myState(state)
102  , myUnloadMode(unloadmode)
103  , myContext(context)
104  , myErrors(errors)
105  , myDepNode(depnode)
106  , myForbiddenNodes(forbiddennodes)
107  , myRecyclingBin(recyclingbin)
108  { }
109 
111  {}
112 
113  TaskStateArray &state() const { return myState; }
114  UnloadMode unloadMode() const { return myUnloadMode; }
115  const OP_Context &context() const { return myContext; }
116  UT_ErrorManager &errors() const { return myErrors; }
117  DEP_MicroNode *depnode() const { return myDepNode; }
118 
119  SOP_NodeVerb::ForbiddenNodeMap &forbiddenNodes() const { return myForbiddenNodes; }
120 
121  bool hasRecycleableGdp() const
122  {
123  if (!myRecyclingBin)
124  return false;
125  return myRecyclingBin->entries() > 0;
126  }
127  GU_DetailHandle allocGdp(bool clear = true) const
128  {
129  GU_DetailHandle result;
130  if (!hasRecycleableGdp())
131  {
133  }
134  else
135  {
136  result = myRecyclingBin->last();
137  myRecyclingBin->removeLast();
138  if (clear)
139  result.gdpNC()->stashAll();
140  myRecycledGdpId.append(result.gdp()->getUniqueId());
141  myRecycledGdpShareCount.append(result.getRefCount());
142  }
143  return result;
144  }
145 
146  bool isGdpIdRecycled(const GU_DetailHandle &gdh) const
147  {
148  UT_ASSERT(gdh.isValid());
149  exint idx = myRecycledGdpId.find(gdh.gdp()->getUniqueId());
150  if (idx < 0)
151  return false;
152  // Verify we haven't had any extra copies made of us during
153  // task execution. We compare against our stashed use
154  // count when first built.
155  if (gdh.getRefCount() != myRecycledGdpShareCount(idx))
156  {
157  return false;
158  }
159  return true;
160  }
161 
162  protected:
172  };
173 
174  class Task
175  {
176  public:
177  Task(SOP_Node *node, int stateid);
178  virtual ~Task();
179 
180  void setInput(int inputidx, Task *input);
181  void setExprInput(int inputidx, Task *input);
182  void appendOutput(Task *output);
183 
184  // Verify we are still wired up the way we used to be. Only the
185  // node id is valid at this point.
186  virtual bool validate();
187  virtual void addNodes(SOP_NodeVerb::ForbiddenNodeMap &nodeset);
188 
189  // Unloads any cached gdps, but not necessarily things like
190  // VEX bindings.
191  virtual void forceUnload(TaskStateArray &state);
192 
193  // Resets the time dependencies of its own node's parm lists,
194  // and any child states node's parm lists.
195  virtual void clearNodeTimeDependencies();
196 
197  SOP_Node *getNode() const { return myNode; }
198  int getNodeId() const { return myNodeId; }
199  GU_DetailHandle getDetailHandle(const TaskStateArray &state) { return state(myStateId).myGdh; }
200  bool hasCECache(const TaskStateArray &state) const { return state(myStateId).myCECache; }
201  bool getTimeDependent(const TaskStateArray &state) const { return state(myStateId).myTimeDependent; }
202  void setTimeDependent(TaskStateArray &state, bool timedep) { state(myStateId).myTimeDependent = timedep; }
203  GU_DetailHandle unloadDetailHandle(TaskStateArray &state, bool flushce, UnloadMode unloadmode, UT_ErrorManager &errors);
204 
205  void setDetailHandle(TaskStateArray &state, GU_DetailHandle gdh, bool cecache)
206  {
207  markClean(state);
208  state(myStateId).myUseCount = 0;
209  state(myStateId).myGdh = gdh;
210  state(myStateId).myCECache = cecache;
211  }
212 
213  void setDelayedCook(TaskStateArray &state, SOP_Node *cooknode, const OP_Context &context)
214  {
215  delete state(myStateId).myDelayedCook;
216  state(myStateId).myDelayedCook = new DelayedCook(cooknode, context);
217  }
218 
219  void lock(TaskStateArray &state)
220  {
221  state(myStateId).myLocked = true;
222  }
223  bool isLocked(TaskStateArray &state) const
224  {
225  return state(myStateId).myLocked;
226  }
227 
228  bool isDirty(const TaskStateArray &state) const { return state(myStateId).myDirty; }
229  void dirty(TaskStateArray &state) { state(myStateId).myDirty = true; }
230  void markClean(TaskStateArray &state) { state(myStateId).myDirty = false; }
231 
232  bool isParmsDirty(const TaskStateArray &state) const { return state(myStateId).myParmsDirty; }
233  void dirtyParms(TaskStateArray &state) { state(myStateId).myParmsDirty = true; }
234  void markParmsClean(TaskStateArray &state) { state(myStateId).myParmsDirty = false; }
235  bool dependsOnExprInputs(const TaskStateArray &state) const { return state(myStateId).myDependsOnExprInputs; }
236  void clearDependsOnExprInputs(TaskStateArray &state) { state(myStateId).myDependsOnExprInputs = false; }
237  void setDependsOnExprInputs(TaskStateArray &state) { state(myStateId).myDependsOnExprInputs = true; }
238 
239  /// Dirties ourself and all children until we hit something
240  /// already dirty.
241  void dirtyChildren(TaskStateArray &state);
242 
243  /// Computes myself, and chains to any inputs, provided not
244  /// dirty.
245  bool execute(const ExecuteParms &parms);
246 
247  virtual bool doExecute(const ExecuteParms &parms) = 0;
248 
249  bool executeInputs(const ExecuteParms &parms);
250  bool executeExprInputs(const ExecuteParms &parms);
251 
252  void dump(std::ostream &os) const;
253  UT_StringHolder buildName() const;
254 
255  protected:
256  virtual void dumpSubclass(std::ostream &os) const {}
258  int myNodeId;
267  };
268 
269  /// Determine if the compiled task list still matches what
270  /// the SOP network has.
271  bool isTopologyDirty(const OP_Context &context);
272 
273  bool isTopologyTimeDependent() const;
274 
275  void dump(std::ostream &os) const;
276 
277  /// Compile a node block, only rebuilding if Topo dependency is
278  /// invalid
279  bool compile(SOP_Node *root, const OP_Context &context, UT_ErrorManager &errors);
280  bool compileMulti(const UT_Array<SOP_Node *> &roots, const OP_Context &context, UT_ErrorManager &errors);
281 
282  /// Determines what node is at the root of the compile block
283  SOP_Node *getRoot(exint idx = 0) const;
284  exint getNumRoots() const;
285 
286  /// Is the task list compiled & valid?
287  bool isCompiled() const;
288 
289  /// Donate the provided detail to be recycled if needed.
290  /// The passed in handle will be cleared.
291  void donateForRecycling(GU_DetailHandle &gdh);
292 
293  /// Execute our cached block
294  /// The inputgdhs will be cleared as they are used, allowing
295  /// them to be stolen & written to if they are unique.
296  GU_DetailHandle execute(bool &hascedata,
297  TaskStateArray &states,
298  bool flushce,
299  UnloadMode unload,
300  const OP_Context &context,
301  UT_ErrorManager &errors,
302  DEP_MicroNode *depnode,
303  const UT_StringArray &inputnames,
304  UT_Array<GU_DetailHandle> &inputgdhs,
305  const UT_Array<bool> &inputhascedata);
306 
307  /// Execute a compiled block that has multiple roots.
308  void executeMulti(
309  UT_Array<GU_DetailHandle> &outputgdhs,
310  UT_Array<bool> &hascedata,
311  TaskStateArray &states,
312  bool flushce,
313  UnloadMode unload,
314  const OP_Context &context,
315  UT_ErrorManager &errors,
316  DEP_MicroNode *depnode,
317  const UT_StringArray &inputnames,
318  UT_Array<GU_DetailHandle> &inputgdhs,
319  const UT_Array<bool> &inputhascedata);
320 
321  void clear();
322 
323  exint taskCount() const { return myTasks.size(); }
324  exint taskInputCount() const { return myTaskInputs.size(); }
325  exint nodeCount() const { return myNodeSet ? myNodeSet->size() : 0; }
326 
327  /// Determines somewhat conservatively if the node is eligbile for
328  /// compilation. Verbs always are, but things like subnets are only
329  /// if their SOP contents are as well.
330  static bool canBeCompiled(SOP_Node *node);
331 
332 
333 protected:
335 
339 
342 };
343 
344 #endif
345 
DelayedCook(SOP_Node *cooknode, const OP_Context &context)
Definition: SOP_Compiled.h:38
void stashAll()
Definition: GA_Detail.h:137
exint taskCount() const
Definition: SOP_Compiled.h:323
exint nodeCount() const
Definition: SOP_Compiled.h:325
UT_Array< Task * > myTaskInputs
Definition: SOP_Compiled.h:338
void lock(TaskStateArray &state)
Definition: SOP_Compiled.h:219
Unsorted map container.
Definition: UT_Map.h:83
bool isValid() const
Determine if this is a valid handle (!isNull())
DEP_MicroNode * depnode() const
Definition: SOP_Compiled.h:117
DEP_MicroNode * myDepNode
Definition: SOP_Compiled.h:167
bool isGdpIdRecycled(const GU_DetailHandle &gdh) const
Definition: SOP_Compiled.h:146
UT_Array< Task * > myOutputs
Definition: SOP_Compiled.h:266
UT_IntArray myNodeInputIds
Definition: SOP_Compiled.h:262
UT_Array< TaskState > TaskStateArray
Definition: SOP_Compiled.h:89
const GU_Detail * gdp() const
GU_DetailHandle allocGdp(bool clear=true) const
Definition: SOP_Compiled.h:127
UT_ExintArray myRecycledGdpShareCount
Definition: SOP_Compiled.h:171
UT_Array< GU_DetailHandle > * myRecyclingBin
Definition: SOP_Compiled.h:169
bool isDirty(const TaskStateArray &state) const
Definition: SOP_Compiled.h:228
bool hasCECache(const TaskStateArray &state) const
Definition: SOP_Compiled.h:200
SOP_Node * getNode() const
Definition: SOP_Compiled.h:197
UT_Array< Task * > myRoots
Definition: SOP_Compiled.h:336
const OP_Context & context() const
Definition: SOP_Compiled.h:115
void allocateAndSet(GU_Detail *gdp, bool own=true)
TaskStateArray & myState
Definition: SOP_Compiled.h:163
UT_Array< GU_DetailHandle > myRecyclingBin
Definition: SOP_Compiled.h:341
bool hasRecycleableGdp() const
Definition: SOP_Compiled.h:121
UnloadMode unloadMode() const
Definition: SOP_Compiled.h:114
int getRefCount() const
Returns the number of references made to the base handle.
int64 exint
Definition: SYS_Types.h:116
SOP_NodeCache * myNodeCache
Definition: SOP_Compiled.h:83
UT_ErrorManager & myErrors
Definition: SOP_Compiled.h:166
void dirtyParms(TaskStateArray &state)
Definition: SOP_Compiled.h:233
GU_DetailHandle getDetailHandle(const TaskStateArray &state)
Definition: SOP_Compiled.h:199
SOP_NodeParms * myNodeParms
Definition: SOP_Compiled.h:84
SOP_NodeVerb::ForbiddenNodeMap * myNodeSet
Definition: SOP_Compiled.h:340
void clearDependsOnExprInputs(TaskStateArray &state)
Definition: SOP_Compiled.h:236
void setTimeDependent(TaskStateArray &state, bool timedep)
Definition: SOP_Compiled.h:202
void setDetailHandle(TaskStateArray &state, GU_DetailHandle gdh, bool cecache)
Definition: SOP_Compiled.h:205
virtual void dumpSubclass(std::ostream &os) const
Definition: SOP_Compiled.h:256
UT_Array< Task * > myInputs
Definition: SOP_Compiled.h:264
TaskStateArray & state() const
Definition: SOP_Compiled.h:113
SOP_NodeParms * myNodeParmsOrig
Definition: SOP_Compiled.h:85
int getNodeId() const
Definition: SOP_Compiled.h:198
GU_Detail * gdpNC()
void dirty(TaskStateArray &state)
Definition: SOP_Compiled.h:229
DelayedCook * myDelayedCook
Definition: SOP_Compiled.h:86
exint getUniqueId() const
Definition: GA_Detail.h:116
UT_Array< Task * > myTasks
Definition: SOP_Compiled.h:337
void markClean(TaskStateArray &state)
Definition: SOP_Compiled.h:230
UT_ErrorManager & errors() const
Definition: SOP_Compiled.h:116
DEP_TimedMicroNode myTopoMicroNode
Definition: SOP_Compiled.h:334
static GU_Detail * prepNewDetail(GU_Detail *gdp)
SOP_NodeVerb::ForbiddenNodeMap & forbiddenNodes() const
Definition: SOP_Compiled.h:119
bool isLocked(TaskStateArray &state) const
Definition: SOP_Compiled.h:223
void setDependsOnExprInputs(TaskStateArray &state)
Definition: SOP_Compiled.h:237
UT_ExintArray myRecycledGdpId
Definition: SOP_Compiled.h:170
exint taskInputCount() const
Definition: SOP_Compiled.h:324
ExecuteParms(TaskStateArray &state, UnloadMode unloadmode, const OP_Context &context, UT_ErrorManager &errors, DEP_MicroNode *depnode, SOP_NodeVerb::ForbiddenNodeMap &forbiddennodes, UT_Array< GU_DetailHandle > *recyclingbin)
Definition: SOP_Compiled.h:96
void markParmsClean(TaskStateArray &state)
Definition: SOP_Compiled.h:234
A global error manager scope.
#define SOP_API
Definition: SOP_API.h:10
void setDelayedCook(TaskStateArray &state, SOP_Node *cooknode, const OP_Context &context)
Definition: SOP_Compiled.h:213
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
const OP_Context & myContext
Definition: SOP_Compiled.h:165
SOP_NodeVerb::ForbiddenNodeMap & myForbiddenNodes
Definition: SOP_Compiled.h:168
bool isParmsDirty(const TaskStateArray &state) const
Definition: SOP_Compiled.h:232
bool dependsOnExprInputs(const TaskStateArray &state) const
Definition: SOP_Compiled.h:235
UT_Array< Task * > myExprInputs
Definition: SOP_Compiled.h:265
bool getTimeDependent(const TaskStateArray &state) const
Definition: SOP_Compiled.h:201
GU_DetailHandle myGdh
Definition: SOP_Compiled.h:74