Loading...
Searching...
No Matches
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,
340 double* tUpper) const = 0;
341
342 SDF_API
343 virtual size_t
344 GetNumTimeSamplesForPath(const SdfPath& path) const = 0;
345
346 SDF_API
347 virtual bool
348 GetBracketingTimeSamplesForPath(const SdfPath& path,
349 double time,
350 double* tLower, double* tUpper) const = 0;
351
364 SDF_API
365 virtual bool
366 GetPreviousTimeSampleForPath(const SdfPath& path, double time,
367 double* tPrevious) const;
368
369 SDF_API
370 virtual bool
371 QueryTimeSample(const SdfPath& path, double time,
372 VtValue *optionalValue = NULL) const = 0;
373 SDF_API
374 virtual bool
375 QueryTimeSample(const SdfPath& path, double time,
376 SdfAbstractDataValue *optionalValue) const = 0;
377
378 SDF_API
379 virtual void
380 SetTimeSample(const SdfPath& path, double time,
381 const VtValue & value) = 0;
382
383 SDF_API
384 virtual void
385 EraseTimeSample(const SdfPath& path, double time) = 0;
386
388
389protected:
395 SDF_API
396 virtual void _VisitSpecs(SdfAbstractDataSpecVisitor* visitor) const = 0;
397};
398
399template <class T>
401 const SdfPath& path,
402 const TfToken& field, const T& defaultVal) const
403{
404 VtValue val = Get(path, field);
405 if (val.IsHolding<T>()) {
406 return val.UncheckedGet<T>();
407 }
408 return defaultVal;
409}
410
417{
418public:
419 template <class T>
420 bool StoreValue(T &&v)
421 {
422 // this can be std::remove_cvref_t in c++20.
423 using Type = std::remove_cv_t<std::remove_reference_t<T>>;
424
425 if constexpr (std::is_same_v<Type, VtValue>) {
426 return _StoreVtValue(std::forward<T>(v));
427 }
428
429 isValueBlock = false;
430 isAnimationBlock = false;
431 typeMismatch = false;
432 if constexpr (std::is_same_v<Type, SdfValueBlock>) {
433 isValueBlock = true;
434 return true;
435 } else if constexpr (std::is_same_v<Type, SdfAnimationBlock>) {
436 isAnimationBlock = true;
437 return true;
438 }
439 if (TfSafeTypeCompare(typeid(Type), valueType)) {
440 *static_cast<Type*>(value) = std::forward<T>(v);
441 return true;
442 }
443 typeMismatch = true;
444 return false;
445 }
446
447 void* value;
448 const std::type_info& valueType;
449 bool isValueBlock;
450 bool isAnimationBlock;
451 bool typeMismatch;
452
453protected:
454 SdfAbstractDataValue(void* value_, const std::type_info& valueType_)
455 : value(value_)
456 , valueType(valueType_)
457 , isValueBlock(false)
458 , isAnimationBlock(false)
459 , typeMismatch(false)
460 { }
461
462private:
463 virtual bool _StoreVtValue(const VtValue& value) = 0;
464 virtual bool _StoreVtValue(VtValue &&value) = 0;
465};
466
480template <class T>
482{
483public:
485 : SdfAbstractDataValue(value, typeid(T))
486 { }
487
488private:
489 T const &_Get(const VtValue &v) {
490 return v.UncheckedGet<T>();
491 }
492
493 T _Get(VtValue &&v) {
494 return v.UncheckedRemove<T>();
495 }
496
497 template <class Value>
498 bool _StoreVtValueImpl(Value &&v) {
499 typeMismatch = false;
500 isValueBlock = false;
501 isAnimationBlock = false;
502 if (ARCH_LIKELY(std::forward<Value>(v).template IsHolding<T>())) {
503 *static_cast<T*>(value) = _Get(std::forward<Value>(v));
504 if constexpr (std::is_same_v<T, SdfValueBlock>) {
505 isValueBlock = true;
506 } else if constexpr (std::is_same_v<T, SdfAnimationBlock>) {
507 isAnimationBlock = true;
508 }
509 return true;
510 }
511
512 if (std::forward<Value>(v).template IsHolding<SdfValueBlock>()) {
513 isValueBlock = true;
514 return true;
515 }
516 else if (std::forward<Value>(v).template IsHolding<SdfAnimationBlock>())
517 {
518 isAnimationBlock = true;
519 return true;
520 }
521
522 typeMismatch = true;
523
524 return false;
525 }
526
527 virtual bool
528 _StoreVtValue(const VtValue& v) override {
529 return _StoreVtValueImpl(v);
530 }
531
532 virtual bool
533 _StoreVtValue(VtValue &&v) override {
534 return _StoreVtValueImpl(v);
535 }
536};
537
544{
545public:
546 virtual bool GetValue(VtValue* value) const = 0;
547
548 template <class T> bool GetValue(T* v) const
549 {
550 if (TfSafeTypeCompare(typeid(T), valueType)) {
551 *v = *static_cast<const T*>(value);
552 return true;
553 }
554 return false;
555 }
556
557 virtual bool IsEqual(const VtValue& value) const = 0;
558
559 const void* value;
560 const std::type_info& valueType;
561 const bool isArrayEdit;
562 const std::type_info& elementValueType; // void unless isArrayEdit
563
564protected:
565 SdfAbstractDataConstValue(const void* value_,
566 const std::type_info& valueType_,
567 const bool isArrayEdit_,
568 const std::type_info& elementValueType_)
569 : value(value_)
570 , valueType(valueType_)
571 , isArrayEdit(isArrayEdit_)
572 , elementValueType(elementValueType_)
573 {
574 }
575};
576
590template <class T>
592{
593public:
594 static std::type_info const &_GetElementType() {
595 if constexpr (VtIsArrayEdit<T>::value) {
596 return typeid(typename T::ElementType);
597 }
598 else {
599 return typeid(void);
600 }
601 }
602
603 SdfAbstractDataConstTypedValue(const T* value)
605 value, typeid(T), VtIsArrayEdit<T>::value, this->_GetElementType())
606 {}
607
608 virtual bool GetValue(VtValue* v) const
609 {
610 *v = _GetValue();
611 return true;
612 }
613
614 virtual bool IsEqual(const VtValue& v) const
615 {
616 return (v.IsHolding<T>() && v.UncheckedGet<T>() == _GetValue());
617 }
618
619private:
620 const T& _GetValue() const
621 {
622 return *static_cast<const T*>(value);
623 }
624};
625
626// Specialization of SdAbstractDataConstTypedValue that converts character
627// arrays to std::string.
628template <int N>
629class SdfAbstractDataConstTypedValue<char[N]>
630 : public SdfAbstractDataConstTypedValue<std::string>
631{
632public:
633 typedef char CharArray[N];
634 SdfAbstractDataConstTypedValue(const CharArray* value)
635 : SdfAbstractDataConstTypedValue<std::string>(&_str)
636 , _str(*value)
637 { }
638
639private:
640 std::string _str;
641};
642
649{
650public:
651 SDF_API
653
657 SDF_API
658 virtual bool VisitSpec(const SdfAbstractData& data,
659 const SdfPath& path) = 0;
660
663 SDF_API
664 virtual void Done(const SdfAbstractData& data) = 0;
665};
666
667PXR_NAMESPACE_CLOSE_SCOPE
668
669#endif // PXR_USD_SDF_ABSTRACT_DATA_H
The fully-typed container for a field value in an SdfAbstractData.
Definition: abstractData.h:592
A type-erased container for a const field value in an SdfAbstractData.
Definition: abstractData.h:544
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 bool GetPreviousTimeSampleForPath(const SdfPath &path, double time, double *tPrevious) const
Returns the previous time sample authored just before the querying time.
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:400
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:649
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:482
A type-erased container for a field value in an SdfAbstractData.
Definition: abstractData.h:417
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:152
T UncheckedRemove()
Make this value empty and return the held T instance.
Definition: value.h:1008
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
Definition: value.h:1050
T const & UncheckedGet() const &
Returns a const reference to the held object if the held object is of type T.
Definition: value.h:1094
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:92
A trait to detect instantiations of VtArrayEdit, specialized in arrayEdit.h.
Definition: traits.h:26
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