HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
resolverContext_v1.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_CONTEXT
25 #error This file should not be included directly. Include resolverContext.h instead
26 #endif
27 
28 #ifndef PXR_USD_AR_RESOLVER_CONTEXT_V1_H
29 #define PXR_USD_AR_RESOLVER_CONTEXT_V1_H
30 
31 /// \file ar/resolverContext_v1.h
32 
33 #include "pxr/pxr.h"
34 #include "pxr/usd/ar/api.h"
36 
37 #include <memory>
38 #include <string>
39 #include <type_traits>
40 #include <typeinfo>
41 
43 
44 /// \class ArIsContextObject
45 ///
46 /// Metafunction to determine whether the templated object type is a
47 /// valid context object.
48 ///
49 template <class T>
51 {
52  static const bool value = false;
53 };
54 
55 /// Default implementation for providing debug info on the contained context.
56 template <class Context>
57 std::string ArGetDebugString(const Context& context);
58 
59 /// \class ArResolverContext
60 ///
61 /// An asset resolver context allows clients to provide additional data
62 /// to the resolver for use during resolution. Clients may provide this
63 /// data via a context object of their own (subject to restrictions below).
64 /// An ArResolverContext is simply a wrapper around this object that
65 /// allows it to be treated as a single type.
66 ///
67 /// A client-defined context object must provide the following:
68 /// - Default and copy constructors
69 /// - operator<
70 /// - operator==
71 /// - An overload for size_t hash_value(const T&)
72 ///
73 /// Note that the user may define a free function:
74 ///
75 /// std::string ArGetDebugString(const Context& ctx);
76 /// (Where Context is the type of the user's path resolver context.)
77 ///
78 /// This is optional; a default generic implementation has been predefined.
79 /// This function should return a string representation of the context
80 /// to be utilized for debugging purposes(such as in TF_DEBUG statements).
81 ///
82 /// The ArIsContextObject template must also be specialized for this
83 /// object to declare that it can be used as a context object. This is to
84 /// avoid accidental use of an unexpected object as a context object.
85 /// The AR_DECLARE_RESOLVER_CONTEXT macro can be used to do this
86 /// as a convenience.
87 ///
88 /// \sa AR_DECLARE_RESOLVER_CONTEXT
89 /// \sa ArResolver::BindContext
90 /// \sa ArResolver::UnbindContext
91 /// \sa ArResolverContextBinder
93 {
94 public:
95  /// Construct an empty asset resolver context.
97  {
98  }
99 
100  /// Construct a resolver context using the context object \p context.
101  /// See class documentation for requirements.
102  template <class Context,
104  ::type* = nullptr>
105  ArResolverContext(const Context& context)
106  : _context(new _Typed<Context>(context))
107  {
108  }
109 
110  /// Returns whether this context object is empty.
111  bool IsEmpty() const
112  {
113  return !_context;
114  }
115 
116  /// Return pointer to the context object held in this asset resolver
117  /// context if the context is holding an object of the requested type,
118  /// NULL otherwise.
119  template <class Context>
120  const Context* Get() const
121  {
122  return _context && _context->IsHolding(typeid(Context)) ?
123  &_GetTyped<Context>(*_context)._context : NULL;
124  }
125 
126  /// Returns a debug string representing the contained context
128  {
129  return _context ? _context->GetDebugString() : std::string();
130  }
131 
132  /// \name Operators
133  /// @{
134  bool operator==(const ArResolverContext& rhs) const
135  {
136  if (_context && rhs._context) {
137  return (_context->IsHolding(rhs._context->GetTypeid())
138  && _context->Equals(*rhs._context));
139  }
140  return (!_context && !rhs._context);
141  }
142 
143  bool operator!=(const ArResolverContext& rhs) const
144  {
145  return !(*this == rhs);
146  }
147 
148  bool operator<(const ArResolverContext& rhs) const
149  {
150  if (_context && rhs._context) {
151  if (_context->IsHolding(rhs._context->GetTypeid())) {
152  return _context->LessThan(*rhs._context);
153  }
154  return (std::string(_context->GetTypeid().name()) <
155  std::string(rhs._context->GetTypeid().name()));
156  }
157  else if (_context && !rhs._context) {
158  return false;
159  }
160  else if (!_context && rhs._context) {
161  return true;
162  }
163  return false;
164  }
165 
166  /// @}
167 
168  /// Returns hash value for this asset resolver context.
169  friend size_t hash_value(const ArResolverContext& context)
170  {
171  return context._context ? context._context->Hash() : 0;
172  }
173 
174 private:
175  // Type-erased storage for context objects.
176  struct _Untyped;
177  template <class Context> struct _Typed;
178 
179  template <class Context>
180  static const _Typed<Context>& _GetTyped(const _Untyped& untyped)
181  {
182  return static_cast<const _Typed<Context>&>(untyped);
183  }
184 
185  struct _Untyped
186  {
187  AR_API
188  virtual ~_Untyped();
189 
190  bool IsHolding(const std::type_info& ti) const
191  {
192  return TfSafeTypeCompare(ti, GetTypeid());
193  }
194 
195  virtual const std::type_info& GetTypeid() const = 0;
196  virtual bool LessThan(const _Untyped& rhs) const = 0;
197  virtual bool Equals(const _Untyped& rhs) const = 0;
198  virtual size_t Hash() const = 0;
199  virtual std::string GetDebugString() const = 0;
200  };
201 
202  template <class Context>
203  struct _Typed : public _Untyped
204  {
205  virtual ~_Typed() { }
206 
207  _Typed(const Context& context) : _context(context)
208  {
209  }
210 
211  virtual const std::type_info& GetTypeid() const
212  {
213  return typeid(Context);
214  }
215 
216  virtual bool LessThan(const _Untyped& rhs) const
217  {
218  return _context < _GetTyped<Context>(rhs)._context;
219  }
220 
221  virtual bool Equals(const _Untyped& rhs) const
222  {
223  return _context == _GetTyped<Context>(rhs)._context;
224  }
225 
226  virtual size_t Hash() const
227  {
228  return hash_value(_context);
229  }
230 
231  virtual std::string GetDebugString() const
232  {
233  return ArGetDebugString(_context);
234  }
235 
236  Context _context;
237  };
238 
239  std::shared_ptr<_Untyped> _context;
240 };
241 
242 
243 // Default implementation for streaming out held contexts.
244 AR_API
245 std::string Ar_GetDebugString(const std::type_info&, void const*);
246 
247 template <class Context>
249 {
250  return Ar_GetDebugString(typeid(Context),
251  static_cast<void const*>(&context));
252 }
253 
255 
256 #endif
friend size_t hash_value(const ArResolverContext &context)
Returns hash value for this asset resolver context.
bool operator==(const ArResolverContext &rhs) const
bool operator!=(const ArResolverContext &rhs) const
STATIC_INLINE size_t Hash(const char *s, size_t len)
Definition: farmhash.h:2038
#define AR_API
Definition: api.h:40
ArResolverContext(const Context &context)
class OCIOEXPORT Context
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
const Context * Get() const
std::string ArGetDebugString(const Context &context)
Default implementation for providing debug info on the contained context.
AR_API std::string Ar_GetDebugString(const std::type_info &, void const *)
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
bool IsEmpty() const
Returns whether this context object is empty.
ArResolverContext()
Construct an empty asset resolver context.
std::string GetDebugString() const
Returns a debug string representing the contained context.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1375
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
GLsizei const GLfloat * value
Definition: glcorearb.h:823
PXR_NAMESPACE_OPEN_SCOPE bool TfSafeTypeCompare(const std::type_info &t1, const std::type_info &t2)
bool operator<(const ArResolverContext &rhs) const