HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_Graph.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_GRAPH_H__
10 #define __PDG_GRAPH_H__
11 
12 #include "PDG_API.h"
13 
14 #include "PDG_AttributeOwner.h"
15 #include "PDG_AttributeTypes.h"
16 #include "PDG_NodeTypes.h"
17 #include "PDG_RegisteredType.h"
18 #include "PDG_WorkItemDirty.h"
19 
20 #include <UT/UT_ArrayMap.h>
21 #include <UT/UT_ArrayStringMap.h>
23 #include <UT/UT_StringHolder.h>
24 #include <UT/UT_StringMap.h>
25 #include <UT/UT_RWLock.h>
26 
28 class PDG_GraphContext;
29 struct PDG_MemoryInfo;
30 class PDG_NodeInterface;
31 class PDG_Node;
33 class PDG_Port;
34 class PDG_WorkItem;
35 class PDG_WorkItemDirty;
36 
37 class UT_WorkBuffer;
38 
40 {
41 public:
42  /// Nodes not created by TOPs will have id = nodeIdBase + counter
43  static constexpr PDG_NodeID nodeIdBase = 1000000;
44 
45  /// Typedef for work item id -> work item
47 
48 public:
49  PDG_Graph(PDG_GraphContext* context);
50  ~PDG_Graph() override;
51 
52  /// Returns the total memory usage of the graph, and all the nodes and
53  /// work items in it
54  int64 getMemoryUsage(bool inclusive) const;
55 
56  /// Returns the total memory usage of the graph, and all the nodes and
57  /// work items in it.
58  void memoryInfo(PDG_MemoryInfo& memory_info,
59  bool inclusive) const;
60 
61  /// Returns a descriptive name of the attribute owner
62  UT_StringHolder attribOwnerName() const override;
63 
64  /// Checks if the specified flag is valid for this owner
65  bool isAttribFlagValid(
66  PDG_AttributeFlag flag) const override;
67 
68  /// Checks if the specified bit vector flags is valid for this owner
69  bool areAttribFlagsValid(uint16 flags) const override;
70 
71  /// Returns a human-readable description of the nodes in the graph
72  void description(UT_WorkBuffer& buffer) const;
73 
74  /// Serializes the nodes to Python, which can then be used to rebuild the
75  /// graph at a later point
76  void serialize(UT_WorkBuffer& buffer) const;
77 
78  /// Constructs a new PDG node with a given node callbakc type, name and
79  /// extra args
80  PDG_Node* createNode(PDG_NodeCallbackType* type_object,
81  const UT_StringHolder& node_name,
82  const PDGT_ValueArgs& args,
83  UT_WorkBuffer& errors,
84  PDG_NodeID id = -1);
85 
86  /// Adds an existing node to the graph
87  void insertNode(PDG_NodePtr& node);
88 
89  /// Renames a node given i's current/old node name. Does not update any
90  /// external references to the node name
91  bool renameNode(
92  const UT_StringHolder& old_name,
93  const UT_StringHolder& new_name);
94 
95  /// Renames a node give its ID. Does not update any external references
96  /// tot he node name
97  bool renameNodeById(
98  PDG_NodeID node_id,
99  const UT_StringHolder& new_name);
100 
101  /// Remove node/nodes from the graph
102  PDG_NodePtr removeNode(const UT_StringHolder& node_name);
103  PDG_NodePtr removeNodeById(PDG_NodeID node_id);
104  void removeAllNodes();
105 
106  /// Notifies nodes that a scheduler has been removed
107  void removeScheduler(PDG_Scheduler* scheduler);
108 
109  /// Accessors for nodes in the graph
110  PDG_Node* node(const UT_StringHolder& name) const;
111  PDG_Node* nodeById(PDG_NodeID id) const;
112  int nodeCount() const
113  { return myNodeNameMap.size(); }
114  const PDG_NodePtrMap& nodes() const
115  { return myNodeNameMap; }
116 
117  /// Returns a unqiue name for a node by adding a numeric suffix until a
118  /// name is found that isn't already in use
119  UT_StringHolder uniqueNodeName(const UT_StringHolder& name);
120 
121  /// Looks up a port using the node.port_name syntax
122  PDG_Port* nodePort(const UT_StringHolder& node_name,
123  const UT_StringHolder& port_name) const;
124  PDG_Port* nodePort(const UT_StringHolder& full_name) const;
125 
126  /// Adds/ removes or queries external dependencies
127  PDG_DependencyPtr dependencyForKey(const UT_StringHolder& key) const;
128  PDG_DependencyPtr addDependency(const UT_StringHolder& type,
129  const UT_StringHolder& key,
130  const PDGT_ValueArgs& args,
131  UT_WorkBuffer& errors);
132  void addDependency(PDG_DependencyPtr dependency);
133  void removeDependency(PDG_DependencyPtr dependency);
134 
135  /// Returns the graph contex that owns this graph
136  PDG_GraphContext* context() const;
137 
138 
139  /// Adds a work item to the work item id -> pointer map
140  void addWorkItem(PDG_WorkItem* work_item);
141 
142  /// Removes a work item from the graph
143  void removeWorkItem(PDG_WorkItem* work_item);
144 
145 
146  /// Returns a work item for a given id
147  PDG_WorkItem* workItemById(PDG_WorkItemID id) const;
148 
149  /// Returns a work item for a given id. Iterates through all active
150  static PDG_WorkItem* workItemByGlobalId(PDG_WorkItemID id);
151 
152  /// Returns a list of work items for a given list of ids
153  void workItemsById(
154  PDG_WorkItemArray& work_items,
156  bool allow_null) const;
157 
158  /// Returns a work item for a given name
159  PDG_WorkItem* workItemByName(const UT_StringHolder& name) const;
160 
161  /// Returns a work item id from a name, assuming the name is using the
162  /// node_id compatibility format
163  PDG_WorkItemID workItemIdFromName(const UT_StringHolder& name) const;
164 
165  /// Returns an array of work item IDs currently in the graph
166  void workItemIds(PDG_WorkItemIDArray& ids) const;
167 
168  /// Returns the map of work item ids -> work item
169  IdMap workItemIdMap() const { return myWorkItemIdMap; }
170 
171  /// Returns a map of item->dependencies, item->dependents and ready items
172  void dependencyGraph(
173  PDG_WorkItemMap& dependencies,
174  PDG_WorkItemMap& dependents,
175  PDG_WorkItemArray& ready,
176  bool expand,
177  PDG_Scheduler* filter) const;
178 
179  /// Returns a static dependency graph as a map of work item -> dependencies
180  /// If "inverse" is true, returns the dependent map instead
181  void dependencyGraph(
182  PDG_WorkItemMap& graph,
183  bool inverse,
184  bool expand,
185  PDG_Scheduler* filter) const;
186 
187  /// Dirties all work items in the graph, faster than the standard dirty
188  /// methods as it can simply blow away everything
189  PDG_WorkItemDirty dirtyAll(
190  bool remove_outputs,
191  bool apply_dirty) const;
192 
193  /// Dirties a work item by id
194  ///
195  /// Note that this method acquires the serial cook write lock, preventing
196  /// any other code from accessing/generating static or dirtying work items
197  PDG_WorkItemDirty dirtyWorkItem(
198  PDG_WorkItemID id,
199  bool should_delete,
200  bool remove_outputs,
201  bool apply_dirty) const;
202 
203  /// Dirties a work item by pointer
204  ///
205  /// Note that this method acquires the serial cook write lock, preventing
206  /// any other code from accessing/generating static or dirtying work items
207  PDG_WorkItemDirty dirtyWorkItem(
208  PDG_WorkItem* work_item,
209  bool should_delete,
210  bool remove_outputs,
211  bool apply_dirty) const;
212 
213  /// Dirities an array of work items
214  ///
215  /// Note that this method acquires the serial cook write lock, preventing
216  /// any other code from accessing/generating static or dirtying work items
217  PDG_WorkItemDirty dirtyWorkItems(
218  const PDG_WorkItemArray& work_items,
219  PDG_Node* source_node,
220  bool should_delete,
221  bool remove_outputs,
222  bool apply_dirty,
223  bool emit_events) const;
224  PDG_WorkItemDirty dirtyWorkItems(
225  const PDG_WorkItemPtrArray& work_items,
226  PDG_Node* source_node,
227  bool should_delete,
228  bool remove_outputs,
229  bool apply_dirty,
230  bool emit_events) const;
231 
232  /// Dirities an array of work items, using the existing dirty state
233  /// object.
234  ///
235  /// Note that this method acquires the serial cook write lock, preventing
236  /// any other code from accessing/generating static or dirtying work items
237  void dirtyWorkItems(
238  const PDG_WorkItemArray& work_items,
239  PDG_WorkItemDirty* dirty_state) const;
240  void dirtyWorkItems(
241  const PDG_WorkItemPtrArray& work_items,
242  PDG_WorkItemDirty* dirty_state) const;
243 
244  /// Does a numeric data lookup, for use with the @ operator
245  PDG_AttributeCast numericData(
246  fpreal& param,
247  exint& query_index,
248  const PDG_AttributeEvaluator& evaluator) const;
249 
250  /// Does a string data lookup, for use with the @ operator
251  PDG_AttributeCast stringData(
253  exint& query_index,
254  const PDG_AttributeEvaluator& evaluator,
255  const PDG_EvaluationContext* local_context) const;
256 
257  /// Binds a global attribute to a specific work item
258  void bindGlobalAttribute(
259  const UT_StringHolder& attrib_name,
260  PDG_WorkItem* work_item);
261 
262  /// Returns the work iterm that an attribute is bound to
263  PDG_WorkItem* boundAttributeWorkItem(
264  const UT_StringHolder& attrib_name) const;
265 
266  /// Adjusts the unique id counter so the specified ID is included in the
267  /// range of used values.
268  static void addUniqueId(PDG_WorkItemID id);
269 
270  /// Returns a new unique work item id
271  static PDG_WorkItemID uniqueWorkItemId();
272 
273  /// Returns the current maximum unique work item id
274  static PDG_WorkItemID currentWorkItemId();
275 
276  /// Returns a new unique cache id
277  PDG_CacheID uniqueCacheId();
278 
279  /// Returns a new unique node id
280  PDG_NodeID uniqueNodeId();
281 
282  /// Increments the graph's cache id.
283  void bumpCacheId();
284 
285  /// Returns the serial cook RW lock. This is only so that PDG_Node is able
286  /// to use the lock to guard access to its static items, wrappers and done
287  /// item lists.
289  { return mySerialCookLock; }
290 
291  /// Runs a functor on the specified node with the node lock held.
292  template <typename Func>
293  void safeNodeAccess(PDG_NodeID id, const Func& f) const
294  {
295  UT_AutoReadLock nodes_lock(myNodesLock);
296  auto it = myNodeIdMap.find(id);
297  if (it != myNodeIdMap.end())
298  f(it->second);
299  }
300 
301  /// Runs a functor on the node map with the node lock held.
302  template <typename Func>
303  void safeNodeMapAccess(const Func& f) const
304  {
305  UT_AutoReadLock nodes_lock(myNodesLock);
306  f(myNodeNameMap);
307  }
308 
309  /// Runs a functor on the specified work item with an ID map iterator
310  /// held.
311  template <typename Func>
313  const Func& f) const
314  {
315  IdMap::accessor access;
316  if (myWorkItemIdMap.find(access, id))
317  f(access->second);
318  }
319 
320 private:
321  friend class PDG_WorkItemDirty;
322 
323  /// Typedef for exteranl dependency map
325 
326  /// Typedef for node id -> node
328 
329  /// Map of work item ID to global attributes bound to that work item
331 
332  /// Inverse map for global attributes, mapping attribute name to work
333  /// item ID
335 
336  void applyDirty(bool remove_outputs);
337 
338 private:
339  PDG_NodePtrMap myNodeNameMap;
340  NodeIdMap myNodeIdMap;
341  IdMap myWorkItemIdMap;
342 
343  GlobalAttribMap myGlobalAttribMap;
344  GlobalAttribInvMap myGlobalAttribInvMap;
345 
346  SYS_AtomicCounter myNodeIdCounter;
347  PDG_CacheID myCacheIdCounter;
348 
349  DepMap myDependencies;
350  PDG_GraphContext* myContext;
351 
352  mutable UT_RWLock myNodesLock;
353  mutable UT_RWLock mySerialCookLock;
354 };
355 
356 #endif /* __PDG_GRAPH_H__ */
exint PDG_WorkItemID
Type defs for unique work item IDs.
GLbitfield flags
Definition: glcorearb.h:1596
unsigned short uint16
Definition: SYS_Types.h:38
UT_SharedPtr< PDG_Dependency > PDG_DependencyPtr
Type defs for registered type objects.
Definition: PDG_NodeTypes.h:25
virtual bool areAttribFlagsValid(uint16 flags) const
#define PDG_API
Definition: PDG_API.h:23
UT_UniquePtr< PDG_Node > PDG_NodePtr
Array, set and map of nodes.
Definition: PDG_NodeTypes.h:33
int64 exint
Definition: SYS_Types.h:125
virtual UT_StringHolder attribOwnerName() const
GLuint buffer
Definition: glcorearb.h:660
void safeNodeMapAccess(const Func &f) const
Runs a functor on the node map with the node lock held.
Definition: PDG_Graph.h:303
IdMap workItemIdMap() const
Returns the map of work item ids -> work item.
Definition: PDG_Graph.h:169
int nodeCount() const
Definition: PDG_Graph.h:112
GLfloat f
Definition: glcorearb.h:1926
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
const PDG_NodePtrMap & nodes() const
Definition: PDG_Graph.h:114
GLuint GLint GLboolean GLint GLenum access
Definition: glcorearb.h:2222
void safeWorkItemAccess(PDG_WorkItemID id, const Func &f) const
Definition: PDG_Graph.h:312
PDG_AttributeCast
Enumeration of attribute cast results.
UT_ConcurrentHashMap< PDG_WorkItemID, PDG_WorkItem * > IdMap
Typedef for work item id -> work item.
Definition: PDG_Graph.h:46
long long int64
Definition: SYS_Types.h:116
void applyDirty(bool remove_outputs)
Applies the stored dirty operation.
A simple class to hold a rwlock and release it when it goes out of scope.
Definition: UT_RWLock.h:22
tbb::concurrent_hash_map< K, T, H, A > UT_ConcurrentHashMap
GLuint const GLchar * name
Definition: glcorearb.h:786
void safeNodeAccess(PDG_NodeID id, const Func &f) const
Runs a functor on the specified node with the node lock held.
Definition: PDG_Graph.h:293
PDG_AttributeFlag
Enumeration of extra attribute flags. Flags can be ORed together.
GLenum GLfloat param
Definition: glcorearb.h:104
UT_RWLock & serialCookLock()
Definition: PDG_Graph.h:288
fpreal64 fpreal
Definition: SYS_Types.h:283
int PDG_NodeID
Node ID type.
Definition: PDG_NodeTypes.h:29
**If you just want to fire and args
Definition: thread.h:618
virtual bool isAttribFlagValid(PDG_AttributeFlag flag) const
Reader/Writer mutex class.
Definition: UT_RWLock.h:48
GLuint * ids
Definition: glcorearb.h:652
int PDG_CacheID
Definition: PDG_NodeTypes.h:30
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297