HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 
278  /// Decreases the reference count of the bundle, and deletes it when it
279  /// reaches zero. Used for discarding unwanted bundles that will no longer
280  /// be used.
281  void deReferenceBundle(const UT_StringRef &prev_bundle);
282 
283  /// Sorts the list of bundles alphabetically. This is useful after
284  /// appending, renaming, or removing any bundles, to mainatin the
285  /// alphanumeric order.
286  void sortBundles();
287 
288  /// Attempts to simplify the given pattern using this bundle list.
289  /// @param root The node with respect to which relative paths are
290  /// specified in the pattern.
291  void simplifyPattern( const OP_Node *root, UT_String &pattern );
292 
293  /// Attempts to simplify the given pattern in a slightly safer manner than
294  /// the other method. The three main differences are:
295  /// it supports groups, it doesn't care about group/bundle contents
296  /// (hence a bit faster), and it ignores unrecognized tokens instead
297  /// of removing them.
298  /// @param root The node with respect to which relative paths are
299  /// specified in the pattern.
300  static void simplifyPatternSafely(const OP_Node *root, UT_String &pattern);
301 
302 
303  /// Implements the hscript command that lists the bundles.
304  void cmdLs(CMD_Args &args);
305 
306  /// Implements the hscript command that adds a new bundle.
307  void cmdAdd(CMD_Args &args);
308 
309  /// Implements the hscript command that removes an old bundle.
310  void cmdRm(CMD_Args &args);
311 
312  /// Implements the hscript command that manipulates bundle contents by
313  /// adding, removing, or replacing the member nodes.
314  void cmdOp(CMD_Args &args);
315 
316  /// Implements the hscript command that renames a bundle.
317  void cmdName(CMD_Args &args);
318 
319  /// Saves the bundle list to the hip file.
320  int saveToHip(std::ostream &os);
321 
322  /// Generates a menu contents that consists of the names of the available
323  /// bundles.
324  /// @param menu An output parameter that will contain new names
325  /// representing the menu entries.
326  /// @param max The maximum number of entries that are allowed to be
327  /// added.
328  /// @param filter If not NULL, the name of the filter that the bundles
329  /// must have, if the are to be added to the menu.
330  void buildBundleMenu(PRM_Name *menu, int max,
331  const char *filter=0,
332  int include_at_sign=1,
333  int put_in_default_message=1);
334 
335  /// Standard function that installs the bundle hscript commands.
336  static void installCommands(CMD_Manager *cmd);
337 
338  /// Invoked when the group has changed. It dirties any bundles whose
339  /// contents depends on that group.
340  void notifyOpsOfGroupChange(OP_Group *group);
341 
342  /// Returns an obiect that emmits events that originated from the
343  /// bundle list.
345  &getEventNotifier() { return myEventNotifier; }
346 
347  /// Prints out all the available bundle filters.
348  void dumpFilters(std::ostream &os);
349 
350 private:
351  /// Alerts all other bundles when a bundle has changed.
352  void notifyBundleChange(const char *name);
353 
354  /// Emits an event notifying that a bundle is about to change.
355  void notifyBundleDeletion(OP_Bundle *bundle);
356 
357  /// Incremeants the touch time (when a bundle is added or removed, and the
358  /// list changes).
359  void touch();
360 
361  /// Obtains nodes that match the pattern (relative paths are specified
362  /// with respect to the root).
363  bool getSortedPatternTokenNodes(
364  const OP_Node *root,
365  const char *pattern_token,
366  OP_NodeList &nodes );
367 
368  /// Notifies bundles of an added node and recures on node's descendents.
369  void nodeAddedRecurse(OP_Bundle *bundle, OP_Node *node);
370 
371  /// Collects the nodes to be removed from a bundle when a given node
372  /// is about to be deleted. These are the descendants of the node.
373  void nodeDeletedRecurse(OP_Bundle *bundle, OP_Node *node,
374  OP_NodeList & to_remove);
375 
376 
377 private:
378  /// The list of non-internal bundles.
379  UT_ValArray<OP_Bundle *> myBundles;
380 
381  /// The list of internal bundles.
382  UT_ValArray<OP_Bundle *> myInternal;
383 
384  /// Look-up table that maps a bundle name to the bundle pointer.
386 
387  /// Flag that indicates if the list needs to be re-sorted.
388  int mySortDirty;
389 
390  /// The version integer that is incremented each time the bundle list
391  /// changes (eg, when a bundle is added or removed).
392  int myTouchTime;
393 
394  /// ID's of nodes to add once director complets loading.
395  UT_IntArray myPendingBulkAdded;
396 
397  /// Object that nodifies about bundle list events.
398  UT_NotifierImpl<OP_BundleListEvent&> myEventNotifier;
399 };
400 
401 
402 // helper class for saving/restoring node bundle memberships
403 class op_NodeBundle;
405 {
406 public:
408  OP_NodeBundleMemberships( OP_BundleList *bundle_list );
410 
411  /// Saves all node bundle memberships including descendents.
412  void saveMemberships( OP_Node *node );
413 
414  /// Restore previously saved node bundle memberships.
415  void restoreMemberships( OP_Node *node );
416 
417  /// Return number of bytes used in RAM.
418  int64 getMemoryUsage() const;
419 
420  /// Returns the number of bundles.
421  int getNumBundles() const;
422 
423 private: // methods
424  void saveChildMemberships( OP_Node *node, OP_Node *root );
425 
426 private: // data
427  UT_ValArray<op_NodeBundle *> myNodeBundles;
428  OP_BundleList * myBundleList;
429 };
430 
431 #endif
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2544
OP_BundleListEventType myEventType
Definition: OP_BundleList.h:49
png_uint_32 i
Definition: png.h:2877
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
long long int64
Definition: SYS_Types.h:106
int internalEntries() const
Returns the number of internal bundles.
Definition: OP_BundleList.h:79
UT_NotifierImpl< OP_BundleListEvent & > & getEventNotifier()
GLuint const GLchar * name
Definition: glcorearb.h:785
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:785
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
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:1296