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