HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OP_BundleList.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_BundleList.h ( OP_BundleList Library, C++)
7  *
8  * COMMENTS: Container for bundles of objects
9  */
10 
11 #ifndef __OP_BundleList__
12 #define __OP_BundleList__
13 
14 #include "OP_API.h"
15 #include <iosfwd>
16 #include <UT/UT_ValArray.h>
17 #include <UT/UT_IntArray.h>
18 #include <UT/UT_SymbolTable.h>
19 #include <UT/UT_Notifier.h>
20 #include "OP_Node.h"
21 
22 class UT_String;
23 class PRM_Name;
24 class OP_Node;
25 class OP_Network;
26 class CMD_Args;
27 class CMD_Manager;
28 class OP_Bundle;
29 class OP_Group;
30 class OP_BundleFilter;
31 
32 
33 // a small class for notifications about bundle events
35 {
36 public:
37 
39  {
40  BUNDLE_ADDED, // bundle was created or added to the list
41  BUNDLE_DELETED, // bundle was removed from the list
42  BUNDLE_CHANGED // a bundle changed
43  };
44 
46  : myEventType( type ), myBundle( bundle ) {}
47 
48  // the event type
51 };
52 
53 
54 // definition of the bundle list
56 {
57 public:
58  OP_BundleList();
59  ~OP_BundleList();
60 
61  /// Deletes all bundles (internal or non-internal).
62  void clear();
63 
64  /// Returns the number of non-internal bundles.
65  int entries() const { return myBundles.entries(); }
66 
67  /// Returns the i-th non-internal bundle.
68  OP_Bundle *getBundle(int i) { return myBundles(i); }
69 
70  /// Searches for the bundle by name, and returns it if found. Otherwise
71  /// returns NULL.
72  OP_Bundle *getBundle(const char *name);
73 
74  /// Obtains the list of bundles whose names match the given pattern.
75  void getBundlesByPattern( const char * pattern,
76  UT_ValArray<OP_Bundle *> & bundles );
77 
78  /// Returns the number of internal bundles.
79  int internalEntries() const { return myInternal.entries(); }
80 
81  /// Returns the i-th internal bundle.
82  OP_Bundle *getInternalBundle(int i) { return myInternal(i); }
83 
84  /// Creates and returns a new bundle.
85  /// @param name The name of the bundle.
86  /// @param internal If true, the created bundle is internal. Otherwise,
87  /// it's non-internal.
88  OP_Bundle *createBundle(const char *name, int internal=0);
89 
90  /// Creates a duplicate of a given bundle. The new bundle's name is similar
91  /// to the original, but a numerical suffix is appended.
92  /// @param bundle The bundle to duplicate.
93  OP_Bundle *duplicateBundle(OP_Bundle * bundle);
94 
95  /// Deletes the bundle of a given name. Before the bundle is deleted an
96  /// event is sent out.
97  /// @param name The name of the bundle to delete.
98  ///
99  /// @return True if the bundle was found and destroyed.
100  int destroyBundle(const char *name);
101  int destroyBundle(int index);
102 
103  /// Returns a potential bundle name that has no duplicate among the
104  /// existing bundles.
105  /// @param base The desired name of the bundle. If that name is not
106  /// taken, it will be returned. Otherwise, a numerical
107  /// suffix will be appended.
108  char * findUniqueBundleName(const char *base = NULL);
109  int renameBundle(const char *oldname, const char *newname);
110 
111  /// Obtains an array of pointers to the non-internal bundles that
112  /// the given node is a member of. This will NOT return indices to
113  /// internal bundles.
114  /// @returns The number of bundles returned.
115  int getMemberships(const OP_Node *node,
116  UT_ValArray<OP_Bundle *> &memberships) const;
117 
118  /// Sets a new bundle filter.
119  /// @param bname The bundle name.
120  /// @param fname The filter name.
121  /// @return The previous filter.
122  const OP_BundleFilter *setBundleFilter(const char *bname,
123  const char *fname);
124  /// Returns the filter by the given name, or NULL if not found.
125  const OP_BundleFilter *lookupFilter(const char *name) const;
126 
127  /// Obtains a list of existing filters.
128  void getFilters( UT_ValArray<const OP_BundleFilter *> &list );
129 
130 
131  /// A convenience method to set the lock on the member nodes of a bundle,
132  /// within an undo bloc.
133  void bundleSetLock( OP_Bundle *bundle, bool lock );
134 
135  /// A convenience method to set a filter on a bundle, within an undo block.
136  /// @param fname The name of the new filter.
137  /// @return The old filter.
138  const OP_BundleFilter *bundleSetFilter(OP_Bundle* bundle,
139  const char *fname);
140 
141  /// A convenience method to set a filter on a bundle, within an undo block.
142  /// @return The old filter.
143  const OP_BundleFilter *bundleSetFilter(OP_Bundle* bundle,
144  const OP_BundleFilter *filter);
145 
146  /// A convenience method to set a pattern on a bundle, within an undo block.
147  /// If a bundle was a normal bundle, it is turned into a pattern bundle.
148  void bundleSetPattern(OP_Bundle* bundle,
149  const char * pattern);
150 
151  /// A convenience method to remove all nodes from the bundle, within an undo
152  /// block, and to send out a notification.
153  void bundleClear( OP_Bundle *bundle );
154 
155  /// A convenience method to add a node to the bundle, within an undo
156  /// block, and to send out a notification.
157  /// @return The number of nodes added.
158  int bundleAddOp( OP_Bundle *bundle, OP_Node* node );
159 
160  /// A convenience method to add nodes to the bundle, within an undo
161  /// block, and to send out a notification.
162  /// @return The number of nodes added.
163  int bundleAddOps(OP_Bundle *bundle,
164  const OP_NodeList &nodes );
165 
166  /// A convenience method to remove a node from the bundle, within an undo
167  /// block, and to send out a notification.
168  /// @return The number of nodes removed.
169  int bundleRemoveOp( OP_Bundle *bundle, OP_Node* node );
170 
171  /// A convenience method to remove nodes from the bundle, within an undo
172  /// block, and to send out a notification.
173  /// @return The number of nodes removed.
174  int bundleRemoveOps(OP_Bundle *bundle,
175  const OP_NodeList &nodes );
176 
177  /// A notifier called by OP_Network when a node has been created. Adds the
178  /// node to any matching pattern bundles.
179  void nodeAdded(OP_Node *node);
180 
181  /// A notifier called by OP_Network when a node has been deleted. Removes
182  /// the node from any bundles that contain it.
183  void nodeDeleted(OP_Node *node);
184 
185  /// A notifier called by OP_Network when a node has been renamed. Removes
186  /// the node from any pattern bundles that the node no longer matches, and
187  /// adds the node to any pattern bundles that the node now matches.
188  void nodeRenamed(OP_Node *node);
189 
190  /// A notifier called when the node type (or its representative type) has
191  /// changed. It reapplies the filters to the bundles to see if the node
192  /// now passes the type tests.
193  void refilterOp(OP_Node &node);
194 
195  /// Called when director is finished loading. It adds the nodes to any
196  /// matching bundles.
197  // NB: if loading is nested (as it sometimes happens with nested OTLs)
198  // and we are still loading when this method is invoked,
199  // nodes will be added to a pending list. When the bulkAddNodes is
200  // invoked later (since it is invoked always after endLoading()),
201  // and when we are no longer loading, then we process both nodes and
202  // pending nodes. If nodes is NULL then it tries to flush pending unless
203  // director is still loading.
204  void bulkAddNodes(const OP_NodeList *nodes);
205 
206  /// Returns the integer indicating the list version number. Each time
207  /// the list changes (a bundle is added, removed, etc) the integer is
208  /// incremented. This can be used to avoid any recomputations, if nothing
209  /// has changed.
210  int getTouchTime() const { return myTouchTime; }
211 
212  /// Returns an internal bundle that has the specified pattern.
213  /// If the bundle already exists (as specified by the name parameter)
214  /// and the method parameters correspond to the bundle attributes, then it
215  /// is reused and returned. Otherwise, a new bundle is created, configured,
216  /// and returned; in this case, if there is any old bundle matching the
217  /// given name, its reference count is decreased. This is handy for
218  /// streamlined requests for internal pattern bundles, where this method
219  /// can be invoked with the same UT_String object and different pattern, and
220  /// the old bundles are seamlessly deleted and new ones created.
221  ///
222  /// This method will get a pattern style (i.e. internal bundle) based on the
223  /// creator and the pattern specified. The "style" parameter should be a
224  /// unique string for the type of pattern (i.e. "lightmask").
225  /// To maintain proper reference counting, the method takes a reference to a
226  /// pointer. This allows the list to maintain the list of referenced
227  /// patterns. The subnet_inclusion argument determines whether subnet
228  /// contents are included unless explicitly excluded.
229  /// @param prev_bundle The name of the bundle created before based on a
230  /// pattern (perhaps the same or perhaps different) used for the same
231  /// purpose as the bundle obtained by this method. If, a bundle given by
232  /// this parameter exists, and it is a of a different pattern, then its
233  /// reference count will be decremented (and bundle deleted if it
234  /// reaches zero). Upon return of this method, this parameter will
235  /// contain the name of the new bundle. If prev_bundle exists, and it
236  /// exhibits the same properties as specified in the method invocation,
237  /// then that bundle is reused, the prev_bundle parameter is unchanged,
238  /// and no reference count is bumped or decreased (ie, just reusing
239  /// the bundle). This parameter can be an empty string (eg, when called
240  /// for the very first time).
241  /// @param creator The node at which the search for matching nodes
242  /// begins. It's like a root node in the node parenthood hierarchy. Only
243  /// nodes contained by the creator are considered for the bundle
244  /// membership; that is only children, grandchildreen, etc of the root
245  /// node are considered.
246  /// @param relativeto The node with respect to which the relative node
247  /// paths are specified in the pattern.
248  /// @param pattern The node name or path pattern. Any nodes that match
249  /// the patterns will be included in the bundle.
250  /// @param filter The name of the OP_BundleFilter filter that needs to
251  /// be applied to the bundle. Only nodes passing the filter test
252  /// (usually the node type test) will be included in the bundle.
253  /// @param label An arbitrary label that is included in the
254  /// construction of the name for the new bundle. May be used for
255  /// differentiating between bundles with the same pattern and filter.
256  /// @param subnet_inclusion If true, a node will be included in the
257  /// bundle if any of its ancestors (parent, grandparent, etc) matches
258  /// the patter, even if the node itself does not match the pattern.
259  /// @param addinterest If true, the relativeto node will request an
260  /// interest in the bundle, so it is dirtied an recooked whenever
261  /// the contents of the returned internal pattern bundle changes.
262  /// This is because it is usually the relativeto nodes that invoke this
263  /// method during their cook path (and parameter evaluation), to gather
264  /// any other nodes (defined by the pattern), process them, and update
265  /// own cooked values according to them; since the cooked values are
266  /// dependent on the gathered nodes, and the gathered nodes
267  /// depend on the pattern, then the cooked node needs to be marked as
268  /// dirty.
269  OP_Bundle *getPattern(UT_String &prev_bundle,
270  const OP_Network *creator,
271  const OP_Node *relativeto,
272  const char *pattern,
273  const char *filter = 0,
274  const char *label = 0,
275  bool subnet_inclusion = true,
276  bool addinterest=1,
277  bool ignore_case = false);
278 
279  /// Decreases the reference count of the bundle, and deletes it when it
280  /// reaches zero. Used for discarding unwanted bundles that will no longer
281  /// be used.
282  void deReferenceBundle(const UT_StringRef &prev_bundle);
283 
284  /// Sorts the list of bundles alphabetically. This is useful after
285  /// appending, renaming, or removing any bundles, to mainatin the
286  /// alphanumeric order.
287  void sortBundles();
288 
289  /// Attempts to simplify the given pattern using this bundle list.
290  /// @param root The node with respect to which relative paths are
291  /// specified in the pattern.
292  void simplifyPattern( const OP_Node *root, UT_String &pattern );
293 
294  /// Attempts to simplify the given pattern in a slightly safer manner than
295  /// the other method. The three main differences are:
296  /// it supports groups, it doesn't care about group/bundle contents
297  /// (hence a bit faster), and it ignores unrecognized tokens instead
298  /// of removing them.
299  /// @param root The node with respect to which relative paths are
300  /// specified in the pattern.
301  static void simplifyPatternSafely(const OP_Node *root, UT_String &pattern);
302 
303 
304  /// Implements the hscript command that lists the bundles.
305  void cmdLs(CMD_Args &args);
306 
307  /// Implements the hscript command that adds a new bundle.
308  void cmdAdd(CMD_Args &args);
309 
310  /// Implements the hscript command that removes an old bundle.
311  void cmdRm(CMD_Args &args);
312 
313  /// Implements the hscript command that manipulates bundle contents by
314  /// adding, removing, or replacing the member nodes.
315  void cmdOp(CMD_Args &args);
316 
317  /// Implements the hscript command that renames a bundle.
318  void cmdName(CMD_Args &args);
319 
320  /// Saves the bundle list to the hip file.
321  int saveToHip(std::ostream &os);
322 
323  /// Generates a menu contents that consists of the names of the available
324  /// bundles.
325  /// @param menu An output parameter that will contain new names
326  /// representing the menu entries.
327  /// @param max The maximum number of entries that are allowed to be
328  /// added.
329  /// @param filter If not NULL, the name of the filter that the bundles
330  /// must have, if the are to be added to the menu.
331  void buildBundleMenu(PRM_Name *menu, int max,
332  const char *filter=0,
333  int include_at_sign=1,
334  int put_in_default_message=1);
335 
336  /// Standard function that installs the bundle hscript commands.
337  static void installCommands(CMD_Manager *cmd);
338 
339  /// Invoked when the group has changed. It dirties any bundles whose
340  /// contents depends on that group.
341  void notifyOpsOfGroupChange(OP_Group *group);
342 
343  /// Returns an obiect that emmits events that originated from the
344  /// bundle list.
346  &getEventNotifier() { return myEventNotifier; }
347 
348  /// Prints out all the available bundle filters.
349  void dumpFilters(std::ostream &os);
350 
351 private:
352  /// Alerts all other bundles when a bundle has changed.
353  void notifyBundleChange(const char *name);
354 
355  /// Emits an event notifying that a bundle is about to change.
356  void notifyBundleDeletion(OP_Bundle *bundle);
357 
358  /// Incremeants the touch time (when a bundle is added or removed, and the
359  /// list changes).
360  void touch();
361 
362  /// Obtains nodes that match the pattern (relative paths are specified
363  /// with respect to the root).
364  bool getSortedPatternTokenNodes(
365  const OP_Node *root,
366  const char *pattern_token,
367  OP_NodeList &nodes );
368 
369  /// Notifies bundles of an added node and recures on node's descendants.
370  void nodeAddedRecurse(OP_Bundle *bundle, OP_Node *node);
371 
372  /// Collects the nodes to be removed from a bundle when a given node
373  /// is about to be deleted. These are the descendants of the node.
374  void nodeDeletedRecurse(OP_Bundle *bundle, OP_Node *node,
375  OP_NodeList & to_remove);
376 
377 
378 private:
379  /// The list of non-internal bundles.
380  UT_ValArray<OP_Bundle *> myBundles;
381 
382  /// The list of internal bundles.
383  UT_ValArray<OP_Bundle *> myInternal;
384 
385  /// Look-up table that maps a bundle name to the bundle pointer.
387 
388  /// Flag that indicates if the list needs to be re-sorted.
389  int mySortDirty;
390 
391  /// The version integer that is incremented each time the bundle list
392  /// changes (eg, when a bundle is added or removed).
393  int myTouchTime;
394 
395  /// ID's of nodes to add once director complets loading.
396  UT_IntArray myPendingBulkAdded;
397 
398  /// Object that nodifies about bundle list events.
399  UT_NotifierImpl<OP_BundleListEvent&> myEventNotifier;
400 };
401 
402 
403 // helper class for saving/restoring node bundle memberships
404 class op_NodeBundle;
406 {
407 public:
409  OP_NodeBundleMemberships( OP_BundleList *bundle_list );
411 
412  /// Saves all node bundle memberships including descendants.
413  void saveMemberships( OP_Node *node );
414 
415  /// Restore previously saved node bundle memberships.
416  void restoreMemberships( OP_Node *node );
417 
418  /// Return number of bytes used in RAM.
419  int64 getMemoryUsage() const;
420 
421  /// Returns the number of bundles.
422  int getNumBundles() const;
423 
424 private: // methods
425  void saveChildMemberships( OP_Node *node, OP_Node *root );
426 
427 private: // data
428  UT_ValArray<op_NodeBundle *> myNodeBundles;
429  OP_BundleList * myBundleList;
430 };
431 
432 #endif
std::string ignore_case(std::string item)
Helper function to allow ignore_case to be passed to IsMember or Transform.
Definition: CLI11.h:3456
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
OP_BundleListEventType myEventType
Definition: OP_BundleList.h:49
int internalEntries() const
Returns the number of internal bundles.
Definition: OP_BundleList.h:79
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
UT_NotifierImpl< OP_BundleListEvent & > & getEventNotifier()
long long int64
Definition: SYS_Types.h:116
GLuint const GLchar * name
Definition: glcorearb.h:786
GLushort pattern
Definition: glad.h:2583
OP_Bundle * getInternalBundle(int i)
Returns the i-th internal bundle.
Definition: OP_BundleList.h:82
int getTouchTime() const
int entries() const
Returns the number of non-internal bundles.
Definition: OP_BundleList.h:65
OP_BundleListEvent(OP_BundleListEventType type, OP_Bundle &bundle)
Definition: OP_BundleList.h:45
#define OP_API
Definition: OP_API.h:10
GLuint index
Definition: glcorearb.h:786
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
**If you just want to fire and args
Definition: thread.h:618
OP_Bundle & myBundle
Definition: OP_BundleList.h:50
OP_Bundle * getBundle(int i)
Returns the i-th non-internal bundle.
Definition: OP_BundleList.h:68
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297