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 
101  SDF_API
102  virtual bool IsEmpty() const;
103 
109  // XXX: What are the right semantics for this?
110  // Does it matter if the underlying implementation matches?
111  SDF_API
112  virtual bool Equals(const SdfAbstractDataRefPtr &rhs) const;
113 
118  SDF_API
119  virtual void WriteToStream(std::ostream& out) const;
120 
123 
126  SDF_API
127  virtual void CreateSpec(const SdfPath &path,
128  SdfSpecType specType) = 0;
129 
131  SDF_API
132  virtual bool HasSpec(const SdfPath &path) const = 0;
133 
136  SDF_API
137  virtual void EraseSpec(const SdfPath &path) = 0;
138 
141  SDF_API
142  virtual void MoveSpec(const SdfPath &oldPath,
143  const SdfPath &newPath) = 0;
144 
147  virtual SdfSpecType GetSpecType(const SdfPath &path) const = 0;
148 
153  SDF_API
154  void VisitSpecs(SdfAbstractDataSpecVisitor* visitor) const;
155 
157 
160 
163  SDF_API
164  virtual bool Has(const SdfPath& path, const TfToken& fieldName,
165  SdfAbstractDataValue* value) const = 0;
166 
169  SDF_API
170  virtual bool Has(const SdfPath& path, const TfToken &fieldName,
171  VtValue *value = NULL) const = 0;
172 
183  SDF_API
184  virtual bool
185  HasSpecAndField(const SdfPath &path, const TfToken &fieldName,
186  SdfAbstractDataValue *value, SdfSpecType *specType) const;
187 
198  SDF_API
199  virtual bool
200  HasSpecAndField(const SdfPath &path, const TfToken &fieldName,
201  VtValue *value, SdfSpecType *specType) const;
202 
205  SDF_API
206  virtual VtValue Get(const SdfPath& path,
207  const TfToken& fieldName) const = 0;
208 
217  SDF_API
218  virtual std::type_info const &
219  GetTypeid(const SdfPath &path, const TfToken &fieldName) const;
220 
225  SDF_API
226  virtual void Set(const SdfPath &path, const TfToken &fieldName,
227  const VtValue &value) = 0;
228 
232  SDF_API
233  virtual void Set(const SdfPath &path, const TfToken &fieldName,
234  const SdfAbstractDataConstValue& value) = 0;
235 
237  SDF_API
238  virtual void Erase(const SdfPath& path,
239  const TfToken& fieldName) = 0;
240 
242  SDF_API
243  virtual std::vector<TfToken> List(const SdfPath& path) const = 0;
244 
247  template <class T>
248  inline T GetAs(const SdfPath& path, const TfToken& fieldName,
249  const T& defaultValue = T()) const;
250 
252 
253 
256 
257  // Return true and set \p value (if non null) if the field identified by
258  // \p path and \p fieldName is dictionary-valued, and if there is an element
259  // at \p keyPath in that dictionary. Return false otherwise. If
260  // \p keyPath names an entire sub-dictionary, set \p value to that entire
261  // sub-dictionary and return true.
262  SDF_API
263  virtual bool HasDictKey(const SdfPath& path,
264  const TfToken &fieldName,
265  const TfToken &keyPath,
266  SdfAbstractDataValue* value) const;
267  SDF_API
268  virtual bool HasDictKey(const SdfPath& path,
269  const TfToken &fieldName,
270  const TfToken &keyPath,
271  VtValue *value = NULL) const;
272 
273  // Same as HasDictKey but return empty VtValue on failure.
274  SDF_API
275  virtual VtValue GetDictValueByKey(const SdfPath& path,
276  const TfToken &fieldName,
277  const TfToken &keyPath) const;
278 
279  // Set the element at \p keyPath in the dictionary-valued field identified
280  // by \p path and \p fieldName. If the field itself is not
281  // dictionary-valued, replace the field with a new dictionary and set the
282  // element at \p keyPath in it. If \p value is empty, invoke
283  // EraseDictValueByKey instead.
284  SDF_API
285  virtual void SetDictValueByKey(const SdfPath& path,
286  const TfToken &fieldName,
287  const TfToken &keyPath,
288  const VtValue &value);
289  SDF_API
290  virtual void SetDictValueByKey(const SdfPath& path,
291  const TfToken &fieldName,
292  const TfToken &keyPath,
293  const SdfAbstractDataConstValue& value);
294 
295  // If \p path and \p fieldName identify a dictionary-valued field with an
296  // element at \p keyPath, remove that element from the dictionary. If this
297  // leaves the dictionary empty, Erase() the entire field.
298  SDF_API
299  virtual void EraseDictValueByKey(const SdfPath& path,
300  const TfToken &fieldName,
301  const TfToken &keyPath);
302 
303  // If \p path, \p fieldName, and \p keyPath identify a (sub) dictionary,
304  // return a vector of the keys in that dictionary, otherwise return an empty
305  // vector.
306  SDF_API
307  virtual std::vector<TfToken> ListDictKeys(const SdfPath& path,
308  const TfToken &fieldName,
309  const TfToken &keyPath) const;
310 
311 
313 
314 
324 
325  SDF_API
326  virtual std::set<double>
327  ListAllTimeSamples() const = 0;
328 
329  SDF_API
330  virtual std::set<double>
331  ListTimeSamplesForPath(const SdfPath& path) const = 0;
332 
333  SDF_API
334  virtual bool
335  GetBracketingTimeSamples(double time, double* tLower, double* tUpper) const = 0;
336 
337  SDF_API
338  virtual size_t
339  GetNumTimeSamplesForPath(const SdfPath& path) const = 0;
340 
341  SDF_API
342  virtual bool
343  GetBracketingTimeSamplesForPath(const SdfPath& path,
344  double time,
345  double* tLower, double* tUpper) const = 0;
346 
347  SDF_API
348  virtual bool
349  QueryTimeSample(const SdfPath& path, double time,
350  VtValue *optionalValue = NULL) const = 0;
351  SDF_API
352  virtual bool
353  QueryTimeSample(const SdfPath& path, double time,
354  SdfAbstractDataValue *optionalValue) const = 0;
355 
356  SDF_API
357  virtual void
358  SetTimeSample(const SdfPath& path, double time,
359  const VtValue & value) = 0;
360 
361  SDF_API
362  virtual void
363  EraseTimeSample(const SdfPath& path, double time) = 0;
364 
366 
367 protected:
373  SDF_API
374  virtual void _VisitSpecs(SdfAbstractDataSpecVisitor* visitor) const = 0;
375 };
376 
377 template <class T>
379  const SdfPath& path,
380  const TfToken& field, const T& defaultVal) const
381 {
382  VtValue val = Get(path, field);
383  if (val.IsHolding<T>()) {
384  return val.UncheckedGet<T>();
385  }
386  return defaultVal;
387 }
388 
395 {
396 public:
397  virtual bool StoreValue(const VtValue& value) = 0;
398  virtual bool StoreValue(VtValue &&value) = 0;
399 
400  template <class T>
401  bool StoreValue(const T& v)
402  {
403  if (TfSafeTypeCompare(typeid(T), valueType)) {
404  *static_cast<T*>(value) = v;
405  return true;
406  }
407  typeMismatch = true;
408  return false;
409  }
410 
411  bool StoreValue(const SdfValueBlock& block)
412  {
413  isValueBlock = true;
414  return true;
415  }
416 
417  void* value;
418  const std::type_info& valueType;
419  bool isValueBlock;
420  bool typeMismatch;
421 
422 protected:
423  SdfAbstractDataValue(void* value_, const std::type_info& valueType_)
424  : value(value_)
425  , valueType(valueType_)
426  , isValueBlock(false)
427  , typeMismatch(false)
428  { }
429 };
430 
444 template <class T>
446 {
447 public:
448  SdfAbstractDataTypedValue(T* value)
449  : SdfAbstractDataValue(value, typeid(T))
450  { }
451 
452  virtual bool StoreValue(const VtValue& v) override
453  {
454  if (ARCH_LIKELY(v.IsHolding<T>())) {
455  *static_cast<T*>(value) = v.UncheckedGet<T>();
456  if (std::is_same<T, SdfValueBlock>::value) {
457  isValueBlock = true;
458  }
459  return true;
460  }
461 
462  if (v.IsHolding<SdfValueBlock>()) {
463  isValueBlock = true;
464  return true;
465  }
466 
467  typeMismatch = true;
468 
469  return false;
470  }
471 
472  virtual bool StoreValue(VtValue &&v) override
473  {
474  if (ARCH_LIKELY(v.IsHolding<T>())) {
475  *static_cast<T*>(value) = v.UncheckedRemove<T>();
476  if (std::is_same<T, SdfValueBlock>::value) {
477  isValueBlock = true;
478  }
479  return true;
480  }
481 
482  if (v.IsHolding<SdfValueBlock>()) {
483  isValueBlock = true;
484  return true;
485  }
486 
487  typeMismatch = true;
488 
489  return false;
490  }
491 };
492 
499 {
500 public:
501  virtual bool GetValue(VtValue* value) const = 0;
502 
503  template <class T> bool GetValue(T* v) const
504  {
505  if (TfSafeTypeCompare(typeid(T), valueType)) {
506  *v = *static_cast<const T*>(value);
507  return true;
508  }
509  return false;
510  }
511 
512  virtual bool IsEqual(const VtValue& value) const = 0;
513 
514  const void* value;
515  const std::type_info& valueType;
516 
517 protected:
518  SdfAbstractDataConstValue(const void* value_,
519  const std::type_info& valueType_)
520  : value(value_)
521  , valueType(valueType_)
522  {
523  }
524 };
525 
539 template <class T>
541 {
542 public:
543  SdfAbstractDataConstTypedValue(const T* value)
544  : SdfAbstractDataConstValue(value, typeid(T))
545  { }
546 
547  virtual bool GetValue(VtValue* v) const
548  {
549  *v = _GetValue();
550  return true;
551  }
552 
553  virtual bool IsEqual(const VtValue& v) const
554  {
555  return (v.IsHolding<T>() && v.UncheckedGet<T>() == _GetValue());
556  }
557 
558 private:
559  const T& _GetValue() const
560  {
561  return *static_cast<const T*>(value);
562  }
563 };
564 
565 // Specialization of SdAbstractDataConstTypedValue that converts character
566 // arrays to std::string.
567 template <int N>
568 class SdfAbstractDataConstTypedValue<char[N]>
569  : public SdfAbstractDataConstTypedValue<std::string>
570 {
571 public:
572  typedef char CharArray[N];
573  SdfAbstractDataConstTypedValue(const CharArray* value)
574  : SdfAbstractDataConstTypedValue<std::string>(&_str)
575  , _str(*value)
576  { }
577 
578 private:
579  std::string _str;
580 };
581 
588 {
589 public:
590  SDF_API
591  virtual ~SdfAbstractDataSpecVisitor();
592 
596  SDF_API
597  virtual bool VisitSpec(const SdfAbstractData& data,
598  const SdfPath& path) = 0;
599 
602  SDF_API
603  virtual void Done(const SdfAbstractData& data) = 0;
604 };
605 
606 PXR_NAMESPACE_CLOSE_SCOPE
607 
608 #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:587
A type-erased container for a const field value in an SdfAbstractData.
Definition: abstractData.h:498
The fully-typed container for a field value in an SdfAbstractData.
Definition: abstractData.h:540
A type-erased container for a field value in an SdfAbstractData.
Definition: abstractData.h:394
A special value type that can be used to explicitly author an opinion for an attribute's default valu...
Definition: types.h:594
#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:1039
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:378
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:445
T const & UncheckedGet() const
Returns a const reference to the held object if the held object is of type T.
Definition: value.h:1077
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.
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
Definition: value.h:1049
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.