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