HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
registry.h
Go to the documentation of this file.
1 //
2 // Copyright 2018 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 
8 #ifndef PXR_USD_NDR_REGISTRY_H
9 #define PXR_USD_NDR_REGISTRY_H
10 
11 /// \file ndr/registry.h
12 ///
13 /// \deprecated
14 /// All Ndr objects are deprecated in favor of the corresponding Sdr objects
15 /// in sdr/registry.h
16 
17 #include "pxr/pxr.h"
18 #include "pxr/usd/ndr/api.h"
19 #include "pxr/base/tf/weakBase.h"
20 #include "pxr/usd/ndr/declare.h"
22 #include "pxr/usd/ndr/node.h"
25 #include "pxr/usd/sdf/assetPath.h"
26 #include <map>
27 #include <mutex>
28 
30 
31 /// \class NdrRegistry
32 ///
33 /// The registry provides access to node information. "Discovery Plugins" are
34 /// responsible for finding the nodes that should be included in the registry.
35 ///
36 /// Discovery plugins are found through the plugin system. If additional
37 /// discovery plugins need to be specified, a client can pass them to
38 /// `SetExtraDiscoveryPlugins()`.
39 ///
40 /// When the registry is first told about the discovery plugins, the plugins
41 /// will be asked to discover nodes. These plugins will generate
42 /// `NdrNodeDiscoveryResult` instances, which only contain basic metadata. Once
43 /// the client asks for information that would require the node's contents to
44 /// be parsed (eg, what its inputs and outputs are), the registry will begin the
45 /// parsing process on an as-needed basis. See `NdrNodeDiscoveryResult` for the
46 /// information that can be retrieved without triggering a parse.
47 ///
48 /// Some methods in this library may allow for a "family" to be provided. A
49 /// family is simply a generic grouping which is optional.
50 ///
51 /// \deprecated
52 /// Deprecated in favor of SdrRegistry
53 class NdrRegistry : public TfWeakBase
54 {
55 public:
56  using DiscoveryPluginRefPtrVec = NdrDiscoveryPluginRefPtrVector;
57 
58  /// Allows the client to set any additional discovery plugins that would
59  /// otherwise NOT be found through the plugin system. Runs the discovery
60  /// process for the specified plugins immediately.
61  ///
62  /// Note that this method cannot be called after any nodes in the registry
63  /// have been parsed (eg, through GetNode*()), otherwise an error will
64  /// result.
65  NDR_API
67 
68  /// Allows the client to set any additional discovery plugins that would
69  /// otherwise NOT be found through the plugin system. Runs the discovery
70  /// process for the specified plugins immediately.
71  ///
72  /// Note that this method cannot be called after any nodes in the registry
73  /// have been parsed (eg, through GetNode*()), otherwise an error will
74  /// result.
75  NDR_API
76  void SetExtraDiscoveryPlugins(const std::vector<TfType>& pluginTypes);
77 
78  /// Allows the client to explicitly set additional discovery results that
79  /// would otherwise NOT be found through the plugin system. For example
80  /// to support lazily-loaded plugins which cannot be easily discovered
81  /// in advance.
82  ///
83  /// This method will not immediately spawn a parse call which will be
84  /// deferred until a GetNode*() method is called.
85  ///
86  /// \deprecated
87  /// Deprecated in favor of
88  /// SdrRegistry::AddDiscoveryResult(SdrShaderNodeDiscoveryResult&&)
89  NDR_API
90  void AddDiscoveryResult(NdrNodeDiscoveryResult&& discoveryResult);
91 
92  /// Copy version of the method above.
93  /// For performance reasons, one should prefer to use the rvalue reference
94  /// form.
95  /// \overload
96  ///
97  /// \deprecated
98  /// Deprecated in favor of
99  /// SdrRegistry::AddDiscoveryResult(const SdrShaderNodeDiscoveryResult&)
100  NDR_API
101  void AddDiscoveryResult(const NdrNodeDiscoveryResult& discoveryResult);
102 
103  /// Allows the client to set any additional parser plugins that would
104  /// otherwise NOT be found through the plugin system.
105  ///
106  /// Note that this method cannot be called after any nodes in the registry
107  /// have been parsed (eg, through GetNode*()), otherwise an error will
108  /// result.
109  NDR_API
110  void SetExtraParserPlugins(const std::vector<TfType>& pluginTypes);
111 
112  /// Parses the given \p asset, constructs a NdrNode from it and adds it to
113  /// the registry.
114  ///
115  /// Nodes created from an asset using this API can be looked up by the
116  /// unique identifier and sourceType of the returned node, or by URI,
117  /// which will be set to the unresolved asset path value.
118  ///
119  /// \p metadata contains additional metadata needed for parsing and
120  /// compiling the source code in the file pointed to by \p asset correctly.
121  /// This metadata supplements the metadata available in the asset and
122  /// overrides it in cases where there are key collisions.
123  ///
124  /// \p subidentifier is optional, and it would be used to indicate a
125  /// particular definition in the asset file if the asset contains multiple
126  /// node definitions.
127  ///
128  /// \p sourceType is optional, and it is only needed to indicate a
129  /// particular type if the asset file is capable of representing a node
130  /// definition of multiple source types.
131  ///
132  /// Returns a valid node if the asset is parsed successfully using one
133  /// of the registered parser plugins.
134  ///
135  /// \deprecated
136  /// Deprecated in favor of SdrRegistry::GetShaderNodeFromAsset
137  NDR_API
139  const NdrTokenMap &metadata,
140  const TfToken &subIdentifier=TfToken(),
141  const TfToken &sourceType=TfToken());
142 
143  /// Parses the given \p sourceCode string, constructs a NdrNode from it and
144  /// adds it to the registry. The parser to be used is determined by the
145  /// specified \p sourceType.
146  ///
147  /// Nodes created from source code using this API can be looked up by the
148  /// unique identifier and sourceType of the returned node.
149  ///
150  /// \p metadata contains additional metadata needed for parsing and
151  /// compiling the source code correctly. This metadata supplements the
152  /// metadata available in \p sourceCode and overrides it cases where there
153  /// are key collisions.
154  ///
155  /// Returns a valid node if the given source code is parsed successfully
156  /// using the parser plugins that is registered for the specified
157  /// \p sourceType.
158  ///
159  /// \deprecated
160  /// Deprecated in favor of SdrRegistry::GetShaderNodeFromSourceCode
161  NDR_API
162  NdrNodeConstPtr GetNodeFromSourceCode(const std::string &sourceCode,
163  const TfToken &sourceType,
164  const NdrTokenMap &metadata);
165 
166  /// Get the locations where the registry is searching for nodes.
167  ///
168  /// Depending on which discovery plugins were used, this may include
169  /// non-filesystem paths.
170  NDR_API
171  NdrStringVec GetSearchURIs() const;
172 
173  /// Get the identifiers of all the nodes that the registry is aware of.
174  ///
175  /// This will not run the parsing plugins on the nodes that have been
176  /// discovered, so this method is relatively quick. Optionally, a "family"
177  /// name can be specified to only get the identifiers of nodes that belong
178  /// to that family and a filter can be specified to get just the default
179  /// version (the default) or all versions of the node.
180  ///
181  /// \deprecated
182  /// Deprecated in favor of SdrRegistry::GetShaderNodeIdentifiers
183  NDR_API
185  GetNodeIdentifiers(const TfToken& family = TfToken(),
188 
189  /// Get the names of all the nodes that the registry is aware of.
190  ///
191  /// This will not run the parsing plugins on the nodes that have been
192  /// discovered, so this method is relatively quick. Optionally, a "family"
193  /// name can be specified to only get the names of nodes that belong to
194  /// that family.
195  ///
196  /// \deprecated
197  /// Deprecated in favor of SdrRegistry::GetShaderNodeNames
198  NDR_API
199  NdrStringVec GetNodeNames(const TfToken& family = TfToken()) const;
200 
201  /// Get the node with the specified \p identifier, and an optional
202  /// \p sourceTypePriority list specifying the set of node SOURCE types (see
203  /// `NdrNode::GetSourceType()`) that should be searched.
204  ///
205  /// If no sourceTypePriority is specified, the first encountered node with
206  /// the specified identifier will be returned (first is arbitrary) if found.
207  ///
208  /// If a sourceTypePriority list is specified, then this will iterate
209  /// through each source type and try to find a node matching by identifier.
210  /// This is equivalent to calling NdrRegistry::GetNodeByIdentifierAndType
211  /// for each source type until a node is found.
212  ///
213  /// Nodes of the same identifier but different source type can exist
214  /// in the registry. If a node 'Foo' with source types 'abc' and 'xyz'
215  /// exist in the registry, and you want to make sure the 'abc' version
216  /// is fetched before the 'xyz' version, the priority list would be
217  /// specified as ['abc', 'xyz']. If the 'abc' version did not exist in
218  /// the registry, then the 'xyz' version would be returned.
219  ///
220  /// Returns `nullptr` if a node matching the arguments can't be found.
221  ///
222  /// \deprecated
223  /// Deprecated in favor of SdrRegistry::GetShaderNodeByIdentifier
224  NDR_API
226  const NdrTokenVec& sourceTypePriority = NdrTokenVec());
227 
228  /// Get the node with the specified \p identifier and \p sourceType.
229  /// If there is no matching node for the sourceType, nullptr is returned.
230  ///
231  /// \deprecated
232  /// Deprecated in favor of SdrRegistry::GetShaderNodeByIdentifierAndType
233  NDR_API
235  const TfToken& sourceType);
236 
237  /// Get the node with the specified name. An optional priority list
238  /// specifies the set of node SOURCE types (\sa NdrNode::GetSourceType())
239  /// that should be searched and in what order.
240  ///
241  /// Optionally, a filter can be specified to consider just the default
242  /// versions of nodes matching \p name (the default) or all versions
243  /// of the nodes.
244  ///
245  /// \sa GetNodeByIdentifier().
246  ///
247  /// \deprecated
248  /// Deprecated in favor of SdrRegistry::GetShaderNodeByName
249  NDR_API
250  NdrNodeConstPtr GetNodeByName(const std::string& name,
251  const NdrTokenVec& sourceTypePriority = NdrTokenVec(),
253 
254  /// A convenience wrapper around \c GetNodeByName(). Instead of
255  /// providing a priority list, an exact type is specified, and
256  /// `nullptr` is returned if a node with the exact identifier and
257  /// type does not exist.
258  ///
259  /// Optionally, a filter can be specified to consider just the default
260  /// versions of nodes matching \p name (the default) or all versions
261  /// of the nodes.
262  ///
263  /// \deprecated
264  /// Deprecated in favor of SdrRegistry::GetShaderNodeByNameAndType
265  NDR_API
266  NdrNodeConstPtr GetNodeByNameAndType(const std::string& name,
267  const TfToken& sourceType,
270 
271  /// Get all nodes matching the specified identifier (multiple nodes of
272  /// the same identifier, but different source types, may exist). If no nodes
273  /// match the identifier, an empty vector is returned.
274  ///
275  /// \deprecated
276  /// Deprecated in favor of SdrRegistry::GetShaderNodesByIdentifier
277  NDR_API
279 
280  /// Get all nodes matching the specified name. Only nodes matching the
281  /// specified name will be parsed. Optionally, a filter can be specified
282  /// to get just the default version (the default) or all versions of the
283  /// node. If no nodes match an empty vector is returned.
284  ///
285  /// \deprecated
286  /// Deprecated in favor of SdrRegistry::GetShaderNodesByName
287  NDR_API
288  NdrNodeConstPtrVec GetNodesByName(const std::string& name,
291 
292  /// Get all nodes from the registry, optionally restricted to the nodes
293  /// that fall under a specified family and/or the default version.
294  ///
295  /// Note that this will parse \em all nodes that the registry is aware of
296  /// (unless a family is specified), so this may take some time to run
297  /// the first time it is called.
298  ///
299  /// \deprecated
300  /// Deprecated in favor of SdrRegistry::GetShaderNodesByFamily
301  NDR_API
305 
306  /// Get a sorted list of all node source types that may be present on the
307  /// nodes in the registry.
308  ///
309  /// Source types originate from the discovery process, but there is no
310  /// guarantee that the discovered source types will also have a registered
311  /// parser plugin. The actual supported source types here depend on the
312  /// parsers that are available. Also note that some parser plugins may not
313  /// advertise a source type.
314  ///
315  /// See the documentation for `NdrParserPlugin` and
316  /// `NdrNode::GetSourceType()` for more information.
317  ///
318  /// \deprecated
319  /// Deprecated in favor of SdrRegistry::GetAllShaderNodeSourceTypes
320  NDR_API
322 
323 protected:
324  NdrRegistry(const NdrRegistry&) = delete;
325  NdrRegistry& operator=(const NdrRegistry&) = delete;
326 
327  NDR_API
328  NdrRegistry();
329 
330  NDR_API
331  ~NdrRegistry();
332 
333 private:
335  friend class _DiscoveryContext;
336 
337  using _TypeToParserPluginMap =
338  std::unordered_map<TfToken, NdrParserPlugin*, TfToken::HashFunctor>;
339 
340  // Node cache data structure, stored NdrNodes keyed by identifier and source
341  // type.
342  using _NodeMapKey = std::pair<NdrIdentifier, TfToken>;
343  using _NodeMap = std::unordered_map<_NodeMapKey, NdrNodeUniquePtr, TfHash>;
344 
345  // Discovery results data structure, NdrNodeDiscoveryResults multimap keyed
346  // by identifier
347  using _DiscoveryResultsByIdentifier = std::unordered_multimap<
349  using _DiscoveryResultsByIdentifierRange =
350  std::pair<_DiscoveryResultsByIdentifier::const_iterator,
351  _DiscoveryResultsByIdentifier::const_iterator>;
352 
353  // Discovery results data structure: a multimap of raw pointers to
354  // NdrNodeDiscoveryResults (i.e. pointers to the discovery results stored
355  // in a _DiscoveryResultsByIdentifier) keyed by name.
356  using _DiscoveryResultPtrsByName = std::unordered_multimap<
357  std::string, const NdrNodeDiscoveryResult *, TfHash>;
358  using _DiscoveryResultPtrsByNameRange =
359  std::pair<_DiscoveryResultPtrsByName::const_iterator,
360  _DiscoveryResultPtrsByName::const_iterator>;
361 
362  // The discovery result data structures are not concurrent and must be kept
363  // in sync, thus they need some locking infrastructure.
364  mutable std::mutex _discoveryResultMutex;
365 
366  // The node map is not a concurrent data structure, thus it needs some
367  // locking infrastructure.
368  mutable std::mutex _nodeMapMutex;
369 
370  // Runs each discovery plugin provided and adds the results to the
371  // internal discovery result maps
372  void _RunDiscoveryPlugins(const DiscoveryPluginRefPtrVec& discoveryPlugins);
373 
374  // Takes the discovery and puts in the maps that hold the discovery results,
375  // keeping them in sync.
376  void _AddDiscoveryResultNoLock(NdrNodeDiscoveryResult&& dr);
377 
378  // Finds and instantiates the discovery plugins
379  void _FindAndInstantiateDiscoveryPlugins();
380 
381  // Finds and instantiates the parser plugins
382  void _FindAndInstantiateParserPlugins();
383 
384  // Instantiates the specified parser plugins and adds them to
385  // the registry.
386  void _InstantiateParserPlugins(const std::set<TfType>& parserPluginTypes);
387 
388  // Parses the node for the discovery result if adding it to the node map if
389  // able and adds the discovery result to the discovery result maps. Intended
390  // for the GetNodeFromAsset and GetNodeFromSourceCode APIs which can add
391  // nodes that don't already appear in the discovery results.
392  NdrNodeConstPtr _ParseNodeFromAssetOrSourceCode(
394 
395  // Implementation helper for getting the first node of the given sourceType
396  // in the range of node discovery results for a paricular identifier.
397  NdrNodeConstPtr _GetNodeInIdentifierRangeWithSourceType(
398  _DiscoveryResultsByIdentifierRange range, const TfToken& sourceType);
399 
400  // Implementation helper for getting the first node of the given sourceType
401  // and matching the given version filter in the range of node discovery
402  // results for a paricular name.
403  NdrNodeConstPtr _GetNodeInNameRangeWithSourceType(
404  _DiscoveryResultPtrsByNameRange range, const TfToken& sourceType,
406 
407  // Thread-safe find of a node in the cache by key.
408  NdrNodeConstPtr _FindNodeInCache(const _NodeMapKey &key) const;
409 
410  // Thread-safe insertion of a node into the cache with a given key. If a
411  // node with the same key already exists in the cache, the pointer to the
412  // existing node will be returned, otherwise the pointer to pointer to the
413  // inserted node is returned.
414  NdrNodeConstPtr _InsertNodeInCache(
415  _NodeMapKey &&key, NdrNodeUniquePtr &&node);
416 
417  // Finds an existing node in the node cache for the discovery result if one
418  // exists. Otherwise it parses the new node, inserts it into the cache, and
419  // returns it. If there was an error parsing or validating the node,
420  // `nullptr` will be returned.
421  NdrNodeConstPtr _FindOrParseNodeInCache(const NdrNodeDiscoveryResult& dr);
422 
423  // Return the parser plugin for a discovery type. Returns null if no parser
424  // plugin has that discovery type.
426  _GetParserForDiscoveryType(const TfToken& discoveryType) const;
427 
428  // The discovery plugins that were found through libplug and/or provided by
429  // the client
430  DiscoveryPluginRefPtrVec _discoveryPlugins;
431 
432  // The parser plugins that have been discovered via the plugin system. Maps
433  // a discovery result's "discovery type" to a specific parser.
434  _TypeToParserPluginMap _parserPluginMap;
435 
436  // The parser plugins. This has ownership of the plugin objects.
437  std::vector<std::unique_ptr<NdrParserPlugin>> _parserPlugins;
438 
439  // The preliminary discovery results prior to parsing. These are stored
440  // in a multimap by identifier and a multimap by name. If accessing or
441  // mutating, _discoveryResultMutex should be used.
442  _DiscoveryResultsByIdentifier _discoveryResultsByIdentifier;
443  _DiscoveryResultPtrsByName _discoveryResultPtrsByName;
444 
445  // Set of all possible source types as determined by the existing discovery
446  // results. Populated along with the discovery result multimaps. If
447  // accessing or mutating, _discoveryResultMutex should be used.
448  TfToken::Set _allSourceTypes;
449 
450  // Maps a node's identifier and source type to a node instance. If accessing
451  // or mutating, _nodeMapMutex should be used.
452  _NodeMap _nodeMap;
453 };
454 
456 
457 #endif // PXR_USD_NDR_REGISTRY_H
NDR_API void AddDiscoveryResult(NdrNodeDiscoveryResult &&discoveryResult)
NDR_API NdrStringVec GetSearchURIs() const
NdrVersionFilter
Definition: declare.h:198
NDR_API ~NdrRegistry()
GLenum GLint * range
Definition: glcorearb.h:1925
std::vector< TfToken > NdrTokenVec
Definition: declare.h:50
NDR_API NdrNodeConstPtr GetNodeByNameAndType(const std::string &name, const TfToken &sourceType, NdrVersionFilter filter=NdrVersionFilterDefaultOnly)
NdrNode const * NdrNodeConstPtr
Definition: declare.h:64
std::vector< NdrNodeConstPtr > NdrNodeConstPtrVec
Definition: declare.h:66
NdrRegistry & operator=(const NdrRegistry &)=delete
NDR_API NdrNodeConstPtr GetNodeByIdentifier(const NdrIdentifier &identifier, const NdrTokenVec &sourceTypePriority=NdrTokenVec())
friend class _DiscoveryContext
Definition: registry.h:334
NDR_API NdrRegistry()
Definition: hash.h:472
NDR_API NdrNodeConstPtr GetNodeByIdentifierAndType(const NdrIdentifier &identifier, const TfToken &sourceType)
Definition: token.h:70
std::vector< NdrIdentifier > NdrIdentifierVec
Definition: declare.h:45
NDR_API NdrNodeConstPtr GetNodeByName(const std::string &name, const NdrTokenVec &sourceTypePriority=NdrTokenVec(), NdrVersionFilter filter=NdrVersionFilterDefaultOnly)
NDR_API NdrIdentifierVec GetNodeIdentifiers(const TfToken &family=TfToken(), NdrVersionFilter filter=NdrVersionFilterDefaultOnly) const
std::vector< std::string > NdrStringVec
Definition: declare.h:70
NDR_API NdrNodeConstPtr GetNodeFromSourceCode(const std::string &sourceCode, const TfToken &sourceType, const NdrTokenMap &metadata)
NdrDiscoveryPluginRefPtrVector DiscoveryPluginRefPtrVec
Definition: registry.h:56
GLuint const GLchar * name
Definition: glcorearb.h:786
#define NDR_API
Definition: api.h:23
NDR_API NdrNodeConstPtrVec GetNodesByIdentifier(const NdrIdentifier &identifier)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
NDR_API void SetExtraDiscoveryPlugins(DiscoveryPluginRefPtrVec plugins)
std::unique_ptr< NdrNode > NdrNodeUniquePtr
Definition: declare.h:65
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
NDR_API NdrStringVec GetNodeNames(const TfToken &family=TfToken()) const
std::unordered_map< TfToken, std::string, TfToken::HashFunctor > NdrTokenMap
Definition: declare.h:52
NDR_API void SetExtraParserPlugins(const std::vector< TfType > &pluginTypes)
NDR_API NdrNodeConstPtr GetNodeFromAsset(const SdfAssetPath &asset, const NdrTokenMap &metadata, const TfToken &subIdentifier=TfToken(), const TfToken &sourceType=TfToken())
std::set< TfToken, TfTokenFastArbitraryLessThan > Set
Definition: token.h:166
NDR_API NdrNodeConstPtrVec GetNodesByName(const std::string &name, NdrVersionFilter filter=NdrVersionFilterDefaultOnly)
NDR_API NdrNodeConstPtrVec GetNodesByFamily(const TfToken &family=TfToken(), NdrVersionFilter filter=NdrVersionFilterDefaultOnly)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
NDR_API NdrTokenVec GetAllNodeSourceTypes() const