Loading...
Searching...
No Matches
resolverContext.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 PXR_USD_AR_RESOLVER_CONTEXT_H
25#define PXR_USD_AR_RESOLVER_CONTEXT_H
26
28
29#include "pxr/pxr.h"
30#include "pxr/usd/ar/api.h"
31#include "pxr/usd/ar/ar.h"
32
33#include "pxr/base/tf/hash.h"
35
36#ifdef PXR_PYTHON_SUPPORT_ENABLED
37// XXX: This include is a hack to avoid build errors due to
38// incompatible macro definitions in pyport.h on macOS.
39#include <locale>
40#include "pxr/base/tf/pyLock.h"
41#endif
42
43#include "pxr/base/tf/pyObjWrapper.h"
44
45#include <algorithm>
46#include <memory>
47#include <string>
48#include <type_traits>
49#include <typeinfo>
50#include <vector>
51
52PXR_NAMESPACE_OPEN_SCOPE
53
59template <class T>
61{
62 static const bool value = false;
63};
64
66template <class Context>
67std::string ArGetDebugString(const Context& context);
68
69// Metafunctions for determining if a variadic list of objects
70// are valid for use with the ArResolverContext c'tor.
72
73template <class ...Objects> struct Ar_AllValidForContext;
74
75template <class Object, class ...Other>
76struct Ar_AllValidForContext<Object, Other...>
77{
78 static const bool value =
79 (std::is_same<Object, ArResolverContext>::value ||
81 Ar_AllValidForContext<Other...>::value;
82};
83
84template <>
85struct Ar_AllValidForContext<>
86{
87 static const bool value = true;
88};
89
125{
126public:
129 {
130 }
131
147 template <
148 class ...Objects,
149 typename std::enable_if<Ar_AllValidForContext<Objects...>::value>::type*
150 = nullptr>
151 ArResolverContext(const Objects&... objs)
152 {
153 _AddObjects(objs...);
154 }
155
165 AR_API
166 explicit ArResolverContext(const std::vector<ArResolverContext>& ctxs);
167
169 bool IsEmpty() const
170 {
171 return _contexts.empty();
172 }
173
177 template <class ContextObj>
178 const ContextObj* Get() const
179 {
180 for (const auto& context : _contexts) {
181 if (context->IsHolding(typeid(ContextObj))) {
182 return &_GetTyped<ContextObj>(*context)._context;
183 }
184 }
185 return nullptr;
186 }
187
189 AR_API
190 std::string GetDebugString() const;
191
194 AR_API
195 bool operator==(const ArResolverContext& rhs) const;
196
197 bool operator!=(const ArResolverContext& rhs) const
198 {
199 return !(*this == rhs);
200 }
201
202 AR_API
203 bool operator<(const ArResolverContext& rhs) const;
204
206
208 friend size_t hash_value(const ArResolverContext& context)
209 {
210 return TfHash()(context._contexts);
211 }
212
213private:
214 // Type-erased storage for context objects.
215 struct _Untyped;
216 template <class Context> struct _Typed;
217
218 void _AddObjects()
219 {
220 // Empty base case for unpacking parameter pack
221 }
222
223 template <class Object, class ...Other>
224 void _AddObjects(const Object& obj, const Other&... other)
225 {
226 _Add(obj);
227 _AddObjects(other...);
228 }
229
230 AR_API
231 void _Add(const ArResolverContext& ctx);
232
233 template <class Object>
234 void _Add(const Object& obj)
235 {
236 _Add(std::shared_ptr<_Untyped>(new _Typed<Object>(obj)));
237 }
238
239 AR_API
240 void _Add(std::shared_ptr<_Untyped>&& context);
241
242 template <class Context>
243 static const _Typed<Context>& _GetTyped(const _Untyped& untyped)
244 {
245 return static_cast<const _Typed<Context>&>(untyped);
246 }
247
248 struct _Untyped
249 {
250 AR_API
251 virtual ~_Untyped();
252
253 bool IsHolding(const std::type_info& ti) const
254 {
255 return TfSafeTypeCompare(ti, GetTypeid());
256 }
257
258 virtual _Untyped* Clone() const = 0;
259 virtual const std::type_info& GetTypeid() const = 0;
260 virtual bool LessThan(const _Untyped& rhs) const = 0;
261 virtual bool Equals(const _Untyped& rhs) const = 0;
262 virtual size_t Hash() const = 0;
263 virtual std::string GetDebugString() const = 0;
264 virtual TfPyObjWrapper GetPythonObj() const = 0;
265 };
266
267 template <class Context>
268 struct _Typed : public _Untyped
269 {
270 virtual ~_Typed() { }
271
272 _Typed(const Context& context) : _context(context)
273 {
274 }
275
276 virtual _Untyped* Clone() const
277 {
278 return new _Typed<Context>(_context);
279 }
280
281 virtual const std::type_info& GetTypeid() const
282 {
283 return typeid(Context);
284 }
285
286 virtual bool LessThan(const _Untyped& rhs) const
287 {
288 return _context < _GetTyped<Context>(rhs)._context;
289 }
290
291 virtual bool Equals(const _Untyped& rhs) const
292 {
293 return _context == _GetTyped<Context>(rhs)._context;
294 }
295
296 virtual size_t Hash() const
297 {
298 return hash_value(_context);
299 }
300
301 virtual std::string GetDebugString() const
302 {
303 return ArGetDebugString(_context);
304 }
305
306 virtual TfPyObjWrapper GetPythonObj() const
307 {
308 #ifdef PXR_PYTHON_SUPPORT_ENABLED
309 TfPyLock lock;
310 return boost::python::object(_context);
311#else
312 return {};
313#endif
314 }
315
316 Context _context;
317 };
318
319 template <class HashState>
320 friend void TfHashAppend(
321 HashState& h, const std::shared_ptr<_Untyped>& context)
322 {
323 h.Append(context->Hash());
324 }
325
326#ifdef PXR_PYTHON_SUPPORT_ENABLED
327 friend class Ar_ResolverContextPythonAccess;
328#endif
329
330 std::vector<std::shared_ptr<_Untyped>> _contexts;
331};
332
333
334// Default implementation for streaming out held contexts.
335AR_API
336std::string Ar_GetDebugString(const std::type_info&, void const*);
337
338template <class Context>
339std::string ArGetDebugString(const Context& context)
340{
341 return Ar_GetDebugString(typeid(Context),
342 static_cast<void const*>(&context));
343}
344
345PXR_NAMESPACE_CLOSE_SCOPE
346
347#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:477
Convenience class for accessing the Python Global Interpreter Lock.
Definition: pyLock.h:122
Boost Python object wrapper.
Definition: pyObjWrapper.h:97
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.