abstractData.h
1 //
2 // Copyright 2016 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_SDF_ABSTRACT_DATA_H
25 #define PXR_USD_SDF_ABSTRACT_DATA_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/sdf/path.h"
29 #include "pxr/usd/sdf/types.h"
30 
31 #include "pxr/base/vt/value.h"
32 
34 #include "pxr/base/tf/token.h"
35 #include "pxr/base/tf/refBase.h"
36 #include "pxr/base/tf/weakBase.h"
38 
39 #include <vector>
40 #include <type_traits>
41 
42 PXR_NAMESPACE_OPEN_SCOPE
43 
48 
49 
50 #define SDF_DATA_TOKENS \
51  ((TimeSamples, "timeSamples"))
52 
53 TF_DECLARE_PUBLIC_TOKENS(SdfDataTokens, SDF_API, SDF_DATA_TOKENS);
54 
55 
73 class SdfAbstractData : public TfRefBase, public TfWeakBase
74 {
75 public:
76  SdfAbstractData() {}
77  SDF_API
78  virtual ~SdfAbstractData();
79 
84  SDF_API
85  virtual void CopyFrom(const SdfAbstractDataConstPtr& source);
86 
94  SDF_API
95  virtual bool StreamsData() const = 0;
96 
115  SDF_API
116  virtual bool IsDetached() const;
117 
122  SDF_API
123  virtual bool IsEmpty() const;
124 
130  // XXX: What are the right semantics for this?
131  // Does it matter if the underlying implementation matches?
132  SDF_API
133  virtual bool Equals(const SdfAbstractDataRefPtr &rhs) const;
134 
139  SDF_API
140  virtual void WriteToStream(std::ostream& out) const;
141 
144 
147  SDF_API
148  virtual void CreateSpec(const SdfPath &path,
149  SdfSpecType specType) = 0;
150 
152  SDF_API
153  virtual bool HasSpec(const SdfPath &path) const = 0;
154 
157  SDF_API
158  virtual void EraseSpec(const SdfPath &path) = 0;
159 
162  SDF_API
163  virtual void MoveSpec(const SdfPath &oldPath,
164  const SdfPath &newPath) = 0;
165 
168  virtual SdfSpecType GetSpecType(const SdfPath &path) const = 0;
169 
174  SDF_API
175  void VisitSpecs(SdfAbstractDataSpecVisitor* visitor) const;
176 
178 
181 
184  SDF_API
185  virtual bool Has(const SdfPath& path, const TfToken& fieldName,
186  SdfAbstractDataValue* value) const = 0;
187 
190  SDF_API
191  virtual bool Has(const SdfPath& path, const TfToken &fieldName,
192  VtValue *value = NULL) const = 0;
193 
204  SDF_API
205  virtual bool
206  HasSpecAndField(const SdfPath &path, const TfToken &fieldName,
207  SdfAbstractDataValue *value, SdfSpecType *specType) const;
208 
219  SDF_API
220  virtual bool
221  HasSpecAndField(const SdfPath &path, const TfToken &fieldName,
222  VtValue *value, SdfSpecType *specType) const;
223 
226  SDF_API
227  virtual VtValue Get(const SdfPath& path,
228  const TfToken& fieldName) const = 0;
229 
238  SDF_API
239  virtual std::type_info const &
240  GetTypeid(const SdfPath &path, const TfToken &fieldName) const;
241 
246  SDF_API
247  virtual void Set(const SdfPath &path, const TfToken &fieldName,
248  const VtValue &value) = 0;
249 
253  SDF_API
254  virtual void Set(const SdfPath &path, const TfToken &fieldName,
255  const SdfAbstractDataConstValue& value) = 0;
256 
258  SDF_API
259  virtual void Erase(const SdfPath& path,
260  const TfToken& fieldName) = 0;
261 
263  SDF_API
264  virtual std::vector<TfToken> List(const SdfPath& path) const = 0;
265 
268  template <class T>
269  inline T GetAs(const SdfPath& path, const TfToken& fieldName,
270  const T& defaultValue = T()) const;
271 
273 
274 
277 
278  // Return true and set \p value (if non null) if the field identified by
279  // \p path and \p fieldName is dictionary-valued, and if there is an element
280  // at \p keyPath in that dictionary. Return false otherwise. If
281  // \p keyPath names an entire sub-dictionary, set \p value to that entire
282  // sub-dictionary and return true.
283  SDF_API
284  virtual bool HasDictKey(const SdfPath& path,
285  const TfToken &fieldName,
286  const TfToken &keyPath,
287  SdfAbstractDataValue* value) const;
288  SDF_API
289  virtual bool HasDictKey(const SdfPath& path,
290  const TfToken &fieldName,
291  const TfToken &keyPath,
292  VtValue *value = NULL) const;
293 
294  // Same as HasDictKey but return empty VtValue on failure.
295  SDF_API
296  virtual VtValue GetDictValueByKey(const SdfPath& path,
297  const TfToken &fieldName,
298  const TfToken &keyPath) const;
299 
300  // Set the element at \p keyPath in the dictionary-valued field identified
301  // by \p path and \p fieldName. If the field itself is not
302  // dictionary-valued, replace the field with a new dictionary and set the
303  // element at \p keyPath in it. If \p value is empty, invoke
304  // EraseDictValueByKey instead.
305  SDF_API
306  virtual void SetDictValueByKey(const SdfPath& path,
307  const TfToken &fieldName,
308  const TfToken &keyPath,
309  const VtValue &value);
310  SDF_API
311  virtual void SetDictValueByKey(const SdfPath& path,
312  const TfToken &fieldName,
313  const TfToken &keyPath,
314  const SdfAbstractDataConstValue& value);
315 
316  // If \p path and \p fieldName identify a dictionary-valued field with an
317  // element at \p keyPath, remove that element from the dictionary. If this
318  // leaves the dictionary empty, Erase() the entire field.
319  SDF_API
320  virtual void EraseDictValueByKey(const SdfPath& path,
321  const TfToken &fieldName,
322  const TfToken &keyPath);
323 
324  // If \p path, \p fieldName, and \p keyPath identify a (sub) dictionary,
325  // return a vector of the keys in that dictionary, otherwise return an empty
326  // vector.
327  SDF_API
328  virtual std::vector<TfToken> ListDictKeys(const SdfPath& path,
329  const TfToken &fieldName,
330  const TfToken &keyPath) const;
331 
332 
334 
335 
345 
346  SDF_API
347  virtual std::set<double>
348  ListAllTimeSamples() const = 0;
349 
350  SDF_API
351  virtual std::set<double>
352  ListTimeSamplesForPath(const SdfPath& path) const = 0;
353 
354  SDF_API
355  virtual bool
356  GetBracketingTimeSamples(double time, double* tLower, double* tUpper) const = 0;
357 
358  SDF_API
359  virtual size_t
360  GetNumTimeSamplesForPath(const SdfPath& path) const = 0;
361 
362  SDF_API
363  virtual bool
364  GetBracketingTimeSamplesForPath(const SdfPath& path,
365  double time,
366  double* tLower, double* tUpper) const = 0;
367 
368  SDF_API
369  virtual bool
370  QueryTimeSample(const SdfPath& path, double time,
371  VtValue *optionalValue = NULL) const = 0;
372  SDF_API
373  virtual bool
374  QueryTimeSample(const SdfPath& path, double time,
375  SdfAbstractDataValue *optionalValue) const = 0;
376 
377  SDF_API
378  virtual void
379  SetTimeSample(const SdfPath& path, double time,
380  const VtValue & value) = 0;
381 
382  SDF_API
383  virtual void
384  EraseTimeSample(const SdfPath& path, double time) = 0;
385 
387 
388 protected:
394  SDF_API
395  virtual void _VisitSpecs(SdfAbstractDataSpecVisitor* visitor) const = 0;
396 };
397 
398 template <class T>
400  const SdfPath& path,
401  const TfToken& field, const T& defaultVal) const
402 {
403  VtValue val = Get(path, field);
404  if (val.IsHolding<T>()) {
405  return val.UncheckedGet<T>();
406  }
407  return defaultVal;
408 }
409 
416 {
417 public:
418  virtual bool StoreValue(const VtValue& value) = 0;
419  virtual bool StoreValue(VtValue &&value) = 0;
420 
421  template <class T>
422  bool StoreValue(const T& v)
423  {
424  if (TfSafeTypeCompare(typeid(T), valueType)) {
425  *static_cast<T*>(value) = v;
426  return true;
427  }
428  typeMismatch = true;
429  return false;
430  }
431 
432  bool StoreValue(const SdfValueBlock& block)
433  {
434  isValueBlock = true;
435  return true;
436  }
437 
438  void* value;
439  const std::type_info& valueType;
440  bool isValueBlock;
441  bool typeMismatch;
442 
443 protected:
444  SdfAbstractDataValue(void* value_, const std::type_info& valueType_)
445  : value(value_)
446  , valueType(valueType_)
447  , isValueBlock(false)
448  , typeMismatch(false)
449  { }
450 };
451 
465 template <class T>
467 {
468 public:
469  SdfAbstractDataTypedValue(T* value)
470  : SdfAbstractDataValue(value, typeid(T))
471  { }
472 
473  virtual bool StoreValue(const VtValue& v) override
474  {
475  if (ARCH_LIKELY(v.IsHolding<T>())) {
476  *static_cast<T*>(value) = v.UncheckedGet<T>();
477  if (std::is_same<T, SdfValueBlock>::value) {
478  isValueBlock = true;
479  }
480  return true;
481  }
482 
483  if (v.IsHolding<SdfValueBlock>()) {
484  isValueBlock = true;
485  return true;
486  }
487 
488  typeMismatch = true;
489 
490  return false;
491  }
492 
493  virtual bool StoreValue(VtValue &&v) override
494  {
495  if (ARCH_LIKELY(v.IsHolding<T>())) {
496  *static_cast<T*>(value) = v.UncheckedRemove<T>();
497  if (std::is_same<T, SdfValueBlock>::value) {
498  isValueBlock = true;
499  }
500  return true;
501  }
502 
503  if (v.IsHolding<SdfValueBlock>()) {
504  isValueBlock = true;
505  return true;
506  }
507 
508  typeMismatch = true;
509 
510  return false;
511  }
512 };
513 
520 {
521 public:
522  virtual bool GetValue(VtValue* value) const = 0;
523 
524  template <class T> bool GetValue(T* v) const
525  {
526  if (TfSafeTypeCompare(typeid(T), valueType)) {
527  *v = *static_cast<const T*>(value);
528  return true;
529  }
530  return false;
531  }
532 
533  virtual bool IsEqual(const VtValue& value) const = 0;
534 
535  const void* value;
536  const std::type_info& valueType;
537 
538 protected:
539  SdfAbstractDataConstValue(const void* value_,
540  const std::type_info& valueType_)
541  : value(value_)
542  , valueType(valueType_)
543  {
544  }
545 };
546 
560 template <class T>
562 {
563 public:
564  SdfAbstractDataConstTypedValue(const T* value)
565  : SdfAbstractDataConstValue(value, typeid(T))
566  { }
567 
568  virtual bool GetValue(VtValue* v) const
569  {
570  *v = _GetValue();
571  return true;
572  }
573 
574  virtual bool IsEqual(const VtValue& v) const
575  {
576  return (v.IsHolding<T>() && v.UncheckedGet<T>() == _GetValue());
577  }
578 
579 private:
580  const T& _GetValue() const
581  {
582  return *static_cast<const T*>(value);
583  }
584 };
585 
586 // Specialization of SdAbstractDataConstTypedValue that converts character
587 // arrays to std::string.
588 template <int N>
589 class SdfAbstractDataConstTypedValue<char[N]>
590  : public SdfAbstractDataConstTypedValue<std::string>
591 {
592 public:
593  typedef char CharArray[N];
594  SdfAbstractDataConstTypedValue(const CharArray* value)
595  : SdfAbstractDataConstTypedValue<std::string>(&_str)
596  , _str(*value)
597  { }
598 
599 private:
600  std::string _str;
601 };
602 
609 {
610 public:
611  SDF_API
612  virtual ~SdfAbstractDataSpecVisitor();
613 
617  SDF_API
618  virtual bool VisitSpec(const SdfAbstractData& data,
619  const SdfPath& path) = 0;
620 
623  SDF_API
624  virtual void Done(const SdfAbstractData& data) = 0;
625 };
626 
627 PXR_NAMESPACE_CLOSE_SCOPE
628 
629 #endif // PXR_USD_SDF_ABSTRACT_DATA_H
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 Done(const SdfAbstractData &data)=0
SdfAbstractData::VisitSpecs will call this after visitation is complete, even if some VisitSpec() ret...
Standard pointer typedefs.
Base class for objects used to visit specs in an SdfAbstractData object.
Definition: abstractData.h:608
T const & UncheckedGet() const &
Returns a const reference to the held object if the held object is of type T.
Definition: value.h:1093
A type-erased container for a const field value in an SdfAbstractData.
Definition: abstractData.h:519
The fully-typed container for a field value in an SdfAbstractData.
Definition: abstractData.h:561
A type-erased container for a field value in an SdfAbstractData.
Definition: abstractData.h:415
A special value type that can be used to explicitly author an opinion for an attribute's default valu...
Definition: types.h:598
#define TF_DECLARE_WEAK_AND_REF_PTRS(type)
Define standard weak, ref, and vector pointer types.
Definition: declarePtrs.h:89
T UncheckedRemove()
Make this value empty and return the held T instance.
Definition: value.h:1043
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:399
virtual SDF_API bool HasSpec(const SdfPath &path) const =0
Return true if this data has a spec for path.
Basic Sdf data types.
Enable a concrete base class for use with TfRefPtr.
Definition: refBase.h:71
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 CreateSpec(const SdfPath &path, SdfSpecType specType)=0
Create a new spec at path with the given specType.
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...
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
virtual SDF_API void CopyFrom(const SdfAbstractDataConstPtr &source)
Copy the data in source into this data object.
virtual SdfSpecType GetSpecType(const SdfPath &path) const =0
Return the spec type for the spec at path.
#define TF_DECLARE_PUBLIC_TOKENS(...)
Macro to define public tokens.
Definition: staticTokens.h:118
virtual SDF_API void WriteToStream(std::ostream &out) const
Writes the contents of this data object to out.
The fully-typed container for a field value in an SdfAbstractData.
Definition: abstractData.h:466
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
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 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 bool IsEmpty() const
Returns true if this data object has no specs, false otherwise.
This file defines some macros that are useful for declaring and using static TfTokens.
SdfSpecType
An enum that specifies the type of an object.
Definition: types.h:91
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 void MoveSpec(const SdfPath &oldPath, const SdfPath &newPath)=0
Move the spec at oldPath to newPath, including all the fields that are on it.
virtual SDF_API void _VisitSpecs(SdfAbstractDataSpecVisitor *visitor) const =0
Visits every spec in this SdfAbstractData object with the given visitor.
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 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 void Erase(const SdfPath &path, const TfToken &fieldName)=0
Remove the field at path and fieldName, if one exists.
virtual SDF_API bool IsDetached() const
Returns true if this data object is detached from its serialized data store, false otherwise.
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
Definition: value.h:1053
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:141
virtual SDF_API std::vector< TfToken > List(const SdfPath &path) const =0
Return the names of all the fields that are set at path.
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:166
SDF_API void VisitSpecs(SdfAbstractDataSpecVisitor *visitor) const
Visits every spec in this SdfAbstractData object with the given visitor.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
Interface for scene description data storage.
Definition: abstractData.h:73
bool TfSafeTypeCompare(const std::type_info &t1, const std::type_info &t2)
Safely compare std::type_info structures.