Loading...
Searching...
No Matches
resolverContext.h
Go to the documentation of this file.
1//
2// Copyright 2020 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_USD_AR_RESOLVER_CONTEXT_H
8#define PXR_USD_AR_RESOLVER_CONTEXT_H
9
11
12#include "pxr/pxr.h"
13#include "pxr/usd/ar/api.h"
14#include "pxr/usd/ar/ar.h"
15
16#include "pxr/base/tf/hash.h"
18
19#ifdef PXR_PYTHON_SUPPORT_ENABLED
20// XXX: This include is a hack to avoid build errors due to
21// incompatible macro definitions in pyport.h on macOS.
22#include <locale>
23#include "pxr/base/tf/pyLock.h"
24#endif
25
26#include "pxr/base/tf/pyObjWrapper.h"
27
28#include <algorithm>
29#include <memory>
30#include <string>
31#include <type_traits>
32#include <typeinfo>
33#include <vector>
34
35PXR_NAMESPACE_OPEN_SCOPE
36
42template <class T>
44{
45 static const bool value = false;
46};
47
49template <class Context>
50std::string ArGetDebugString(const Context& context);
51
52// Metafunctions for determining if a variadic list of objects
53// are valid for use with the ArResolverContext c'tor.
55
56template <class ...Objects> struct Ar_AllValidForContext;
57
58template <class Object, class ...Other>
59struct Ar_AllValidForContext<Object, Other...>
60{
61 static const bool value =
62 (std::is_same<Object, ArResolverContext>::value ||
64 Ar_AllValidForContext<Other...>::value;
65};
66
67template <>
68struct Ar_AllValidForContext<>
69{
70 static const bool value = true;
71};
72
108{
109public:
112 {
113 }
114
130 template <
131 class ...Objects,
132 typename std::enable_if<Ar_AllValidForContext<Objects...>::value>::type*
133 = nullptr>
134 ArResolverContext(const Objects&... objs)
135 {
136 _AddObjects(objs...);
137 }
138
148 AR_API
149 explicit ArResolverContext(const std::vector<ArResolverContext>& ctxs);
150
152 bool IsEmpty() const
153 {
154 return _contexts.empty();
155 }
156
160 template <class ContextObj>
161 const ContextObj* Get() const
162 {
163 for (const auto& context : _contexts) {
164 if (context->IsHolding(typeid(ContextObj))) {
165 return &_GetTyped<ContextObj>(*context)._context;
166 }
167 }
168 return nullptr;
169 }
170
172 AR_API
173 std::string GetDebugString() const;
174
177 AR_API
178 bool operator==(const ArResolverContext& rhs) const;
179
180 bool operator!=(const ArResolverContext& rhs) const
181 {
182 return !(*this == rhs);
183 }
184
185 AR_API
186 bool operator<(const ArResolverContext& rhs) const;
187
189
191 friend size_t hash_value(const ArResolverContext& context)
192 {
193 return TfHash()(context._contexts);
194 }
195
196private:
197 // Type-erased storage for context objects.
198 struct _Untyped;
199 template <class Context> struct _Typed;
200
201 void _AddObjects()
202 {
203 // Empty base case for unpacking parameter pack
204 }
205
206 template <class Object, class ...Other>
207 void _AddObjects(const Object& obj, const Other&... other)
208 {
209 _Add(obj);
210 _AddObjects(other...);
211 }
212
213 AR_API
214 void _Add(const ArResolverContext& ctx);
215
216 template <class Object>
217 void _Add(const Object& obj)
218 {
219 _Add(std::shared_ptr<_Untyped>(new _Typed<Object>(obj)));
220 }
221
222 AR_API
223 void _Add(std::shared_ptr<_Untyped>&& context);
224
225 template <class Context>
226 static const _Typed<Context>& _GetTyped(const _Untyped& untyped)
227 {
228 return static_cast<const _Typed<Context>&>(untyped);
229 }
230
231 struct _Untyped
232 {
233 AR_API
234 virtual ~_Untyped();
235
236 bool IsHolding(const std::type_info& ti) const
237 {
238 return TfSafeTypeCompare(ti, GetTypeid());
239 }
240
241 virtual _Untyped* Clone() const = 0;
242 virtual const std::type_info& GetTypeid() const = 0;
243 virtual bool LessThan(const _Untyped& rhs) const = 0;
244 virtual bool Equals(const _Untyped& rhs) const = 0;
245 virtual size_t Hash() const = 0;
246 virtual std::string GetDebugString() const = 0;
247 virtual TfPyObjWrapper GetPythonObj() const = 0;
248 };
249
250 template <class Context>
251 struct _Typed : public _Untyped
252 {
253 virtual ~_Typed() { }
254
255 _Typed(const Context& context) : _context(context)
256 {
257 }
258
259 virtual _Untyped* Clone() const
260 {
261 return new _Typed<Context>(_context);
262 }
263
264 virtual const std::type_info& GetTypeid() const
265 {
266 return typeid(Context);
267 }
268
269 virtual bool LessThan(const _Untyped& rhs) const
270 {
271 return _context < _GetTyped<Context>(rhs)._context;
272 }
273
274 virtual bool Equals(const _Untyped& rhs) const
275 {
276 return _context == _GetTyped<Context>(rhs)._context;
277 }
278
279 virtual size_t Hash() const
280 {
281 return hash_value(_context);
282 }
283
284 virtual std::string GetDebugString() const
285 {
286 return ArGetDebugString(_context);
287 }
288
289 virtual TfPyObjWrapper GetPythonObj() const
290 {
291 #ifdef PXR_PYTHON_SUPPORT_ENABLED
292 TfPyLock lock;
293 return pxr_boost::python::object(_context);
294#else
295 return {};
296#endif
297 }
298
299 Context _context;
300 };
301
302 template <class HashState>
303 friend void TfHashAppend(
304 HashState& h, const std::shared_ptr<_Untyped>& context)
305 {
306 h.Append(context->Hash());
307 }
308
309#ifdef PXR_PYTHON_SUPPORT_ENABLED
310 friend class Ar_ResolverContextPythonAccess;
311#endif
312
313 std::vector<std::shared_ptr<_Untyped>> _contexts;
314};
315
316
317// Default implementation for streaming out held contexts.
318AR_API
319std::string Ar_GetDebugString(const std::type_info&, void const*);
320
321template <class Context>
322std::string ArGetDebugString(const Context& context)
323{
324 return Ar_GetDebugString(typeid(Context),
325 static_cast<void const*>(&context));
326}
327
328PXR_NAMESPACE_CLOSE_SCOPE
329
330#endif
An asset resolver context allows clients to provide additional data to the resolver for use during re...
ArResolverContext(const Objects &... objs)
Construct a resolver context using the given objects objs.
const ContextObj * Get() const
Returns pointer to the context object of the given type held in this resolver context.
AR_API std::string GetDebugString() const
Returns a debug string representing the contained context objects.
AR_API ArResolverContext(const std::vector< ArResolverContext > &ctxs)
Construct a resolver context using the ArResolverContexts in ctxs.
bool IsEmpty() const
Returns whether this resolver context is empty.
ArResolverContext()
Construct an empty asset resolver context.
friend size_t hash_value(const ArResolverContext &context)
Returns hash value for this asset resolver context.
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:472
Convenience class for accessing the Python Global Interpreter Lock.
Definition: pyLock.h:105
Boost Python object wrapper.
Definition: pyObjWrapper.h:79
std::string ArGetDebugString(const Context &context)
Default implementation for providing debug info on the contained context.
Safely compare C++ RTTI type structures.
bool TfSafeTypeCompare(const std::type_info &t1, const std::type_info &t2)
Safely compare std::type_info structures.
Metafunction to determine whether the templated object type is a valid context object.