All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
abstractData.h
1//
2// Copyright 2016 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_SDF_ABSTRACT_DATA_H
8#define PXR_USD_SDF_ABSTRACT_DATA_H
9
10#include "pxr/pxr.h"
11#include "pxr/usd/sdf/path.h"
12#include "pxr/usd/sdf/types.h"
13
14#include "pxr/base/vt/value.h"
15
17#include "pxr/base/tf/token.h"
18#include "pxr/base/tf/refBase.h"
21
22#include <vector>
23#include <type_traits>
24
25PXR_NAMESPACE_OPEN_SCOPE
26
31
32
33#define SDF_DATA_TOKENS \
34 ((TimeSamples, "timeSamples"))
35
36TF_DECLARE_PUBLIC_TOKENS(SdfDataTokens, SDF_API, SDF_DATA_TOKENS);
37
38
56class SdfAbstractData : public TfRefBase, public TfWeakBase
57{
58public:
60 SDF_API
61 virtual ~SdfAbstractData();
62
67 SDF_API
68 virtual void CopyFrom(const SdfAbstractDataConstPtr& source);
69
77 SDF_API
78 virtual bool StreamsData() const = 0;
79
98 SDF_API
99 virtual bool IsDetached() const;
100
105 SDF_API
106 virtual bool IsEmpty() const;
107
113 // XXX: What are the right semantics for this?
114 // Does it matter if the underlying implementation matches?
115 SDF_API
116 virtual bool Equals(const SdfAbstractDataRefPtr &rhs) const;
117
122 SDF_API
123 virtual void WriteToStream(std::ostream& out) const;
124
127
130 SDF_API
131 virtual void CreateSpec(const SdfPath &path,
132 SdfSpecType specType) = 0;
133
135 SDF_API
136 virtual bool HasSpec(const SdfPath &path) const = 0;
137
140 SDF_API
141 virtual void EraseSpec(const SdfPath &path) = 0;
142
145 SDF_API
146 virtual void MoveSpec(const SdfPath &oldPath,
147 const SdfPath &newPath) = 0;
148
151 virtual SdfSpecType GetSpecType(const SdfPath &path) const = 0;
152
157 SDF_API
159
161
164
167 SDF_API
168 virtual bool Has(const SdfPath& path, const TfToken& fieldName,
169 SdfAbstractDataValue* value) const = 0;
170
173 SDF_API
174 virtual bool Has(const SdfPath& path, const TfToken &fieldName,
175 VtValue *value = NULL) const = 0;
176
187 SDF_API
188 virtual bool
189 HasSpecAndField(const SdfPath &path, const TfToken &fieldName,
190 SdfAbstractDataValue *value, SdfSpecType *specType) const;
191
202 SDF_API
203 virtual bool
204 HasSpecAndField(const SdfPath &path, const TfToken &fieldName,
205 VtValue *value, SdfSpecType *specType) const;
206
209 SDF_API
210 virtual VtValue Get(const SdfPath& path,
211 const TfToken& fieldName) const = 0;
212
221 SDF_API
222 virtual std::type_info const &
223 GetTypeid(const SdfPath &path, const TfToken &fieldName) const;
224
229 SDF_API
230 virtual void Set(const SdfPath &path, const TfToken &fieldName,
231 const VtValue &value) = 0;
232
236 SDF_API
237 virtual void Set(const SdfPath &path, const TfToken &fieldName,
238 const SdfAbstractDataConstValue& value) = 0;
239
241 SDF_API
242 virtual void Erase(const SdfPath& path,
243 const TfToken& fieldName) = 0;
244
246 SDF_API
247 virtual std::vector<TfToken> List(const SdfPath& path) const = 0;
248
251 template <class T>
252 inline T GetAs(const SdfPath& path, const TfToken& fieldName,
253 const T& defaultValue = T()) const;
254
256
257
260
261 // Return true and set \p value (if non null) if the field identified by
262 // \p path and \p fieldName is dictionary-valued, and if there is an element
263 // at \p keyPath in that dictionary. Return false otherwise. If
264 // \p keyPath names an entire sub-dictionary, set \p value to that entire
265 // sub-dictionary and return true.
266 SDF_API
267 virtual bool HasDictKey(const SdfPath& path,
268 const TfToken &fieldName,
269 const TfToken &keyPath,
270 SdfAbstractDataValue* value) const;
271 SDF_API
272 virtual bool HasDictKey(const SdfPath& path,
273 const TfToken &fieldName,
274 const TfToken &keyPath,
275 VtValue *value = NULL) const;
276
277 // Same as HasDictKey but return empty VtValue on failure.
278 SDF_API
279 virtual VtValue GetDictValueByKey(const SdfPath& path,
280 const TfToken &fieldName,
281 const TfToken &keyPath) const;
282
283 // Set the element at \p keyPath in the dictionary-valued field identified
284 // by \p path and \p fieldName. If the field itself is not
285 // dictionary-valued, replace the field with a new dictionary and set the
286 // element at \p keyPath in it. If \p value is empty, invoke
287 // EraseDictValueByKey instead.
288 SDF_API
289 virtual void SetDictValueByKey(const SdfPath& path,
290 const TfToken &fieldName,
291 const TfToken &keyPath,
292 const VtValue &value);
293 SDF_API
294 virtual void SetDictValueByKey(const SdfPath& path,
295 const TfToken &fieldName,
296 const TfToken &keyPath,
297 const SdfAbstractDataConstValue& value);
298
299 // If \p path and \p fieldName identify a dictionary-valued field with an
300 // element at \p keyPath, remove that element from the dictionary. If this
301 // leaves the dictionary empty, Erase() the entire field.
302 SDF_API
303 virtual void EraseDictValueByKey(const SdfPath& path,
304 const TfToken &fieldName,
305 const TfToken &keyPath);
306
307 // If \p path, \p fieldName, and \p keyPath identify a (sub) dictionary,
308 // return a vector of the keys in that dictionary, otherwise return an empty
309 // vector.
310 SDF_API
311 virtual std::vector<TfToken> ListDictKeys(const SdfPath& path,
312 const TfToken &fieldName,
313 const TfToken &keyPath) const;
314
315
317
318
328
329 SDF_API
330 virtual std::set<double>
331 ListAllTimeSamples() const = 0;
332
333 SDF_API
334 virtual std::set<double>
335 ListTimeSamplesForPath(const SdfPath& path) const = 0;
336
337 SDF_API
338 virtual bool
339 GetBracketingTimeSamples(double time, double* tLower, double* tUpper) const = 0;
340
341 SDF_API
342 virtual size_t
343 GetNumTimeSamplesForPath(const SdfPath& path) const = 0;
344
345 SDF_API
346 virtual bool
347 GetBracketingTimeSamplesForPath(const SdfPath& path,
348 double time,
349 double* tLower, double* tUpper) const = 0;
350
351 SDF_API
352 virtual bool
353 QueryTimeSample(const SdfPath& path, double time,
354 VtValue *optionalValue = NULL) const = 0;
355 SDF_API
356 virtual bool
357 QueryTimeSample(const SdfPath& path, double time,
358 SdfAbstractDataValue *optionalValue) const = 0;
359
360 SDF_API
361 virtual void
362 SetTimeSample(const SdfPath& path, double time,
363 const VtValue & value) = 0;
364
365 SDF_API
366 virtual void
367 EraseTimeSample(const SdfPath& path, double time) = 0;
368
370
371protected:
377 SDF_API
378 virtual void _VisitSpecs(SdfAbstractDataSpecVisitor* visitor) const = 0;
379};
380
381template <class T>
383 const SdfPath& path,
384 const TfToken& field, const T& defaultVal) const
385{
386 VtValue val = Get(path, field);
387 if (val.IsHolding<T>()) {
388 return val.UncheckedGet<T>();
389 }
390 return defaultVal;
391}
392
399{
400public:
401 template <class T>
402 bool StoreValue(T &&v)
403 {
404 // this can be std::remove_cvref_t in c++20.
405 using Type = std::remove_cv_t<std::remove_reference_t<T>>;
406
407 if constexpr (std::is_same_v<Type, VtValue>) {
408 return _StoreVtValue(std::forward<T>(v));
409 }
410
411 isValueBlock = false;
412 typeMismatch = false;
413 if constexpr (std::is_same_v<Type, SdfValueBlock>) {
414 isValueBlock = true;
415 return true;
416 }
417 if (TfSafeTypeCompare(typeid(Type), valueType)) {
418 *static_cast<Type*>(value) = std::forward<T>(v);
419 return true;
420 }
421 typeMismatch = true;
422 return false;
423 }
424
425 void* value;
426 const std::type_info& valueType;
427 bool isValueBlock;
428 bool typeMismatch;
429
430protected:
431 SdfAbstractDataValue(void* value_, const std::type_info& valueType_)
432 : value(value_)
433 , valueType(valueType_)
434 , isValueBlock(false)
435 , typeMismatch(false)
436 { }
437
438private:
439 virtual bool _StoreVtValue(const VtValue& value) = 0;
440 virtual bool _StoreVtValue(VtValue &&value) = 0;
441};
442
456template <class T>
458{
459public:
461 : SdfAbstractDataValue(value, typeid(T))
462 { }
463
464private:
465 T const &_Get(const VtValue &v) {
466 return v.UncheckedGet<T>();
467 }
468
469 T _Get(VtValue &&v) {
470 return v.UncheckedRemove<T>();
471 }
472
473 template <class Value>
474 bool _StoreVtValueImpl(Value &&v) {
475 typeMismatch = false;
476 isValueBlock = false;
477 if (ARCH_LIKELY(std::forward<Value>(v).template IsHolding<T>())) {
478 *static_cast<T*>(value) = _Get(std::forward<Value>(v));
479 if (std::is_same_v<T, SdfValueBlock>) {
480 isValueBlock = true;
481 }
482 return true;
483 }
484
485 if (std::forward<Value>(v).template IsHolding<SdfValueBlock>()) {
486 isValueBlock = true;
487 return true;
488 }
489
490 typeMismatch = true;
491
492 return false;
493 }
494
495 virtual bool
496 _StoreVtValue(const VtValue& v) override {
497 return _StoreVtValueImpl(v);
498 }
499
500 virtual bool
501 _StoreVtValue(VtValue &&v) override {
502 return _StoreVtValueImpl(v);
503 }
504};
505
512{
513public:
514 virtual bool GetValue(VtValue* value) const = 0;
515
516 template <class T> bool GetValue(T* v) const
517 {
518 if (TfSafeTypeCompare(typeid(T), valueType)) {
519 *v = *static_cast<const T*>(value);
520 return true;
521 }
522 return false;
523 }
524
525 virtual bool IsEqual(const VtValue& value) const = 0;
526
527 const void* value;
528 const std::type_info& valueType;
529
530protected:
531 SdfAbstractDataConstValue(const void* value_,
532 const std::type_info& valueType_)
533 : value(value_)
534 , valueType(valueType_)
535 {
536 }
537};
538
552template <class T>
554{
555public:
556 SdfAbstractDataConstTypedValue(const T* value)
557 : SdfAbstractDataConstValue(value, typeid(T))
558 { }
559
560 virtual bool GetValue(VtValue* v) const
561 {
562 *v = _GetValue();
563 return true;
564 }
565
566 virtual bool IsEqual(const VtValue& v) const
567 {
568 return (v.IsHolding<T>() && v.UncheckedGet<T>() == _GetValue());
569 }
570
571private:
572 const T& _GetValue() const
573 {
574 return *static_cast<const T*>(value);
575 }
576};
577
578// Specialization of SdAbstractDataConstTypedValue that converts character
579// arrays to std::string.
580template <int N>
581class SdfAbstractDataConstTypedValue<char[N]>
582 : public SdfAbstractDataConstTypedValue<std::string>
583{
584public:
585 typedef char CharArray[N];
586 SdfAbstractDataConstTypedValue(const CharArray* value)
587 : SdfAbstractDataConstTypedValue<std::string>(&_str)
588 , _str(*value)
589 { }
590
591private:
592 std::string _str;
593};
594
601{
602public:
603 SDF_API
605
609 SDF_API
610 virtual bool VisitSpec(const SdfAbstractData& data,
611 const SdfPath& path) = 0;
612
615 SDF_API
616 virtual void Done(const SdfAbstractData& data) = 0;
617};
618
619PXR_NAMESPACE_CLOSE_SCOPE
620
621#endif // PXR_USD_SDF_ABSTRACT_DATA_H
The fully-typed container for a field value in an SdfAbstractData.
Definition: abstractData.h:554
A type-erased container for a const field value in an SdfAbstractData.
Definition: abstractData.h:512
Interface for scene description data storage.
Definition: abstractData.h:57
virtual SDF_API void Set(const SdfPath &path, const TfToken &fieldName, const SdfAbstractDataConstValue &value)=0
Set the value of the given path and fieldName.
virtual SDF_API bool HasSpec(const SdfPath &path) const =0
Return true if this data has a spec for path.
virtual SDF_API bool Has(const SdfPath &path, const TfToken &fieldName, SdfAbstractDataValue *value) const =0
Returns whether a value exists for the given path and fieldName.
virtual SDF_API bool Has(const SdfPath &path, const TfToken &fieldName, VtValue *value=NULL) const =0
Return whether a value exists for the given path and fieldName.
virtual SDF_API bool IsDetached() const
Returns true if this data object is detached from its serialized data store, false otherwise.
virtual SDF_API std::type_info const & GetTypeid(const SdfPath &path, const TfToken &fieldName) const
Return the type of the value for fieldName on spec path.
virtual SDF_API bool IsEmpty() const
Returns true if this data object has no specs, false otherwise.
virtual SDF_API bool Equals(const SdfAbstractDataRefPtr &rhs) const
Returns true if this data object contains the same specs and fields as lhs, false otherwise.
virtual SDF_API void CopyFrom(const SdfAbstractDataConstPtr &source)
Copy the data in source into this data object.
virtual SDF_API VtValue Get(const SdfPath &path, const TfToken &fieldName) const =0
Return the value for the given path and fieldName.
virtual SDF_API void CreateSpec(const SdfPath &path, SdfSpecType specType)=0
Create a new spec at path with the given specType.
virtual SDF_API bool HasSpecAndField(const SdfPath &path, const TfToken &fieldName, VtValue *value, SdfSpecType *specType) const
Fill specType (which cannot be nullptr) as if by a call to GetSpecType(path).
virtual SDF_API void EraseSpec(const SdfPath &path)=0
Erase the spec at path and any fields that are on it.
virtual SDF_API void WriteToStream(std::ostream &out) const
Writes the contents of this data object to out.
virtual SDF_API std::vector< TfToken > List(const SdfPath &path) const =0
Return the names of all the fields that are set at path.
virtual SDF_API void Set(const SdfPath &path, const TfToken &fieldName, const VtValue &value)=0
Set the value of the given path and fieldName.
virtual SDF_API bool StreamsData() const =0
Returns true if this data object streams its data to and from its serialized data store on demand.
virtual SDF_API bool HasSpecAndField(const SdfPath &path, const TfToken &fieldName, SdfAbstractDataValue *value, SdfSpecType *specType) const
Fill specType (which cannot be nullptr) as if by a call to GetSpecType(path).
virtual SDF_API void _VisitSpecs(SdfAbstractDataSpecVisitor *visitor) const =0
Visits every spec in this SdfAbstractData object with the given visitor.
SDF_API void VisitSpecs(SdfAbstractDataSpecVisitor *visitor) const
Visits every spec in this SdfAbstractData object with the given visitor.
virtual SDF_API void MoveSpec(const SdfPath &oldPath, const SdfPath &newPath)=0
Move the spec at oldPath to newPath, including all the fields that are on it.
T GetAs(const SdfPath &path, const TfToken &fieldName, const T &defaultValue=T()) const
Return the value for the given path and fieldName.
Definition: abstractData.h:382
virtual SDF_API void Erase(const SdfPath &path, const TfToken &fieldName)=0
Remove the field at path and fieldName, if one exists.
virtual SdfSpecType GetSpecType(const SdfPath &path) const =0
Return the spec type for the spec at path.
Base class for objects used to visit specs in an SdfAbstractData object.
Definition: abstractData.h:601
virtual SDF_API bool VisitSpec(const SdfAbstractData &data, const SdfPath &path)=0
SdfAbstractData::VisitSpecs calls this function for every entry it contains, passing itself as data a...
virtual SDF_API void Done(const SdfAbstractData &data)=0
SdfAbstractData::VisitSpecs will call this after visitation is complete, even if some VisitSpec() ret...
The fully-typed container for a field value in an SdfAbstractData.
Definition: abstractData.h:458
A type-erased container for a field value in an SdfAbstractData.
Definition: abstractData.h:399
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:274
Enable a concrete base class for use with TfRefPtr.
Definition: refBase.h:56
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:124
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:147
T UncheckedRemove()
Make this value empty and return the held T instance.
Definition: value.h:1024
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
Definition: value.h:1064
T const & UncheckedGet() const &
Returns a const reference to the held object if the held object is of type T.
Definition: value.h:1104
Standard pointer typedefs.
#define TF_DECLARE_WEAK_AND_REF_PTRS(type)
Define standard weak, ref, and vector pointer types.
Definition: declarePtrs.h:72
STL namespace.
bool TfSafeTypeCompare(const std::type_info &t1, const std::type_info &t2)
Safely compare std::type_info structures.
This file defines some macros that are useful for declaring and using static TfTokens.
#define TF_DECLARE_PUBLIC_TOKENS(...)
Macro to define public tokens.
Definition: staticTokens.h:81
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
Basic Sdf data types.
SdfSpecType
An enum that specifies the type of an object.
Definition: types.h:68