HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
APEX_Registry.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: APEX_Registry.h (APEX Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __APEX_REGISTRY_H__
12 #define __APEX_REGISTRY_H__
13 
14 #include "APEX_API.h"
15 #include "APEX_Callback.h"
16 #include "APEX_CompatibilityMap.h"
17 #include "APEX_COW.h"
18 #include "APEX_Include.h"
19 
20 #include <GA/GA_Types.h>
21 
22 #include <UT/UT_Array.h>
23 #include <UT/UT_ArrayStringMap.h>
24 #include <UT/UT_ArrayStringSet.h>
25 #include <UT/UT_Function.h>
26 #include <UT/UT_Lock.h>
27 #include <UT/UT_Map.h>
28 #include <UT/UT_NonCopyable.h>
29 #include <UT/UT_Notifier.h>
30 #include <UT/UT_SharedPtr.h>
31 #include <UT/UT_StringArray.h>
32 #include <UT/UT_StringHolder.h>
33 #include <UT/UT_UniquePtr.h>
34 #include <SYS/SYS_Types.h>
35 
36 #include <initializer_list>
37 #include <map>
38 #include <string>
39 #include <utility>
40 
41 class GU_DetailHandle;
42 class UN_UniCategory;
43 class UT_DSOHandle;
44 
45 namespace apex
46 {
47 
48 class APEX_Graph;
49 class APEX_Registry;
50 class APEX_OverloadSet;
51 
53 
55 {
56  APEX_REGISTRY_INVALID = -1, // Invalid registry
57  APEX_REGISTRY_CALLBACK, // The callback registry
58  APEX_REGISTRY_COMPONENT, // The component registry
59  APEX_REGISTRY_CONSTRAINT, // The constraint registry
60  APEX_REGISTRY_CONTROL, // The control registry
62 };
63 
65 {
66 public:
67  /// Enumeration of event types.
68  enum Type
69  {
70  CallbacksAdded, // Callback added; names are in the list.
71  SubgraphsUpdated // Subgraphs reloaded.
72  };
73 
75  Type getType() const;
76  const UT_StringArray &getNames() const;
77 
78 private:
79  Type myType;
80  const UT_StringArray &myNames;
81 };
82 
83 
87 
88 
89 /// Registries track callback nodes and subgraph nodes.
90 /// Registries are created in a hierarchy. The "callback" registry holds the
91 /// essential nodes used by descendent registries. For instance, the "callback"
92 /// registry is the parent of the "component" registry (which tracks rig
93 /// component subgraphs). So, each rig component subgraph in the "component"
94 /// registry can make use of the callback nodes and subgraph nodes available
95 /// in its parent registry.
96 class APEX_API APEX_Registry : public UTenable_shared_from_this<APEX_Registry>
97 {
98 public:
99  ~APEX_Registry();
100 
102 
103  static constexpr UT_StringLit theUniCategoryName = "Apex";
104  static constexpr UT_StringLit theUniCategoryLabel = "APEX";
105  static constexpr UT_StringLit theDSOFolder = "apexdso";
106  static constexpr UT_StringLit theBrushRegistryName = "brush";
107  static constexpr UT_StringLit theBrushRegistryGraphFolder = "apexbrush";
108  static constexpr UT_StringLit theCallbackRegistryName = "callback";
109  static constexpr UT_StringLit theCallbackRegistryGraphFolder = "apexgraph";
110  static constexpr UT_StringLit theComponentRegistryName = "component";
111  static constexpr UT_StringLit theComponentRegistryGraphFolder = "apexcomponent";
112  static constexpr UT_StringLit theConstraintRegistryName = "constraint";
113  static constexpr UT_StringLit theConstraintRegistryGraphFolder = "apexconstraint";
114  static constexpr UT_StringLit theControlRegistryName = "control";
115  static constexpr UT_StringLit theControlRegistryGraphFolder = "apexcontrol";
116 
117  /// Returns the global registry map. Registries are looked up by their name.
118  static UT_ArrayStringMap<UT_SharedPtr<APEX_Registry>> &allRegistries();
119 
120  /// Returns the APEX registry using its registry type.
121  static UT_SharedPtr<APEX_Registry> findOrCreateRegistry(APEX_RegistryType reg_type);
122 
123  /// @{ Returns the APEX registries.
124  static UT_SharedPtr<APEX_Registry> findOrCreateBrushRegistry(bool load_subgraphs = true);
125  static UT_SharedPtr<APEX_Registry> findOrCreateCallbackRegistry(bool load_subgraphs = true);
126  static UT_SharedPtr<APEX_Registry> findOrCreateComponentRegistry(bool load_subgraphs = true);
127  static UT_SharedPtr<APEX_Registry> findOrCreateConstraintRegistry(bool load_subgraphs = true);
128  static UT_SharedPtr<APEX_Registry> findOrCreateControlRegistry(bool load_subgraphs = true);
129  /// @}
130 
131  /// Find a registry by its name.
132  static APEX_RegistryPtr findRegistry(const UT_StringRef &reg_name);
133 
134  /// Creates a named registry.
135  /// @param reg_name The name of the new registry.
136  /// @param reg_graph_folder The name of the folder on the HOUDINI_PATH
137  /// holding subgraphs which should be loaded by the new registry.
138  /// @param parent_registries A list of parent registries whose contents
139  /// are accessible by the new registry.
140  /// @param add_to_registry_map When true, the registry is added to the
141  /// global registry map. If a registry with the same name
142  /// already exists in the global map, it is replaced with the
143  /// new registry.
144  static APEX_RegistryPtr createRegistry(
145  const UT_StringRef &reg_name,
146  const UT_StringHolder &reg_graph_folder = "",
147  const APEX_RegistryPtrList &parent_registries = APEX_RegistryPtrList(),
148  bool add_to_registry_map = true);
149 
150  /// @{ Adds a new callback node to the registry. The registry holds a
151  /// pointer to the callback function and does not participate in lifetime
152  /// management of the callback. Therefore, the callback object must exist
153  /// for the lifetime of the registry.
154  void addCallback(const APEX_FunctionBase *f);
155  void addCallbacks(std::initializer_list<const APEX_FunctionBase *> funcs);
156  /// @}
157 
158  /// Returns the number of callback nodes in the registry.
159  exint numCallbacks(bool include_ancestors = false) const;
160 
161  /// Finds the named callback node in the registry.
162  const APEX_FunctionBase *getCallback(
163  const UT_StringRef &callback_name,
164  bool include_ancestors = false) const;
165 
166  /// Returns the overload set which contains all versions of a generic
167  /// callback node. The name of the overload set must contain "<>".
168  // For example, "Add<>" returns an overload set containing all generic
169  // "Add" callback nodes.
170  APEX_OverloadSetPtr getOverloadSet(
171  const UT_StringRef &name,
172  bool include_ancestors = false) const;
173 
174  /// Visits all callback nodes and executes the provided function object.
175  void iterCallbacks(
176  const UT_Function<void(const APEX_FunctionBase &)> &f,
177  bool include_ancestors = false) const;
178 
179  /// Visits all subgraph nodes and executes the provided function object.
180  void iterSubGraphs(
181  const UT_Function<void(const APEX_GraphHandle &)> &f,
182  bool include_ancestors = false) const;
183 
184  /// Loads callback nodes from the dynamic library.
185  /// The dynamic library should define the entry point "addApexFunction"
186  /// with the signature given by @ref addApexFunctionPtr. To register
187  /// callback nodes, use the registry passed to the entry point function to
188  /// call @ref addCallback or @ref addCallbacks.
189  void loadCallbackLibrary(const char *dllpath);
190 
191  /// Loads the subgraph node library (saved as a .bgeo) at the filepath.
192  bool loadSubGraphLibrary(const char *filepath);
193 
194  /// Loads the subgraph node library from an in memory geometry.
195  bool loadSubGraphLibrary(const GU_DetailHandle &gdh, const char *filepath = "",
196  bool replace = false);
197 
198  /// Loads the compatibility file at the filepath.
199  void loadCompatibilityFile(const char *filepath);
200 
201  /// Clears all subgraph nodes loaded by the registry.
202  /// @param except_geo_loaded When true, do not clear subgraphs loaded from
203  /// in memory geometries.
204  void clearSubGraphs(bool except_geo_loaded = false);
205 
206  /// Reload the subgraph node libraries from the registry's graph folder
207  /// (which was specified when creating the registry).
208  void reloadSubGraphLibraries();
209 
210  /// Returns the number of subgraph nodes tracked by the registry.
211  exint numSubGraphs(bool include_ancestors = false) const;
212 
213  /// Returns an array of subgraph node names.
214  UT_StringArray getSubGraphNames(
215  const char *version = nullptr,
216  bool include_ancestors = false) const;
217 
218  /// Returns the path of the subgraph library from which a named subgraph
219  /// node was loaded. If the subgraph node was loaded from a geometry,
220  /// returns "<subgraph>".
221  const UT_StringHolder &getSubGraphPath(
222  const UT_StringRef &name,
223  bool include_ancestors = false) const;
224 
225  /// Returns the subgraph node's geometry representation.
226  const ApexGeometry &getSubGraphGeo(
227  const UT_StringRef &name,
228  bool include_ancestors = false) const;
229 
230  /// Returns the named subgraph node as an @ref APEX_Graph.
231  const APEX_GraphHandle &getSubGraph(
232  const UT_StringRef &name,
233  bool include_ancestors = false) const;
234 
235  /// @name GenericFunctions
236  /// Generic Functions (functions agnostic to being a callback or subgraph).
237  /// @{
238 
239  /// Checks if the @a name (as well as any remapping of the name)
240  /// corresponds to a callback or subgraph tracked by the registry.
241  bool containsName(
242  const UT_StringRef &name,
243  bool include_ancestors = false) const;
244 
245  /// Finds the names of node types matching the @a pattern.
246  /// The default @a version "" matches against the current set of names in
247  /// the registry. When @a version is nullptr, then all names (including the
248  /// names found in the compatibility files) are candidates for matching.
249  /// Otherwise, when a specific @a version is given, the names are matched
250  /// against the names available in that product version.
251  UT_StringArray findMatchingNames(
252  const char *pattern = "*",
253  const char *version = "",
254  bool include_ancestors = false) const;
255 
256  /// A convenience function which checks the compatibility map for @a name
257  /// and returns its latest name in the registry. If @a name is not in the
258  /// compatibility map, it is assumed to already be up to date.
259  UT_StringHolder getLatestName(
260  const UT_StringRef &name,
261  bool include_ancestors = false) const;
262 
263  /// Gets a list of available node names that have the same base (core) name
264  /// as the given name. The list is sorted in descending precedence order.
265  void getNamesInPrecedenceOrder(
266  UT_StringArray &precedence_order,
267  const char *fullname,
268  bool include_ancestors = false) const;
269 
270  /// Get the icon name for given callback
271  ///
272  /// This is first done by mapping it through getLatestName().
273  UT_StringHolder getIconName(
274  const UT_StringRef &name,
275  bool include_ancestors = false) const;
276 
277  /// Returns true if the node should be hidden from the UI.
278  bool getIsHidden(
279  const UT_StringRef &name,
280  bool include_ancestors = false) const;
281 
282  /// Returns the version number in which the node was introduced.
283  UT_StringHolder getMinProductVersion(
284  const UT_StringRef &name,
285  bool include_ancestors = false) const;
286 
287  /// Returns the node's default parameters.
288  const Dict &getParmDefaults(
289  const UT_StringRef &name,
290  bool include_ancestors = false) const;
291 
292  /// Returns the signature of the node.
293  APEX_Signature getSignature(
294  const UT_StringRef &name,
295  bool include_ancestors = false) const;
296 
297  /// @}
298 
299  // Maps from old callback names to new callback names
300  const APEX_CompatibilityMap &getCompatibilityMap() const;
301 
302  /// Gets a CompatibilityResolver which builds a mapping from the type
303  /// definition of @a name at @a version to its current type definition. If
304  /// @a version is an empty string, then it is assumed to be the original
305  /// version of the node type and all compatibility entries are used.
307  getCompatibilityResolver(
308  const UT_StringRef &name,
309  const char *version = "",
310  bool include_ancestors = false) const;
311 
312  // Additional legal characters that APEX uses the node type names,
313  // (to match callback names, which use them to indicate parm types).
314  static constexpr auto theNodeTypeSafeChars = UT_StringLit("<,>");
315 
316  /// Returns the UNI category used for the APEX graphs.
317  static const UN_UniCategory *uniCategory();
318 
319  /// Returns an object used for notifying interested parties about
320  /// new callbacks and subgraphs being added.
322 
323  /// Returns the registry's DataID. The DataID is updated each time the
324  /// registry is modified.
325  GA_DataId getDataId() const;
326 
327 private:
328  struct PassKey {};
329 public:
330  /// Use the @ref createRegistry factory method to create a new registry.
332  const UT_StringHolder &registry_graph_folder,
333  const APEX_RegistryPtrList &parent_registries,
334  const PassKey &);
335 
336 private:
337  const UT_Array<APEX_Registry *> &registryList(bool include_ancestors) const;
338 
339  void loadCallbackLibrariesFromPath(const UT_StringRef &dirname);
340  void loadCompatibilityFilesFromPath(const UT_StringRef &dirname);
341 
342  void addCallbackImpl(const UT_StringHolder &name, const APEX_FunctionBase *f);
343 
344  void bumpDataId();
345 
346  /// Sets the registry type.
347  void setRegistryType(APEX_RegistryType reg_type);
348 
349  class SubGraphData;
350 
351  const SubGraphData *getSubGraphData(
352  const UT_StringRef &name,
353  bool include_ancestors = false) const;
354 
355  // Callbacks
356  UT_ArrayStringMap<UT_DSOHandle *> myCallbackLibraries;
358 
359  // SubGraphs
360  UT_StringHolder mySubGraphFolder; // Optional HOUDINI_PATH subdir in which to find subgraphs
361  UT_StringArray mySubGraphLibraries; // Holds all subgraph library filepaths
362  UT_ArrayStringSet mySubGraphLibrariesFromPath; // Tracks subgraph libraries from HOUDINI_PATH
364 
365  // Overload sets
366  // The first set represents overloads using only this registry.
367  // The second set represents overloads of this registry in addition to all
368  // ancestor registries. Since they can be requested independently, they must
369  // also be cached independently.
371 
372  // Compatibility
373  APEX_CompatibilityMap myCompatibilityMap;
374 
375  // Communication
376  // Object that sends notifications about registry changes.
378  GA_DataId myDataId = 0;
379 
380  // Concurrency
381  mutable UT_Lock myLock;
382 
383  // Dependencies
384  APEX_RegistryPtrList myParentRegistries;
385  UT_Array<APEX_Registry *> myRegistryList;
386  UT_Array<APEX_Registry *> myAncestorRegistryList;
387 
388  // Registry type
389  APEX_RegistryType myRegistryType = APEX_REGISTRY_INVALID;
390 };
391 
392 //
393 // APEX_Registry
394 //
397 {
398  // Currently leaked on purpose due to destruction order problems with
399  // referenced types.
400  static auto the_registries = new UT_ArrayStringMap<UT_SharedPtr<APEX_Registry>>();
401  return *the_registries;
402 }
403 
406 {
407  if (reg_type == APEX_REGISTRY_CALLBACK)
409  if (reg_type == APEX_REGISTRY_COMPONENT)
411  if (reg_type == APEX_REGISTRY_CONSTRAINT)
413  if (reg_type == APEX_REGISTRY_CONTROL)
415  return nullptr;
416 }
417 
418 inline const UT_Array<APEX_Registry *> &
419 APEX_Registry::registryList(bool include_ancestors) const
420 {
421  return include_ancestors ? myAncestorRegistryList : myRegistryList;
422 }
423 
424 inline exint
425 APEX_Registry::numSubGraphs(bool include_ancestors) const
426 {
427  exint count = 0;
428  const UT_Array<APEX_Registry *> &reg_list = registryList(include_ancestors);
429  for (const APEX_Registry *reg : reg_list)
430  {
431  count += reg->mySubGraphs.size();
432  }
433  return count;
434 }
435 
436 inline exint
437 APEX_Registry::numCallbacks(bool include_ancestors) const
438 {
439  exint count = 0;
440  const UT_Array<APEX_Registry *> &reg_list = registryList(include_ancestors);
441  for (const APEX_Registry *reg : reg_list)
442  {
443  count += reg->myCallbacks.size();
444  }
445  return count;
446 }
447 
448 inline const APEX_CompatibilityMap &
450 {
451  return myCompatibilityMap;
452 }
453 
454 inline
455 GA_DataId
457 {
458  return myDataId;
459 }
460 
461 inline void
462 APEX_Registry::bumpDataId()
463 {
464  ++myDataId;
465 }
466 
467 inline void
468 APEX_Registry::setRegistryType(APEX_RegistryType reg_type)
469 {
470  myRegistryType = reg_type;
471 }
472 
473 //
474 // APEX_RegistryEvent
475 //
476 inline
478  : myType(type), myNames(names)
479 {
480 }
481 
484 {
485  return myType;
486 }
487 
488 inline const UT_StringArray &
490 {
491  return myNames;
492 }
493 
496 {
497  return myEventNotifier;
498 }
499 
500 }; // namespace apex
501 
502 #endif // __APEX_REGISTRY_H__
static UT_ArrayStringMap< UT_SharedPtr< APEX_Registry > > & allRegistries()
Returns the global registry map. Registries are looked up by their name.
void(*)(APEX_Registry &) addApexFunctionPtr
Definition: APEX_Registry.h:52
void
Definition: png.h:1083
int64 GA_DataId
Definition: GA_Types.h:703
#define APEX_API
Definition: APEX_API.h:21
GA_DataId getDataId() const
int64 exint
Definition: SYS_Types.h:125
const APEX_CompatibilityMap & getCompatibilityMap() const
UT_NotifierImpl< const APEX_RegistryEvent & > & getEventNotifier()
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
std::enable_shared_from_this< T > UTenable_shared_from_this
Definition: UT_SharedPtr.h:39
GLfloat f
Definition: glcorearb.h:1926
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
Sorted map container.
Definition: UT_Map.h:288
APEX_RegistryEvent(Type type, const UT_StringArray &names=UT_StringArray())
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
std::string OIIO_UTIL_API replace(string_view str, string_view pattern, string_view replacement, bool global=false)
static UT_SharedPtr< APEX_Registry > findOrCreateComponentRegistry(bool load_subgraphs=true)
Returns the APEX registries.
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
static UT_SharedPtr< APEX_Registry > findOrCreateConstraintRegistry(bool load_subgraphs=true)
Returns the APEX registries.
GLuint const GLchar * name
Definition: glcorearb.h:786
GLushort pattern
Definition: glad.h:2583
std::function< T > UT_Function
Definition: UT_Function.h:37
static UT_SharedPtr< APEX_Registry > findOrCreateControlRegistry(bool load_subgraphs=true)
Returns the APEX registries.
GT_API const UT_StringHolder version
APEX_RegistryType
Definition: APEX_Registry.h:54
UT_SharedPtr< APEX_Registry > APEX_RegistryPtr
Definition: APEX_Registry.h:84
UT_SharedPtr< APEX_OverloadSet > APEX_OverloadSetPtr
Definition: APEX_Registry.h:86
exint numCallbacks(bool include_ancestors=false) const
Returns the number of callback nodes in the registry.
static UT_SharedPtr< APEX_Registry > findOrCreateRegistry(APEX_RegistryType reg_type)
Returns the APEX registry using its registry type.
UT_Array< APEX_RegistryPtr > APEX_RegistryPtrList
Definition: APEX_Registry.h:85
static UT_SharedPtr< APEX_Registry > findOrCreateCallbackRegistry(bool load_subgraphs=true)
Returns the APEX registries.
const UT_StringArray & getNames() const
exint numSubGraphs(bool include_ancestors=false) const
Returns the number of subgraph nodes tracked by the registry.
Type
Enumeration of event types.
Definition: APEX_Registry.h:68
GLint GLsizei count
Definition: glcorearb.h:405