registry.h
Go to the documentation of this file.
1 //
2 // Copyright 2018 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef PXR_USD_NDR_REGISTRY_H
26 #define PXR_USD_NDR_REGISTRY_H
27 
29 
30 #include "pxr/pxr.h"
31 #include "pxr/usd/ndr/api.h"
32 #include "pxr/base/tf/weakBase.h"
33 #include "pxr/usd/ndr/declare.h"
34 #include "pxr/usd/ndr/discoveryPlugin.h"
35 #include "pxr/usd/ndr/node.h"
36 #include "pxr/usd/ndr/nodeDiscoveryResult.h"
38 #include "pxr/usd/sdf/assetPath.h"
39 #include <map>
40 #include <mutex>
41 
42 PXR_NAMESPACE_OPEN_SCOPE
43 
64 class NdrRegistry : public TfWeakBase
65 {
66 public:
67  using DiscoveryPluginRefPtrVec = NdrDiscoveryPluginRefPtrVector;
68 
76  NDR_API
77  void SetExtraDiscoveryPlugins(DiscoveryPluginRefPtrVec plugins);
78 
86  NDR_API
87  void SetExtraDiscoveryPlugins(const std::vector<TfType>& pluginTypes);
88 
96  NDR_API
97  void AddDiscoveryResult(NdrNodeDiscoveryResult&& discoveryResult);
98 
103  NDR_API
104  void AddDiscoveryResult(const NdrNodeDiscoveryResult& discoveryResult);
105 
112  NDR_API
113  void SetExtraParserPlugins(const std::vector<TfType>& pluginTypes);
114 
137  NDR_API
138  NdrNodeConstPtr GetNodeFromAsset(const SdfAssetPath &asset,
139  const NdrTokenMap &metadata,
140  const TfToken &subIdentifier=TfToken(),
141  const TfToken &sourceType=TfToken());
142 
158  NDR_API
159  NdrNodeConstPtr GetNodeFromSourceCode(const std::string &sourceCode,
160  const TfToken &sourceType,
161  const NdrTokenMap &metadata);
162 
167  NDR_API
168  NdrStringVec GetSearchURIs() const;
169 
177  NDR_API
178  NdrIdentifierVec
179  GetNodeIdentifiers(const TfToken& family = TfToken(),
180  NdrVersionFilter filter =
181  NdrVersionFilterDefaultOnly) const;
182 
189  NDR_API
190  NdrStringVec GetNodeNames(const TfToken& family = TfToken()) const;
191 
212  NDR_API
213  NdrNodeConstPtr GetNodeByIdentifier(const NdrIdentifier& identifier,
214  const NdrTokenVec& sourceTypePriority = NdrTokenVec());
215 
218  NDR_API
219  NdrNodeConstPtr GetNodeByIdentifierAndType(const NdrIdentifier& identifier,
220  const TfToken& sourceType);
221 
231  NDR_API
232  NdrNodeConstPtr GetNodeByName(const std::string& name,
233  const NdrTokenVec& sourceTypePriority = NdrTokenVec(),
234  NdrVersionFilter filter = NdrVersionFilterDefaultOnly);
235 
244  NDR_API
245  NdrNodeConstPtr GetNodeByNameAndType(const std::string& name,
246  const TfToken& sourceType,
247  NdrVersionFilter filter =
248  NdrVersionFilterDefaultOnly);
249 
253  NDR_API
254  NdrNodeConstPtrVec GetNodesByIdentifier(const NdrIdentifier& identifier);
255 
260  NDR_API
261  NdrNodeConstPtrVec GetNodesByName(const std::string& name,
262  NdrVersionFilter filter =
263  NdrVersionFilterDefaultOnly);
264 
271  NDR_API
272  NdrNodeConstPtrVec GetNodesByFamily(const TfToken& family = TfToken(),
273  NdrVersionFilter filter =
274  NdrVersionFilterDefaultOnly);
275 
287  NDR_API
288  NdrTokenVec GetAllNodeSourceTypes() const;
289 
290 protected:
291  NdrRegistry(const NdrRegistry&) = delete;
292  NdrRegistry& operator=(const NdrRegistry&) = delete;
293 
294  NDR_API
295  NdrRegistry();
296 
297  NDR_API
298  ~NdrRegistry();
299 
300 private:
301  class _DiscoveryContext;
302  friend class _DiscoveryContext;
303 
304  using _TypeToParserPluginMap =
305  std::unordered_map<TfToken, NdrParserPlugin*, TfToken::HashFunctor>;
306 
307  // Node cache data structure, stored NdrNodes keyed by identifier and source
308  // type.
309  using _NodeMapKey = std::pair<NdrIdentifier, TfToken>;
310  using _NodeMap = std::unordered_map<_NodeMapKey, NdrNodeUniquePtr, TfHash>;
311 
312  // Discovery results data structure, NdrNodeDiscoveryResults multimap keyed
313  // by identifier
314  using _DiscoveryResultsByIdentifier = std::unordered_multimap<
316  using _DiscoveryResultsByIdentifierRange =
317  std::pair<_DiscoveryResultsByIdentifier::const_iterator,
318  _DiscoveryResultsByIdentifier::const_iterator>;
319 
320  // Discovery results data structure: a multimap of raw pointers to
321  // NdrNodeDiscoveryResults (i.e. pointers to the discovery results stored
322  // in a _DiscoveryResultsByIdentifier) keyed by name.
323  using _DiscoveryResultPtrsByName = std::unordered_multimap<
324  std::string, const NdrNodeDiscoveryResult *, TfHash>;
325  using _DiscoveryResultPtrsByNameRange =
326  std::pair<_DiscoveryResultPtrsByName::const_iterator,
327  _DiscoveryResultPtrsByName::const_iterator>;
328 
329  // The discovery result data structures are not concurrent and must be kept
330  // in sync, thus they need some locking infrastructure.
331  mutable std::mutex _discoveryResultMutex;
332 
333  // The node map is not a concurrent data structure, thus it needs some
334  // locking infrastructure.
335  mutable std::mutex _nodeMapMutex;
336 
337  // Runs each discovery plugin provided and adds the results to the
338  // internal discovery result maps
339  void _RunDiscoveryPlugins(const DiscoveryPluginRefPtrVec& discoveryPlugins);
340 
341  // Takes the discovery and puts in the maps that hold the discovery results,
342  // keeping them in sync.
343  void _AddDiscoveryResultNoLock(NdrNodeDiscoveryResult&& dr);
344 
345  // Finds and instantiates the discovery plugins
346  void _FindAndInstantiateDiscoveryPlugins();
347 
348  // Finds and instantiates the parser plugins
349  void _FindAndInstantiateParserPlugins();
350 
351  // Instantiates the specified parser plugins and adds them to
352  // the registry.
353  void _InstantiateParserPlugins(const std::set<TfType>& parserPluginTypes);
354 
355  // Parses the node for the discovery result if adding it to the node map if
356  // able and adds the discovery result to the discovery result maps. Intended
357  // for the GetNodeFromAsset and GetNodeFromSourceCode APIs which can add
358  // nodes that don't already appear in the discovery results.
359  NdrNodeConstPtr _ParseNodeFromAssetOrSourceCode(
361 
362  // Implementation helper for getting the first node of the given sourceType
363  // in the range of node discovery results for a paricular identifier.
364  NdrNodeConstPtr _GetNodeInIdentifierRangeWithSourceType(
365  _DiscoveryResultsByIdentifierRange range, const TfToken& sourceType);
366 
367  // Implementation helper for getting the first node of the given sourceType
368  // and matching the given version filter in the range of node discovery
369  // results for a paricular name.
370  NdrNodeConstPtr _GetNodeInNameRangeWithSourceType(
371  _DiscoveryResultPtrsByNameRange range, const TfToken& sourceType,
372  NdrVersionFilter filter);
373 
374  // Thread-safe find of a node in the cache by key.
375  NdrNodeConstPtr _FindNodeInCache(const _NodeMapKey &key) const;
376 
377  // Thread-safe insertion of a node into the cache with a given key. If a
378  // node with the same key already exists in the cache, the pointer to the
379  // existing node will be returned, otherwise the pointer to pointer to the
380  // inserted node is returned.
381  NdrNodeConstPtr _InsertNodeInCache(
382  _NodeMapKey &&key, NdrNodeUniquePtr &&node);
383 
384  // Finds an existing node in the node cache for the discovery result if one
385  // exists. Otherwise it parses the new node, inserts it into the cache, and
386  // returns it. If there was an error parsing or validating the node,
387  // `nullptr` will be returned.
388  NdrNodeConstPtr _FindOrParseNodeInCache(const NdrNodeDiscoveryResult& dr);
389 
390  // Return the parser plugin for a discovery type. Returns null if no parser
391  // plugin has that discovery type.
393  _GetParserForDiscoveryType(const TfToken& discoveryType) const;
394 
395  // The discovery plugins that were found through libplug and/or provided by
396  // the client
397  DiscoveryPluginRefPtrVec _discoveryPlugins;
398 
399  // The parser plugins that have been discovered via the plugin system. Maps
400  // a discovery result's "discovery type" to a specific parser.
401  _TypeToParserPluginMap _parserPluginMap;
402 
403  // The parser plugins. This has ownership of the plugin objects.
404  std::vector<std::unique_ptr<NdrParserPlugin>> _parserPlugins;
405 
406  // The preliminary discovery results prior to parsing. These are stored
407  // in a multimap by identifier and a multimap by name. If accessing or
408  // mutating, _discoveryResultMutex should be used.
409  _DiscoveryResultsByIdentifier _discoveryResultsByIdentifier;
410  _DiscoveryResultPtrsByName _discoveryResultPtrsByName;
411 
412  // Set of all possible source types as determined by the existing discovery
413  // results. Populated along with the discovery result multimaps. If
414  // accessing or mutating, _discoveryResultMutex should be used.
415  TfToken::Set _allSourceTypes;
416 
417  // Maps a node's identifier and source type to a node instance. If accessing
418  // or mutating, _nodeMapMutex should be used.
419  _NodeMap _nodeMap;
420 };
421 
422 PXR_NAMESPACE_CLOSE_SCOPE
423 
424 #endif // PXR_USD_NDR_REGISTRY_H
NdrVersionFilter
Enumeration used to select nodes by version.
Definition: declare.h:203
NDR_API NdrStringVec GetSearchURIs() const
Get the locations where the registry is searching for nodes.
NDR_API NdrNodeConstPtr GetNodeByName(const std::string &name, const NdrTokenVec &sourceTypePriority=NdrTokenVec(), NdrVersionFilter filter=NdrVersionFilterDefaultOnly)
Get the node with the specified name.
Interface for parser plugins.
Definition: parserPlugin.h:125
NDR_API NdrNodeConstPtrVec GetNodesByFamily(const TfToken &family=TfToken(), NdrVersionFilter filter=NdrVersionFilterDefaultOnly)
Get all nodes from the registry, optionally restricted to the nodes that fall under a specified famil...
NDR_API NdrIdentifierVec GetNodeIdentifiers(const TfToken &family=TfToken(), NdrVersionFilter filter=NdrVersionFilterDefaultOnly) const
Get the identifiers of all the nodes that the registry is aware of.
NDR_API NdrStringVec GetNodeNames(const TfToken &family=TfToken()) const
Get the names of all the nodes that the registry is aware of.
NDR_API NdrTokenVec GetAllNodeSourceTypes() const
Get a sorted list of all node source types that may be present on the nodes in the registry.
NDR_API NdrNodeConstPtr GetNodeFromAsset(const SdfAssetPath &asset, const NdrTokenMap &metadata, const TfToken &subIdentifier=TfToken(), const TfToken &sourceType=TfToken())
Parses the given asset, constructs a NdrNode from it and adds it to the registry.
NDR_API void SetExtraParserPlugins(const std::vector< TfType > &pluginTypes)
Allows the client to set any additional parser plugins that would otherwise NOT be found through the ...
NDR_API NdrNodeConstPtr GetNodeByIdentifierAndType(const NdrIdentifier &identifier, const TfToken &sourceType)
Get the node with the specified identifier and sourceType.
NDR_API NdrNodeConstPtr GetNodeByIdentifier(const NdrIdentifier &identifier, const NdrTokenVec &sourceTypePriority=NdrTokenVec())
Get the node with the specified identifier, and an optional sourceTypePriority list specifying the se...
NDR_API void AddDiscoveryResult(NdrNodeDiscoveryResult &&discoveryResult)
Allows the client to explicitly set additional discovery results that would otherwise NOT be found th...
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:447
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
std::set< TfToken, TfTokenFastArbitraryLessThan > Set
Predefined type for set of tokens, for when faster lookup is desired, without paying the memory or in...
Definition: token.h:183
The registry provides access to node information.
Definition: registry.h:64
NDR_API NdrNodeConstPtrVec GetNodesByIdentifier(const NdrIdentifier &identifier)
Get all nodes matching the specified identifier (multiple nodes of the same identifier,...
Represents the raw data of a node, and some other bits of metadata, that were determined via a NdrDis...
NDR_API NdrNodeConstPtr GetNodeByNameAndType(const std::string &name, const TfToken &sourceType, NdrVersionFilter filter=NdrVersionFilterDefaultOnly)
A convenience wrapper around GetNodeByName().
Contains an asset path and an optional resolved path.
Definition: assetPath.h:47
NDR_API void SetExtraDiscoveryPlugins(DiscoveryPluginRefPtrVec plugins)
Allows the client to set any additional discovery plugins that would otherwise NOT be found through t...
NDR_API NdrNodeConstPtrVec GetNodesByName(const std::string &name, NdrVersionFilter filter=NdrVersionFilterDefaultOnly)
Get all nodes matching the specified name.
NDR_API NdrNodeConstPtr GetNodeFromSourceCode(const std::string &sourceCode, const TfToken &sourceType, const NdrTokenMap &metadata)
Parses the given sourceCode string, constructs a NdrNode from it and adds it to the registry.
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:141