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 
225  /// Dirities an array of work items, using the existing dirty state
226  /// object.
227  ///
228  /// Note that this method acquires the serial cook write lock, preventing
229  /// any other code from accessing/generating static or dirtying work items
230  void dirtyWorkItems(
231  const PDG_WorkItemArray& work_items,
232  PDG_WorkItemDirty* dirty_state) const;
233 
234  /// Does a numeric data lookup, for use with the @ operator
235  PDG_AttributeCast numericData(
236  fpreal& param,
237  exint& query_index,
238  const PDG_AttributeEvaluator& evaluator) const;
239 
240  /// Does a string data lookup, for use with the @ operator
241  PDG_AttributeCast stringData(
243  exint& query_index,
244  const PDG_AttributeEvaluator& evaluator,
245  const PDG_EvaluationContext* local_context) const;
246 
247  /// Binds a global attribute to a specific work item
248  void bindGlobalAttribute(
249  const UT_StringHolder& attrib_name,
250  PDG_WorkItem* work_item);
251 
252  /// Returns the work iterm that an attribute is bound to
253  PDG_WorkItem* boundAttributeWorkItem(
254  const UT_StringHolder& attrib_name) const;
255 
256  /// Adjusts the unique id counter so the specified ID is included in the
257  /// range of used values.
258  static void addUniqueId(PDG_WorkItemID id);
259 
260  /// Returns a new unique work item id
261  static PDG_WorkItemID uniqueWorkItemId();
262 
263  /// Returns the current maximum unique work item id
264  static PDG_WorkItemID currentWorkItemId();
265 
266  /// Returns a new unique cache id
267  PDG_CacheID uniqueCacheId();
268 
269  /// Returns a new unique node id
270  PDG_NodeID uniqueNodeId();
271 
272  /// Increments the graph's cache id.
273  void bumpCacheId();
274 
275  /// Returns the serial cook RW lock. This is only so that PDG_Node is able
276  /// to use the lock to guard access to its static items, wrappers and done
277  /// item lists.
279  { return mySerialCookLock; }
280 
281  /// Runs a functor on the specified node with the node lock held.
282  template <typename Func>
283  void safeNodeAccess(PDG_NodeID id, const Func& f) const
284  {
285  UT_AutoReadLock nodes_lock(myNodesLock);
286  auto it = myNodeIdMap.find(id);
287  if (it != myNodeIdMap.end())
288  f(it->second);
289  }
290 
291  /// Runs a functor on the node map with the node lock held.
292  template <typename Func>
293  void safeNodeMapAccess(const Func& f) const
294  {
295  UT_AutoReadLock nodes_lock(myNodesLock);
296  f(myNodeNameMap);
297  }
298 
299  /// Runs a functor on the specified work item with an ID map iterator
300  /// held.
301  template <typename Func>
303  const Func& f) const
304  {
305  IdMap::accessor access;
306  if (myWorkItemIdMap.find(access, id))
307  f(access->second);
308  }
309 
310 private:
311  friend class PDG_WorkItemDirty;
312 
313  /// Typedef for exteranl dependency map
315 
316  /// Typedef for node id -> node
318 
319  /// Map of work item ID to global attributes bound to that work item
321 
322  /// Inverse map for global attributes, mapping attribute name to work
323  /// item ID
325 
326  void applyDirty(bool remove_outputs);
327 
328 private:
329  PDG_NodePtrMap myNodeNameMap;
330  NodeIdMap myNodeIdMap;
331  IdMap myWorkItemIdMap;
332 
333  GlobalAttribMap myGlobalAttribMap;
334  GlobalAttribInvMap myGlobalAttribInvMap;
335 
336  SYS_AtomicCounter myNodeIdCounter;
337  PDG_CacheID myCacheIdCounter;
338 
339  DepMap myDependencies;
340  PDG_GraphContext* myContext;
341 
342  mutable UT_RWLock myNodesLock;
343  mutable UT_RWLock mySerialCookLock;
344 };
345 
346 #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:293
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:302
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:283
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:278
fpreal64 fpreal
Definition: SYS_Types.h:278
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