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
46  using IdMap = UT_ConcurrentHashMap<PDG_WorkItemID, PDG_WorkItem*>;
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  /// Accessors for nodes in the graph
107  PDG_Node* node(const UT_StringHolder& name) const;
108  PDG_Node* nodeById(PDG_NodeID id) const;
109  int nodeCount() const
110  { return myNodeNameMap.size(); }
111  const PDG_NodePtrMap& nodes() const
112  { return myNodeNameMap; }
113 
114  /// Returns a unqiue name for a node by adding a numeric suffix until a
115  /// name is found that isn't already in use
116  UT_StringHolder uniqueNodeName(const UT_StringHolder& name);
117 
118  /// Looks up a port using the node.port_name syntax
119  PDG_Port* nodePort(const UT_StringHolder& node_name,
120  const UT_StringHolder& port_name) const;
121  PDG_Port* nodePort(const UT_StringHolder& full_name) const;
122 
123  /// Adds/ removes or queries external dependencies
124  PDG_DependencyPtr dependencyForKey(const UT_StringHolder& key) const;
125  PDG_DependencyPtr addDependency(const UT_StringHolder& type,
126  const UT_StringHolder& key,
127  const PDGT_ValueArgs& args,
128  UT_WorkBuffer& errors);
129  void addDependency(PDG_DependencyPtr dependency);
130  void removeDependency(PDG_DependencyPtr dependency);
131 
132  /// Returns the graph contex that owns this graph
133  PDG_GraphContext* context() const;
134 
135 
136  /// Adds a work item to the work item id -> pointer map
137  void addWorkItem(PDG_WorkItem* work_item);
138 
139  /// Removes a work item from the graph
140  void removeWorkItem(PDG_WorkItem* work_item);
141 
142 
143  /// Returns a work item for a given id
144  PDG_WorkItem* workItemById(PDG_WorkItemID id) const;
145 
146  /// Returns a work item for a given id. Iterates through all active
147  static PDG_WorkItem* workItemByGlobalId(PDG_WorkItemID id);
148 
149  /// Returns a list of work items for a given list of ids
150  void workItemsById(
151  PDG_WorkItemArray& work_items,
153  bool allow_null) const;
154 
155  /// Returns a work item for a given name
156  PDG_WorkItem* workItemByName(const UT_StringHolder& name) const;
157 
158  /// Returns a work item id from a name, assuming the name is using the
159  /// node_id compatibility format
160  PDG_WorkItemID workItemIdFromName(const UT_StringHolder& name) const;
161 
162  /// Returns an array of work item IDs currently in the graph
163  void workItemIds(PDG_WorkItemIDArray& ids) const;
164 
165  /// Returns the map of work item ids -> work item
166  IdMap workItemIdMap() const { return myWorkItemIdMap; }
167 
168  /// Returns a map of item->dependencies, item->dependents and ready items
169  void dependencyGraph(
170  PDG_WorkItemMap& dependencies,
171  PDG_WorkItemMap& dependents,
172  PDG_WorkItemArray& ready,
173  bool expand,
174  PDG_Scheduler* filter) const;
175 
176  /// Returns a static dependency graph as a map of work item -> dependencies
177  /// If "inverse" is true, returns the dependent map instead
178  void dependencyGraph(
179  PDG_WorkItemMap& graph,
180  bool inverse,
181  bool expand,
182  PDG_Scheduler* filter) const;
183 
184  /// Dirties all work items in the graph, faster than the standard dirty
185  /// methods as it can simply blow away everything
186  PDG_WorkItemDirty dirtyAll(
187  bool remove_outputs,
188  bool apply_dirty) const;
189 
190  /// Dirties a work item by id
191  ///
192  /// Note that this method acquires the serial cook write lock, preventing
193  /// any other code from accessing/generating static or dirtying work items
194  PDG_WorkItemDirty dirtyWorkItem(
195  PDG_WorkItemID id,
196  bool should_delete,
197  bool remove_outputs,
198  bool apply_dirty) const;
199 
200  /// Dirties a work item by pointer
201  ///
202  /// Note that this method acquires the serial cook write lock, preventing
203  /// any other code from accessing/generating static or dirtying work items
204  PDG_WorkItemDirty dirtyWorkItem(
205  PDG_WorkItem* work_item,
206  bool should_delete,
207  bool remove_outputs,
208  bool apply_dirty) const;
209 
210  /// Dirities an array of work items
211  ///
212  /// Note that this method acquires the serial cook write lock, preventing
213  /// any other code from accessing/generating static or dirtying work items
214  PDG_WorkItemDirty dirtyWorkItems(
215  const PDG_WorkItemArray& work_items,
216  PDG_Node* source_node,
217  bool should_delete,
218  bool remove_outputs,
219  bool apply_dirty,
220  bool emit_events) const;
221 
222  /// Dirities an array of work items, using the existing dirty state
223  /// object.
224  ///
225  /// Note that this method acquires the serial cook write lock, preventing
226  /// any other code from accessing/generating static or dirtying work items
227  void dirtyWorkItems(
228  const PDG_WorkItemArray& work_items,
229  PDG_WorkItemDirty* dirty_state) const;
230 
231  /// Does a numeric data lookup, for use with the @ operator
232  PDG_AttributeCast numericData(
233  fpreal& param,
234  exint& query_index,
235  const PDG_AttributeEvaluator& evaluator) const;
236 
237  /// Does a string data lookup, for use with the @ operator
238  PDG_AttributeCast stringData(
240  exint& query_index,
241  const PDG_AttributeEvaluator& evaluator,
242  const PDG_EvaluationContext* local_context) const;
243 
244  /// Binds a global attribute to a specific work item
245  void bindGlobalAttribute(
246  const UT_StringHolder& attrib_name,
247  PDG_WorkItem* work_item);
248 
249  /// Returns the work iterm that an attribute is bound to
250  PDG_WorkItem* boundAttributeWorkItem(
251  const UT_StringHolder& attrib_name) const;
252 
253  /// Adjusts the unique id counter so the specified ID is included in the
254  /// range of used values.
255  static void addUniqueId(PDG_WorkItemID id);
256 
257  /// Returns a new unique work item id
258  static PDG_WorkItemID uniqueWorkItemId();
259 
260  /// Returns the current maximum unique work item id
261  static PDG_WorkItemID currentWorkItemId();
262 
263  /// Returns a new unique cache id
264  PDG_CacheID uniqueCacheId();
265 
266  /// Returns a new unique node id
267  PDG_NodeID uniqueNodeId();
268 
269  /// Increments the graph's cache id.
270  void bumpCacheId();
271 
272  /// Returns the serial cook RW lock. This is only so that PDG_Node is able
273  /// to use the lock to guard access to its static items, wrappers and done
274  /// item lists.
276  { return mySerialCookLock; }
277 
278  /// Runs a functor on the specified node with the node lock held.
279  template <typename Func>
280  void safeNodeAccess(PDG_NodeID id, const Func& f) const
281  {
282  UT_AutoReadLock nodes_lock(myNodesLock);
283  auto it = myNodeIdMap.find(id);
284  if (it != myNodeIdMap.end())
285  f(it->second);
286  }
287 
288  /// Runs a functor on the node map with the node lock held.
289  template <typename Func>
290  void safeNodeMapAccess(const Func& f) const
291  {
292  UT_AutoReadLock nodes_lock(myNodesLock);
293  f(myNodeNameMap);
294  }
295 
296  /// Runs a functor on the specified work item with an ID map iterator
297  /// held.
298  template <typename Func>
300  const Func& f) const
301  {
302  IdMap::accessor access;
303  if (myWorkItemIdMap.find(access, id))
304  f(access->second);
305  }
306 
307 private:
308  friend class PDG_WorkItemDirty;
309 
310  /// Typedef for exteranl dependency map
312 
313  /// Typedef for node id -> node
315 
316  /// Map of work item ID to global attributes bound to that work item
318 
319  /// Inverse map for global attributes, mapping attribute name to work
320  /// item ID
322 
323  void applyDirty(bool remove_outputs);
324 
325 private:
326  PDG_NodePtrMap myNodeNameMap;
327  NodeIdMap myNodeIdMap;
328  IdMap myWorkItemIdMap;
329 
330  GlobalAttribMap myGlobalAttribMap;
331  GlobalAttribInvMap myGlobalAttribInvMap;
332 
333  SYS_AtomicCounter myNodeIdCounter;
334  PDG_CacheID myCacheIdCounter;
335 
336  DepMap myDependencies;
337  PDG_GraphContext* myContext;
338 
339  mutable UT_RWLock myNodesLock;
340  mutable UT_RWLock mySerialCookLock;
341 };
342 
343 #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
void safeNodeMapAccess(const Func &f) const
Runs a functor on the node map with the node lock held.
Definition: PDG_Graph.h:290
IdMap workItemIdMap() const
Returns the map of work item ids -> work item.
Definition: PDG_Graph.h:166
int nodeCount() const
Definition: PDG_Graph.h:109
GLfloat f
Definition: glcorearb.h:1926
const PDG_NodePtrMap & nodes() const
Definition: PDG_Graph.h:111
Definition: core.h:760
GLuint GLint GLboolean GLint GLenum access
Definition: glcorearb.h:2222
void safeWorkItemAccess(PDG_WorkItemID id, const Func &f) const
Definition: PDG_Graph.h:299
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
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:280
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:275
fpreal64 fpreal
Definition: SYS_Types.h:277
int PDG_NodeID
Node ID type.
Definition: PDG_NodeTypes.h:29
**If you just want to fire and args
Definition: thread.h:609
virtual bool isAttribFlagValid(PDG_AttributeFlag flag) const
Reader/Writer mutex class.
Definition: UT_RWLock.h:48
type
Definition: core.h:1059
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