HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
resolver_v2.h
Go to the documentation of this file.
1 //
2 // Copyright 2020 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 #ifndef INCLUDE_AR_RESOLVER
25 #error This file should not be included directly. Include resolver.h instead.
26 #endif
27 
28 #ifndef PXR_USD_AR_RESOLVER_V2_H
29 #define PXR_USD_AR_RESOLVER_V2_H
30 
31 /// \file ar/resolver_v2.h
32 
33 #include "pxr/pxr.h"
34 #include "pxr/usd/ar/api.h"
37 #include "pxr/usd/ar/timestamp.h"
38 
39 #include <memory>
40 #include <string>
41 #include <vector>
42 
44 
45 class ArAsset;
46 class ArAssetInfo;
47 class ArResolverContext;
48 class ArWritableAsset;
49 class TfType;
50 class VtValue;
51 
52 /// \class ArResolver
53 ///
54 /// Interface for the asset resolution system. An asset resolver is
55 /// responsible for resolving asset information (including the asset's
56 /// physical path) from a logical path.
57 ///
58 /// See \ref ar_implementing_resolver for information on how to customize
59 /// asset resolution behavior by implementing a subclass of ArResolver.
60 /// Clients may use #ArGetResolver to access the configured asset resolver.
61 ///
62 class ArResolver
63 {
64 public:
65  AR_API
66  virtual ~ArResolver();
67 
68  // Disallow copies
69  ArResolver(const ArResolver&) = delete;
70  ArResolver& operator=(const ArResolver&) = delete;
71 
72  // --------------------------------------------------------------------- //
73  /// \anchor ArResolver_identifier
74  /// \name Identifiers
75  ///
76  /// Identifiers are canonicalized asset paths that may be assigned
77  /// to a logical asset to facilitate comparisons and lookups. They
78  /// may be used to determine if different asset paths might refer to
79  /// the same asset without performing resolution.
80  ///
81  /// Since identifiers are just a form of asset path, they may be used
82  /// with other functions on ArResolver that require an asset path, like
83  /// Resolve.
84  ///
85  /// If two asset paths produce the same identifier, those asset paths
86  /// must refer to the same asset. However, in some cases comparing
87  /// identifiers may not be sufficient to determine if assets are equal.
88  /// For example, there could be two assets with the same identifier
89  /// but whose contents were read from different resolved paths because
90  /// different resolver contexts were bound when those assets were loaded.
91  ///
92  /// @{
93  // --------------------------------------------------------------------- //
94 
95  /// Returns an identifier for the asset specified by \p assetPath.
96  /// If \p anchorAssetPath is not empty, it is the resolved asset path
97  /// that \p assetPath should be anchored to if it is a relative path.
98  AR_API
100  const std::string& assetPath,
101  const ArResolvedPath& anchorAssetPath = ArResolvedPath()) const;
102 
103  /// Returns an identifier for a new asset specified by \p assetPath.
104  /// If \p anchorAssetPath is not empty, it is the resolved asset path
105  /// that \p assetPath should be anchored to if it is a relative path.
106  AR_API
108  const std::string& assetPath,
109  const ArResolvedPath& anchorAssetPath = ArResolvedPath()) const;
110 
111  /// @}
112 
113  // --------------------------------------------------------------------- //
114  /// \anchor ArResolver_resolution
115  /// \name Path Resolution Operations
116  ///
117  /// @{
118  // --------------------------------------------------------------------- //
119 
120  /// Returns the resolved path for the asset identified by the given \p
121  /// assetPath if it exists. If the asset does not exist, returns an empty
122  /// ArResolvedPath.
123  AR_API
125  const std::string& assetPath) const;
126 
127  /// Returns the resolved path for the given \p assetPath that may be used
128  /// to create a new asset. If such a path cannot be computed for
129  /// \p assetPath, returns an empty ArResolvedPath.
130  ///
131  /// Note that an asset might or might not already exist at the returned
132  /// resolved path.
133  AR_API
135  const std::string& assetPath) const;
136 
137  /// @}
138 
139  // --------------------------------------------------------------------- //
140  /// \anchor ArResolver_context
141  /// \name Asset Resolver Context Operations
142  ///
143  /// @{
144  // --------------------------------------------------------------------- //
145 
146  /// Binds the given context to this resolver.
147  ///
148  /// Clients should generally use ArResolverContextBinder instead of calling
149  /// this function directly.
150  ///
151  /// \see ArResolverContextBinder
152  AR_API
153  void BindContext(
154  const ArResolverContext& context,
155  VtValue* bindingData);
156 
157  /// Unbind the given context from this resolver.
158  ///
159  /// Clients should generally use ArResolverContextBinder instead of calling
160  /// this function directly.
161  ///
162  /// \see ArResolverContextBinder
163  AR_API
164  void UnbindContext(
165  const ArResolverContext& context,
166  VtValue* bindingData);
167 
168  /// Return an ArResolverContext that may be bound to this resolver
169  /// to resolve assets when no other context is explicitly specified.
170  ///
171  /// The returned ArResolverContext will contain the default context
172  /// returned by the primary resolver and all URI resolvers.
173  AR_API
175 
176  /// Return an ArResolverContext that may be bound to this resolver
177  /// to resolve the asset located at \p assetPath or referenced by
178  /// that asset when no other context is explicitly specified.
179  ///
180  /// The returned ArResolverContext will contain the default context
181  /// for \p assetPath returned by the primary resolver and all URI resolvers.
182  AR_API
184  const std::string& assetPath) const;
185 
186  /// Return an ArResolverContext created from the primary ArResolver
187  /// implementation using the given \p contextStr.
188  AR_API
190  const std::string& contextStr) const;
191 
192  /// Return an ArResolverContext created from the ArResolver registered
193  /// for the given \p uriScheme using the given \p contextStr.
194  ///
195  /// An empty \p uriScheme indicates the primary resolver and is
196  /// equivalent to CreateContextFromString(string).
197  ///
198  /// If no resolver is registered for \p uriScheme, returns an empty
199  /// ArResolverContext.
200  AR_API
202  const std::string& uriScheme, const std::string& contextStr) const;
203 
204  /// Return an ArResolverContext created by combining the ArResolverContext
205  /// objects created from the given \p contextStrs.
206  ///
207  /// \p contextStrs is a list of pairs of strings. The first element in the
208  /// pair is the URI scheme for the ArResolver that will be used to create
209  /// the ArResolverContext from the second element in the pair. An empty
210  /// URI scheme indicates the primary resolver.
211  ///
212  /// For example:
213  ///
214  /// \code
215  /// ArResolverContext ctx = ArGetResolver().CreateContextFromStrings(
216  /// { {"", "context str 1"},
217  /// {"my_scheme", "context str 2"} });
218  /// \endcode
219  ///
220  /// This will use the primary resolver to create an ArResolverContext
221  /// using the string "context str 1" and use the resolver registered for
222  /// the "my_scheme" URI scheme to create an ArResolverContext using
223  /// "context str 2". These contexts will be combined into a single
224  /// ArResolverContext and returned.
225  ///
226  /// If no resolver is registered for a URI scheme in an entry in
227  /// \p contextStrs, that entry will be ignored.
228  AR_API
230  const std::vector<
231  std::pair<std::string, std::string>>& contextStrs) const;
232 
233  /// Refresh any caches associated with the given context. If doing so
234  /// would invalidate asset paths that had previously been resolved,
235  /// an ArNotice::ResolverChanged notice will be sent to inform clients
236  /// of this.
237  AR_API
238  void RefreshContext(
239  const ArResolverContext& context);
240 
241  /// Returns the asset resolver context currently bound in this thread.
242  ///
243  /// \see ArResolver::BindContext, ArResolver::UnbindContext
244  AR_API
246 
247  /// Returns true if \p assetPath is a context-dependent path, false
248  /// otherwise.
249  ///
250  /// A context-dependent path may result in different resolved paths
251  /// depending on what asset resolver context is bound when Resolve
252  /// is called. Assets located at the same context-dependent path may not
253  /// be the same since those assets may have been loaded from different
254  /// resolved paths. In this case, the assets' resolved paths must be
255  /// consulted to determine if they are the same.
256  AR_API
258  const std::string& assetPath) const;
259 
260  /// @}
261 
262  // --------------------------------------------------------------------- //
263  /// \anchor ArResolver_files
264  /// \name File/asset-specific Operations
265  ///
266  /// @{
267  // --------------------------------------------------------------------- //
268 
269  /// Returns the file extension for the given \p assetPath. The returned
270  /// extension does not include a "." at the beginning.
271  AR_API
273  const std::string& assetPath) const;
274 
275  /// Returns an ArAssetInfo populated with additional metadata (if any)
276  /// about the asset at the given \p assetPath. \p resolvedPath is the
277  /// resolved path computed for the given \p assetPath.
278  AR_API
280  const std::string& assetPath,
281  const ArResolvedPath& resolvedPath) const;
282 
283  /// Returns an ArTimestamp representing the last time the asset at
284  /// \p assetPath was modified. \p resolvedPath is the resolved path
285  /// computed for the given \p assetPath. If a timestamp cannot be
286  /// retrieved, return an invalid ArTimestamp.
287  AR_API
289  const std::string& assetPath,
290  const ArResolvedPath& resolvedPath) const;
291 
292  /// Returns an ArAsset object for the asset located at \p resolvedPath.
293  /// Returns an invalid std::shared_ptr if object could not be created.
294  ///
295  /// The returned ArAsset object provides functions for accessing the
296  /// contents of the specified asset.
297  AR_API
298  std::shared_ptr<ArAsset> OpenAsset(
299  const ArResolvedPath& resolvedPath) const;
300 
301  /// Enumeration of write modes for OpenAssetForWrite
302  enum class WriteMode
303  {
304  /// Open asset for in-place updates. If the asset exists, its contents
305  /// will not be discarded and writes may overwrite existing data.
306  /// Otherwise, the asset will be created.
307  Update = 0,
308 
309  /// Open asset for replacement. If the asset exists, its contents will
310  /// be discarded by the time the ArWritableAsset is destroyed.
311  /// Otherwise, the asset will be created.
312  Replace
313  };
314 
315  /// Returns an ArWritableAsset object for the asset located at \p
316  /// resolvedPath using the specified \p writeMode. Returns an invalid
317  /// std::shared_ptr if object could not be created.
318  ///
319  /// The returned ArWritableAsset object provides functions for writing data
320  /// to the specified asset.
321  ///
322  /// Note that support for reading an asset through other APIs while it
323  /// is open for write is implementation-specific. For example, writes to
324  /// an asset may or may not be immediately visible to other threads or
325  /// processes depending on the implementation.
326  AR_API
327  std::shared_ptr<ArWritableAsset> OpenAssetForWrite(
328  const ArResolvedPath& resolvedPath,
329  WriteMode writeMode) const;
330 
331  /// Returns true if an asset may be written to the given \p resolvedPath,
332  /// false otherwise. If this function returns false and \p whyNot is not
333  /// \c nullptr, it may be filled with an explanation.
334  AR_API
335  bool CanWriteAssetToPath(
336  const ArResolvedPath& resolvedPath,
337  std::string* whyNot = nullptr) const;
338 
339  /// @}
340 
341  // --------------------------------------------------------------------- //
342  /// \anchor ArResolver_scopedCache
343  /// \name Scoped Resolution Cache
344  ///
345  /// A scoped resolution cache indicates to the resolver that results of
346  /// calls to Resolve should be cached for a certain scope. This is
347  /// important for performance and also for consistency -- it ensures
348  /// that repeated calls to Resolve with the same parameters will
349  /// return the same result.
350  ///
351  /// A resolution cache scope is opened by a call to BeginCacheScope and
352  /// must be closed with a matching call to EndCacheScope. The resolver must
353  /// cache the results of Resolve until the scope is closed. Note that these
354  /// calls may be nested.
355  ///
356  /// Cache scopes are thread-specific: if multiple threads are running and
357  /// a cache scope is opened in one of those threads, caching should be
358  /// enabled in that thread only.
359  ///
360  /// When opening a scope, a resolver may return additional data for
361  /// implementation-specific purposes. This data may be shared across
362  /// threads, so long as it is safe to access this data concurrently.
363  ///
364  /// ArResolverScopedCache is an RAII object for managing cache scope
365  /// lifetimes and data. Clients should generally use that class rather
366  /// than calling the BeginCacheScope and EndCacheScope functions manually.
367  ///
368  /// \see ArResolverScopedCache
369  /// @{
370  // --------------------------------------------------------------------- //
371 
372  /// Mark the start of a resolution caching scope.
373  ///
374  /// Clients should generally use ArResolverScopedCache instead of calling
375  /// this function directly.
376  ///
377  /// Resolvers may fill \p cacheScopeData with arbitrary data. Clients may
378  /// also pass in a \p cacheScopeData populated by an earlier call to
379  /// BeginCacheScope to allow the resolver access to that information.
380  ///
381  /// \see ArResolverScopedCache
382  AR_API
383  void BeginCacheScope(
384  VtValue* cacheScopeData);
385 
386  /// Mark the end of a resolution caching scope.
387  ///
388  /// Clients should generally use ArResolverScopedCache instead of calling
389  /// this function directly.
390  ///
391  /// \p cacheScopeData should contain the data that was populated by the
392  /// previous corresponding call to BeginCacheScope.
393  ///
394  /// \see ArResolverScopedCache
395  AR_API
396  void EndCacheScope(
397  VtValue* cacheScopeData);
398 
399  /// @}
400 
401  // --------------------------------------------------------------------- //
402  /// \anchor ArResolver_deprecated
403  /// \name Deprecated APIs
404  ///
405  /// The functions in this section are deprecated in Ar 2.0 and slated
406  /// for removal. Most have default implementations to allow subclasses
407  /// to ignore them completely.
408  ///
409  /// @{
410  // --------------------------------------------------------------------- //
411 
412  /// \deprecated
413  /// Returns true if the given path is a repository path.
414  AR_API
415  bool IsRepositoryPath(const std::string& path) const;
416 
417  /// @}
418 
419 protected:
420  AR_API
421  ArResolver();
422 
423  // --------------------------------------------------------------------- //
424  /// \anchor ArResolver_implementation
425  /// \name Implementation
426  ///
427  /// @{
428 
429  /// Return an identifier for the asset at the given \p assetPath.
430  /// See \ref ArResolver_identifier "Identifiers" for more information.
431  ///
432  /// If \p anchorAssetPath is non-empty, it should be used as the anchoring
433  /// asset if \p assetPath is relative. For example, for a filesystem-based
434  /// implementation _CreateIdentifier might return:
435  ///
436  /// _CreateIdentifier(
437  /// /* assetPath = */ "/abs/path/to/model.usd",
438  /// /* anchorAssetPath = */ ArResolvedPath("/abs/path/to/shot.usd"))
439  /// => "/abs/path/to/model.usd"
440  ///
441  /// _CreateIdentifier(
442  /// /* assetPath = */ "relative/model.usd",
443  /// /* anchorAssetPath = */ ArResolvedPath("/abs/path/to/shot.usd"))
444  /// => "/abs/path/to/relative/model.usd"
445  ///
446  /// Identifiers may be compared to determine if given paths refer to the
447  /// same asset, so implementations should take care to canonicalize and
448  /// normalize the returned identifier to a consistent format.
449  ///
450  /// If either \p assetPath or \p anchorAssetPath have a URI scheme, this
451  /// function will be called on the resolver associated with that URI scheme,
452  /// if any.
453  ///
454  /// Example uses:
455  /// - When opening a layer via SdfLayer::FindOrOpen or Find,
456  /// CreateIdentifier will be called with the asset path given to those
457  /// functions and no anchoring asset path. The result will be used as the
458  /// layer's identifier.
459  ///
460  /// - When processing composition arcs that refer to other layers, this
461  /// function will be called with the asset path of the referenced layer
462  /// and the resolved path of the layer where the composition arc was
463  /// authored. The result will be passed to SdfLayer::FindOrOpen to
464  /// open the referenced layer.
465  virtual std::string _CreateIdentifier(
466  const std::string& assetPath,
467  const ArResolvedPath& anchorAssetPath) const = 0;
468 
469  /// Return an identifier for a new asset at the given \p assetPath.
470  ///
471  /// This is similar to _CreateIdentifier but is used to create identifiers
472  /// for assets that may not exist yet and are being created.
473  ///
474  /// Example uses:
475  /// - When creating a new layer via SdfLayer::CreateNew,
476  /// CreateIdentifierForNewAsset will be called with the asset path given
477  /// to the function. The result will be used as the new layer's
478  /// identifier.
480  const std::string& assetPath,
481  const ArResolvedPath& anchorAssetPath) const = 0;
482 
483  /// Return the resolved path for the given \p assetPath or an empty
484  /// ArResolvedPath if no asset exists at that path.
485  virtual ArResolvedPath _Resolve(
486  const std::string& assetPath) const = 0;
487 
488  /// Return the resolved path for the given \p assetPath that may be used
489  /// to create a new asset or an empty ArResolvedPath if such a path cannot
490  /// be computed.
492  const std::string& assetPath) const = 0;
493 
494  /// @}
495 
496  // --------------------------------------------------------------------- //
497  /// \anchor ArResolver_contextImplementation
498  /// \name Context Operations Implementation
499  ///
500  /// If any of these functions are implemented in a subclass, the plugin
501  /// metadata for that subclass in the plugin library's plugInfo.json
502  /// must specify:
503  /// \code
504  /// "implementsContexts" : true.
505  /// \endcode
506  ///
507  /// If a subclass indicates that it implements any of these functions,
508  /// its plugin library will be loaded and these functions will be called
509  /// when the corresponding public ArResolver API is called. Otherwise,
510  /// these functions will not be called.
511  ///
512  /// @{
513 
514  /// Bind the given \p context to this resolver. \p bindingData may be
515  /// populated with additional information that will be kept alive while
516  /// \p context is bound. Both \p context and \p bindingData will be
517  /// passed to UnbindContext when the context is being unbound.
518  ///
519  /// Contexts may be nested; if multiple contexts are bound, the context
520  /// that was most recently bound must take precedence and block all
521  /// previously bound contexts.
522  ///
523  /// Context binding is thread-specific; contexts bound in a thread must
524  /// only affect other resolver calls in the same thread.
525  ///
526  /// ArResolver itself manages thread-local stacks of bound contexts.
527  /// Subclasses can retrieve the most recent context object which was passed
528  /// to BindContext using _GetCurrentContextObject. Because of this,
529  /// subclasses typically do not need to implement this function unless they
530  /// need to be informed when a context object is bound. For example, this
531  /// may be needed if the context needs to be passed on to another subsystem
532  /// that manages these bindings itself.
533  ///
534  /// The default implementation does nothing.
535  AR_API
536  virtual void _BindContext(
537  const ArResolverContext& context,
538  VtValue* bindingData);
539 
540  /// Unbind the given \p context from this resolver.
541  ///
542  /// It is an error if the context being unbound is not the currently
543  /// bound context.
544  ///
545  /// Subclasses typically do not need to implement this function since
546  /// ArResolver itself keeps track of the contexts that are bound via calls
547  /// to BindContext. However, subclasses may need to implement this function
548  /// if they are managing these bindings itself.
549  ///
550  /// The default implementation does nothing.
551  AR_API
552  virtual void _UnbindContext(
553  const ArResolverContext& context,
554  VtValue* bindingData);
555 
556  /// Return a default ArResolverContext that may be bound to this resolver
557  /// to resolve assets when no other context is explicitly specified.
558  ///
559  /// When CreateDefaultContext is called on the configured asset resolver,
560  /// Ar will call this method on the primary resolver and all URI resolvers
561  /// and merge the results into a single ArResolverContext that will be
562  /// returned to the consumer.
563  ///
564  /// This function should not automatically bind this context, but should
565  /// create one that may be used later.
566  ///
567  /// The default implementation returns a default-constructed
568  /// ArResolverContext.
569  ///
570  /// Example uses:
571  /// - UsdStage will call CreateDefaultContext when creating a new stage with
572  /// an anonymous root layer and without a given context. The returned
573  /// context will be bound when resolving asset paths on that stage.
574  AR_API
576 
577  /// Return an ArResolverContext that may be bound to this resolver
578  /// to resolve the asset located at \p assetPath or referenced by
579  /// that asset when no other context is explicitly specified.
580  ///
581  /// When CreateDefaultContextForAsset is called on the configured asset
582  /// resolver, Ar will call this method on the primary resolver and all URI
583  /// resolvers and merge the results into a single ArResolverContext that
584  /// will be returned to the consumer.
585  ///
586  /// Note that this means this method may be called with asset paths that
587  /// are not associated with this resolver. For example, this method may
588  /// be called on a URI resolver with a non-URI asset path. This is to
589  /// support cases where the asset at \p assetPath references other
590  /// assets with URI schemes that differ from the URI scheme (if any)
591  /// in \p assetPath.
592  ///
593  /// This function should not automatically bind this context, but should
594  /// create one that may be used later.
595  ///
596  /// The default implementation returns a default-constructed
597  /// ArResolverContext.
598  ///
599  /// Example uses:
600  /// - UsdStage will call CreateDefaultContextForAsset when creating a new
601  /// stage with a non-anonymous root layer and without a given context. The
602  /// resolved path of the root layer will be passed in as the
603  /// \p assetPath. The returned context will be bound when resolving asset
604  /// paths on that stage.
605  AR_API
607  const std::string& assetPath) const;
608 
609  /// Return an ArResolverContext created from the given \p contextStr.
610  ///
611  /// The default implementation returns a default-constructed
612  /// ArResolverContext.
613  AR_API
615  const std::string& contextStr) const;
616 
617  /// Refresh any caches associated with the given context. If doing so
618  /// would invalidate asset paths that had previously been resolved,
619  /// this function should send an ArNotice::ResolverChanged notice to
620  /// inform clients of this. See documentation on that class for more
621  /// details.
622  ///
623  /// The default implementation does nothing.
624  AR_API
625  virtual void _RefreshContext(
626  const ArResolverContext& context);
627 
628  /// Return the currently bound context. Since context binding is
629  /// thread-specific, this should return the context that was most recently
630  /// bound in this thread.
631  ///
632  /// Subclasses typically do not need to implement this function since
633  /// ArResolver itself keeps track of the contexts that are bound via calls
634  /// to BindContext. However, if a subclass is managing bound contexts itself
635  /// and allows clients to bind context objects via other API outside of
636  /// BindContext, this function should return the context object as described
637  /// above. This typically happens with subclasses that are wrappers around
638  /// other resolution subsystems. \see _BindContext for more information.
639  ///
640  /// The default implementation returns a default-constructed
641  /// ArResolverContext.
642  AR_API
643  virtual ArResolverContext _GetCurrentContext() const;
644 
645  /// Return true if the result of resolving the given \p assetPath may
646  /// differ depending on the asset resolver context that is bound when
647  /// Resolve is called, false otherwise.
648  ///
649  /// The default implementation returns false.
650  ///
651  /// Example uses:
652  /// - SdfLayer will call this function to check if the identifier given
653  /// to SdfLayer::Find or SdfLayer::FindOrOpen is context-dependent.
654  /// If it is and a layer exists with the same identifier, SdfLayer
655  /// can return it without resolving the identifier. If it is not,
656  /// SdfLayer must resolve the identifier and search for a layer with
657  /// the same resolved path, even if a layer exists with the same
658  /// identifier.
659  AR_API
660  virtual bool _IsContextDependentPath(
661  const std::string& assetPath) const;
662 
663  /// @}
664 
665  // --------------------------------------------------------------------- //
666  /// \anchor ArResolver_assetImplementation
667  /// \name Asset Operations Implementation
668  ///
669  /// @{
670 
671  /// Return the file extension for the given \p assetPath. This extension
672  /// should not include a "." at the beginning of the string.
673  ///
674  /// The default implementation returns the string after the last "."
675  /// in \p assetPath. If \p assetPath begins with a ".", the extension
676  /// will be empty unless there is another "." in the path. If
677  /// \p assetPath has components separated by '/' (or '\' on Windows),
678  /// only the last component will be considered.
679  AR_API
680  virtual std::string _GetExtension(
681  const std::string& assetPath) const;
682 
683  /// Return an ArAssetInfo populated with additional metadata (if any)
684  /// about the asset at the given \p assetPath. \p resolvedPath is the
685  /// resolved path computed for the given \p assetPath.
686  /// The default implementation returns a default-constructed ArAssetInfo.
687  AR_API
688  virtual ArAssetInfo _GetAssetInfo(
689  const std::string& assetPath,
690  const ArResolvedPath& resolvedPath) const;
691 
692  /// Return an ArTimestamp representing the last time the asset at
693  /// \p assetPath was modified. \p resolvedPath is the resolved path
694  /// computed for the given \p assetPath. If a timestamp cannot be
695  /// retrieved, return an invalid ArTimestamp.
696  ///
697  /// The default implementation returns an invalid ArTimestamp.
698  ///
699  /// Example uses:
700  /// - SdfLayer will call GetModificationTimestamp when opening a
701  /// layer and store the returned timestamp. When SdfLayer::Reload
702  /// is called on that layer, this method will be called again.
703  /// If the returned timestamp differs from the stored timestamp,
704  /// or if it is invalid, the layer will be reloaded.
705  AR_API
707  const std::string& assetPath,
708  const ArResolvedPath& resolvedPath) const;
709 
710  /// Return an ArAsset object for the asset located at \p resolvedPath.
711  /// Return an invalid std::shared_ptr if object could not be created
712  /// (for example, if the asset at the given path could not be opened).
713  ///
714  /// Note that clients may still be using the data associated with
715  /// this object even after the last shared_ptr has been destroyed. For
716  /// example, a client may have created a memory mapping using the FILE*
717  /// presented in the ArAsset object; this would preclude truncating or
718  /// overwriting any of the contents of that file.
719  AR_API
720  virtual std::shared_ptr<ArAsset> _OpenAsset(
721  const ArResolvedPath& resolvedPath) const = 0;
722 
723  /// Return true if an asset may be written to the given \p resolvedPath,
724  /// false otherwise. If this function returns false and \p whyNot is not
725  /// \c nullptr, it may be filled with an explanation. The default
726  /// implementation returns true.
727  AR_API
728  virtual bool _CanWriteAssetToPath(
729  const ArResolvedPath& resolvedPath,
730  std::string* whyNot) const;
731 
732  /// Return an ArWritableAsset object for the asset at \p resolvedPath
733  /// using the specified \p writeMode. Return an invalid std::shared_ptr
734  /// if object could not be created (for example, if writing to the
735  /// given path is not allowed).
736  ///
737  /// Implementations should create any parent paths that are necessary
738  /// to write this asset. The returned ArWritableAsset must obey the
739  /// behaviors for the given \p writeMode, see the documentation for
740  /// the WriteMode enum for more details.
741  AR_API
742  virtual std::shared_ptr<ArWritableAsset>
744  const ArResolvedPath& resolvedPath,
745  WriteMode writeMode) const = 0;
746 
747  /// @}
748 
749  // --------------------------------------------------------------------- //
750  /// \anchor ArResolver_scopedCacheImplementation
751  /// \name Scoped Resolution Cache Implementation
752  ///
753  /// If any of these functions are implemented in a subclass, the plugin
754  /// metadata for that subclass in the plugin library's plugInfo.json
755  /// must specify:
756  /// \code
757  /// "implementsScopedCaches" : true.
758  /// \endcode
759  ///
760  /// If a subclass indicates that it implements these functions, ArResolver
761  /// will assume the subclass is handling all caching of resolved paths
762  /// and will call these functions when a caching scope is opened and closed.
763  /// Otherwise, these functions will not be called. Instead, ArResolver
764  /// itself will handle caching and returning resolved paths as needed.
765  ///
766  /// @{
767 
768  /// Mark the start of a resolution caching scope.
769  ///
770  /// Resolvers may fill \p cacheScopeData with arbitrary data. Clients may
771  /// also pass in a \p cacheScopeData populated by an earlier call to
772  /// BeginCacheScope to allow the resolver access to that information.
773  ///
774  /// See \ref ArResolver_scopedCacheImplementation "Scoped Resolution Cache Implementation"
775  /// for more implementation details.
776  AR_API
777  virtual void _BeginCacheScope(
778  VtValue* cacheScopeData);
779 
780  /// Mark the end of a resolution caching scope.
781  ///
782  /// \p cacheScopeData should contain the data that was populated by the
783  /// previous corresponding call to BeginCacheScope.
784  ///
785  /// See \ref ArResolver_scopedCacheImplementation "Scoped Resolution Cache Implementation"
786  /// for more implementation details.
787  AR_API
788  virtual void _EndCacheScope(
789  VtValue* cacheScopeData);
790 
791  /// @}
792 
793  /// \deprecated
794  /// Return true if the given path is a repository path, false otherwise.
795  /// Default implementation returns false.
796  AR_API
797  virtual bool _IsRepositoryPath(
798  const std::string& path) const;
799 
800  // --------------------------------------------------------------------- //
801  /// \anchor ArResolver_implementationUtils
802  /// \name Implementation Utilities
803  ///
804  /// Utility functions for implementations.
805  ///
806  /// @{
807 
808  /// Returns a pointer to the context object of type \p ContextObj from
809  /// the last ArResolverContext that was bound via a call to BindContext,
810  /// or \c NULL if no context object of that type exists.
811  ///
812  /// Typically, a subclass might use this in their _Resolve function to
813  /// get the currently bound context to drive their resolution behavior.
814  ///
815  /// \code
816  /// if (const MyContextObject* ctx =
817  /// _GetCurrentContextObject<MyContextObject>()) {
818  ///
819  /// // Use information in ctx to resolve given path
820  /// }
821  /// else {
822  /// // Resolve given path with no context object
823  /// }
824  /// \endcode
825  ///
826  /// This is the same as GetCurrentContext().Get<ContextObj>() but more
827  /// efficient, since it does not make a copy of the ArResolverContext.
828  /// However, it is *not* the same as _GetCurrentContext().Get<ContextObj>().
829  /// Subclasses that manage context binding themselves may have overridden
830  /// _GetCurrentContext to return a context that was bound without calling
831  /// BindContext. These subclasses should not use this function and should
832  /// retrieve the current context from their own internal data structures.
833  template <class ContextObj>
834  const ContextObj* _GetCurrentContextObject() const
835  {
836  const ArResolverContext* ctx = _GetInternallyManagedCurrentContext();
837  return ctx ? ctx->Get<ContextObj>() : nullptr;
838  }
839 
840  /// @}
841 
842 private:
843  // Returns pointer to ArResolverContext that was most recently bound
844  // via BindContext. This is *not* the same as GetCurrentContext,
845  // since subclasses may return an ArResolverContext that hasn't
846  // been bound via BindContext in their implementations.
847  AR_API
848  const ArResolverContext* _GetInternallyManagedCurrentContext() const;
849 
850 };
851 
852 /// Returns the configured asset resolver.
853 ///
854 /// When first called, this function will determine the ArResolver subclass
855 /// to use for asset resolution via the following process:
856 ///
857 /// - If a preferred resolver has been set via \ref ArSetPreferredResolver,
858 /// it will be selected.
859 ///
860 /// - Otherwise, a list of available ArResolver subclasses in plugins will
861 /// be generated. If multiple ArResolver subclasses are found, the list
862 /// will be sorted by typename. ArDefaultResolver will be added as the last
863 /// element of this list, and the first resolver in the list will be
864 /// selected.
865 ///
866 /// - The plugin for the selected subclass will be loaded and an instance
867 /// of the subclass will be constructed.
868 ///
869 /// - If an error occurs, an ArDefaultResolver will be constructed.
870 ///
871 /// The constructed ArResolver subclass will be cached and used to service
872 /// function calls made on the returned resolver.
873 ///
874 /// Note that this function may not return the constructed subclass itself,
875 /// meaning that dynamic casts to the subclass type may fail. See
876 /// ArGetUnderlyingResolver if access to this object is needed.
877 AR_API
879 
880 /// Set the preferred ArResolver subclass used by ArGetResolver.
881 ///
882 /// Consumers may override ArGetResolver's plugin resolver discovery and
883 /// force the use of a specific resolver subclass by calling this
884 /// function with the typename of the implementation to use.
885 ///
886 /// If the subclass specified by \p resolverTypeName cannot be found,
887 /// ArGetResolver will issue a warning and fall back to using
888 /// ArDefaultResolver.
889 ///
890 /// This must be called before the first call to ArGetResolver.
891 AR_API
892 void ArSetPreferredResolver(const std::string& resolverTypeName);
893 
894 /// \name Advanced API
895 ///
896 /// \warning These functions should typically not be used by consumers except
897 /// in very specific cases. Consumers who want to retrieve an ArResolver to
898 /// perform asset resolution should use \ref ArGetResolver.
899 ///
900 /// @{
901 
902 /// Returns the underlying ArResolver instance used by ArGetResolver.
903 ///
904 /// This function returns the instance of the ArResolver subclass used by
905 /// ArGetResolver and can be dynamic_cast to that type.
906 ///
907 /// \warning This functions should typically not be used by consumers except
908 /// in very specific cases. Consumers who want to retrieve an ArResolver to
909 /// perform asset resolution should use \ref ArGetResolver.
910 AR_API
912 
913 /// Returns list of TfTypes for available ArResolver subclasses.
914 ///
915 /// This function returns the list of ArResolver subclasses used to determine
916 /// the resolver implementation returned by \ref ArGetResolver. See
917 /// documentation on that function for more details.
918 ///
919 /// If this function is called from within a call (or calls) to
920 /// \ref ArCreateResolver, the ArResolver subclass(es) being created will
921 /// be removed from the returned list.
922 ///
923 /// This function is not safe to call concurrently with itself or
924 /// \ref ArCreateResolver.
925 ///
926 /// \warning This functions should typically not be used by consumers except
927 /// in very specific cases. Consumers who want to retrieve an ArResolver to
928 /// perform asset resolution should use \ref ArGetResolver.
929 AR_API
930 std::vector<TfType> ArGetAvailableResolvers();
931 
932 /// Construct an instance of the ArResolver subclass specified by
933 /// \p resolverType.
934 ///
935 /// This function will load the plugin for the given \p resolverType and
936 /// construct and return a new instance of the specified ArResolver subclass.
937 /// If an error occurs, coding errors will be emitted and this function
938 /// will return an ArDefaultResolver instance.
939 ///
940 /// Note that this function *does not* change the resolver used by
941 /// \ref ArGetResolver to an instance of \p resolverType.
942 ///
943 /// This function is not safe to call concurrently with itself or
944 /// \ref ArGetAvailableResolvers.
945 ///
946 /// \warning This functions should typically not be used by consumers except
947 /// in very specific cases. Consumers who want to retrieve an ArResolver to
948 /// perform asset resolution should use \ref ArGetResolver.
949 AR_API
950 std::unique_ptr<ArResolver> ArCreateResolver(const TfType& resolverType);
951 
952 /// @}
953 
955 
956 #endif
virtual std::string _CreateIdentifierForNewAsset(const std::string &assetPath, const ArResolvedPath &anchorAssetPath) const =0
AR_API ArResolver & ArGetUnderlyingResolver()
virtual AR_API ArResolverContext _CreateDefaultContext() const
AR_API ArTimestamp GetModificationTimestamp(const std::string &assetPath, const ArResolvedPath &resolvedPath) const
virtual AR_API ArAssetInfo _GetAssetInfo(const std::string &assetPath, const ArResolvedPath &resolvedPath) const
virtual AR_API void _BindContext(const ArResolverContext &context, VtValue *bindingData)
AR_API void RefreshContext(const ArResolverContext &context)
const ContextObj * Get() const
AR_API ArResolverContext GetCurrentContext() const
AR_API ArResolverContext CreateContextFromString(const std::string &contextStr) const
virtual AR_API std::string _GetExtension(const std::string &assetPath) const
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
abs path to model * ArResolvedPath("/abs/path/to/shot.usd"))*
AR_API void BindContext(const ArResolverContext &context, VtValue *bindingData)
virtual AR_API ArTimestamp _GetModificationTimestamp(const std::string &assetPath, const ArResolvedPath &resolvedPath) const
#define AR_API
Definition: api.h:40
virtual AR_API void _UnbindContext(const ArResolverContext &context, VtValue *bindingData)
AR_API ArResolverContext CreateDefaultContext() const
AR_API ArResolver()
AR_API std::string CreateIdentifierForNewAsset(const std::string &assetPath, const ArResolvedPath &anchorAssetPath=ArResolvedPath()) const
virtual AR_API ArResolverContext _CreateDefaultContextForAsset(const std::string &assetPath) const
virtual AR_API ~ArResolver()
AR_API bool IsRepositoryPath(const std::string &path) const
virtual AR_API ArResolverContext _CreateContextFromString(const std::string &contextStr) const
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
virtual ArResolvedPath _ResolveForNewAsset(const std::string &assetPath) const =0
const ContextObj * _GetCurrentContextObject() const
Definition: resolver_v2.h:834
AR_API void ArSetPreferredResolver(const std::string &resolverTypeName)
AR_API void BeginCacheScope(VtValue *cacheScopeData)
ArResolver & operator=(const ArResolver &)=delete
AR_API ArAssetInfo GetAssetInfo(const std::string &assetPath, const ArResolvedPath &resolvedPath) const
virtual AR_API std::shared_ptr< ArAsset > _OpenAsset(const ArResolvedPath &resolvedPath) const =0
AR_API bool IsContextDependentPath(const std::string &assetPath) const
virtual AR_API void _BeginCacheScope(VtValue *cacheScopeData)
AR_API ArResolverContext CreateDefaultContextForAsset(const std::string &assetPath) const
AR_API ArResolvedPath Resolve(const std::string &assetPath) const
AR_API ArResolverContext CreateContextFromStrings(const std::vector< std::pair< std::string, std::string >> &contextStrs) const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1394
WriteMode
Enumeration of write modes for OpenAssetForWrite.
Definition: resolver_v2.h:302
virtual AR_API void _EndCacheScope(VtValue *cacheScopeData)
virtual AR_API bool _CanWriteAssetToPath(const ArResolvedPath &resolvedPath, std::string *whyNot) const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
AR_API void UnbindContext(const ArResolverContext &context, VtValue *bindingData)
AR_API std::unique_ptr< ArResolver > ArCreateResolver(const TfType &resolverType)
Definition: type.h:64
AR_API bool CanWriteAssetToPath(const ArResolvedPath &resolvedPath, std::string *whyNot=nullptr) const
AR_API std::shared_ptr< ArWritableAsset > OpenAssetForWrite(const ArResolvedPath &resolvedPath, WriteMode writeMode) const
AR_API std::shared_ptr< ArAsset > OpenAsset(const ArResolvedPath &resolvedPath) const
virtual AR_API std::shared_ptr< ArWritableAsset > _OpenAssetForWrite(const ArResolvedPath &resolvedPath, WriteMode writeMode) const =0
AR_API std::string GetExtension(const std::string &assetPath) const
AR_API ArResolver & ArGetResolver()
AR_API ArResolvedPath ResolveForNewAsset(const std::string &assetPath) const
virtual AR_API bool _IsContextDependentPath(const std::string &assetPath) const
virtual AR_API bool _IsRepositoryPath(const std::string &path) const
Definition: value.h:166
virtual AR_API void _RefreshContext(const ArResolverContext &context)
virtual ArResolvedPath _Resolve(const std::string &assetPath) const =0
AR_API std::string CreateIdentifier(const std::string &assetPath, const ArResolvedPath &anchorAssetPath=ArResolvedPath()) const
AR_API std::vector< TfType > ArGetAvailableResolvers()
AR_API void EndCacheScope(VtValue *cacheScopeData)
virtual AR_API ArResolverContext _GetCurrentContext() const