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 typeMismatch = false;
431 if constexpr (std::is_same_v<Type, SdfValueBlock>) {
432 isValueBlock = true;
433 return true;
434 }
435 if (TfSafeTypeCompare(typeid(Type), valueType)) {
436 *static_cast<Type*>(value) = std::forward<T>(v);
437 return true;
438 }
439 typeMismatch = true;
440 return false;
441 }
442
443 void* value;
444 const std::type_info& valueType;
445 bool isValueBlock;
446 bool typeMismatch;
447
448protected:
449 SdfAbstractDataValue(void* value_, const std::type_info& valueType_)
450 : value(value_)
451 , valueType(valueType_)
452 , isValueBlock(false)
453 , typeMismatch(false)
454 { }
455
456private:
457 virtual bool _StoreVtValue(const VtValue& value) = 0;
458 virtual bool _StoreVtValue(VtValue &&value) = 0;
459};
460
474template <class T>
476{
477public:
479 : SdfAbstractDataValue(value, typeid(T))
480 { }
481
482private:
483 T const &_Get(const VtValue &v) {
484 return v.UncheckedGet<T>();
485 }
486
487 T _Get(VtValue &&v) {
488 return v.UncheckedRemove<T>();
489 }
490
491 template <class Value>
492 bool _StoreVtValueImpl(Value &&v) {
493 typeMismatch = false;
494 isValueBlock = false;
495 if (ARCH_LIKELY(std::forward<Value>(v).template IsHolding<T>())) {
496 *static_cast<T*>(value) = _Get(std::forward<Value>(v));
497 if (std::is_same_v<T, SdfValueBlock>) {
498 isValueBlock = true;
499 }
500 return true;
501 }
502
503 if (std::forward<Value>(v).template IsHolding<SdfValueBlock>()) {
504 isValueBlock = true;
505 return true;
506 }
507
508 typeMismatch = true;
509
510 return false;
511 }
512
513 virtual bool
514 _StoreVtValue(const VtValue& v) override {
515 return _StoreVtValueImpl(v);
516 }
517
518 virtual bool
519 _StoreVtValue(VtValue &&v) override {
520 return _StoreVtValueImpl(v);
521 }
522};
523
530{
531public:
532 virtual bool GetValue(VtValue* value) const = 0;
533
534 template <class T> bool GetValue(T* v) const
535 {
536 if (TfSafeTypeCompare(typeid(T), valueType)) {
537 *v = *static_cast<const T*>(value);
538 return true;
539 }
540 return false;
541 }
542
543 virtual bool IsEqual(const VtValue& value) const = 0;
544
545 const void* value;
546 const std::type_info& valueType;
547
548protected:
549 SdfAbstractDataConstValue(const void* value_,
550 const std::type_info& valueType_)
551 : value(value_)
552 , valueType(valueType_)
553 {
554 }
555};
556
570template <class T>
572{
573public:
574 SdfAbstractDataConstTypedValue(const T* value)
575 : SdfAbstractDataConstValue(value, typeid(T))
576 { }
577
578 virtual bool GetValue(VtValue* v) const
579 {
580 *v = _GetValue();
581 return true;
582 }
583
584 virtual bool IsEqual(const VtValue& v) const
585 {
586 return (v.IsHolding<T>() && v.UncheckedGet<T>() == _GetValue());
587 }
588
589private:
590 const T& _GetValue() const
591 {
592 return *static_cast<const T*>(value);
593 }
594};
595
596// Specialization of SdAbstractDataConstTypedValue that converts character
597// arrays to std::string.
598template <int N>
599class SdfAbstractDataConstTypedValue<char[N]>
600 : public SdfAbstractDataConstTypedValue<std::string>
601{
602public:
603 typedef char CharArray[N];
604 SdfAbstractDataConstTypedValue(const CharArray* value)
605 : SdfAbstractDataConstTypedValue<std::string>(&_str)
606 , _str(*value)
607 { }
608
609private:
610 std::string _str;
611};
612
619{
620public:
621 SDF_API
623
627 SDF_API
628 virtual bool VisitSpec(const SdfAbstractData& data,
629 const SdfPath& path) = 0;
630
633 SDF_API
634 virtual void Done(const SdfAbstractData& data) = 0;
635};
636
637PXR_NAMESPACE_CLOSE_SCOPE
638
639#endif // PXR_USD_SDF_ABSTRACT_DATA_H
The fully-typed container for a field value in an SdfAbstractData.
Definition: abstractData.h:572
A type-erased container for a const field value in an SdfAbstractData.
Definition: abstractData.h:530
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:619
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:476
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: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