HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
primTypeInfo.h
Go to the documentation of this file.
1 //
2 // Copyright 2020 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_USD_PRIM_TYPE_INFO_H
25 #define PXR_USD_USD_PRIM_TYPE_INFO_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/usd/api.h"
30 #include "pxr/base/tf/token.h"
31 
32 #include <atomic>
33 
35 
36 /// Class that holds the full type information for a prim. It holds the type
37 /// name, applied API schema names, and possibly a mapped schema type name which
38 /// represent a unique full type.
39 /// The info this holds is used to cache and provide the "real" schema type for
40 /// the prim's type name regardless of whether it is a recognized prim type or
41 /// not. The optional "mapped schema type name" is used to obtain a valid schema
42 /// type for an unrecognized prim type name if the stage provides a fallback
43 /// type for the unrecognized type. This class also provides access to the prim
44 /// definition that defines all the built-in properties and metadata of a prim
45 /// of this type.
47 {
48 public:
49  /// Returns the concrete prim type name.
50  const TfToken &GetTypeName() const { return _typeId.primTypeName; }
51 
52  /// Returns the list of applied API schemas, directly authored on the prim,
53  /// that impart additional properties on its prim definition. This does NOT
54  /// include the applied API schemas that may be defined in the conrete prim
55  /// type's prim definition..
57  return _typeId.appliedAPISchemas;
58  }
59 
60  /// Returns the TfType of the actual concrete schema that prims of this
61  /// type will use to create their prim definition. Typically, this will
62  /// be the type registered in the schema registry for the concrete prim type
63  /// returned by GetTypeName. But if the stage provided this type info with
64  /// a fallback type because the prim type name is not a recognized schema,
65  /// this will return the provided fallback schema type instead.
66  ///
67  /// \sa \ref Usd_OM_FallbackPrimTypes
68  const TfType &GetSchemaType() const { return _schemaType; }
69 
70  /// Returns the type name associated with the schema type returned from
71  /// GetSchemaType. This will always be equivalent to calling
72  /// UsdSchemaRegistry::GetConcreteSchemaTypeName on the type returned by
73  /// GetSchemaType and will typically be the same as GetTypeName as long as
74  /// the prim type name is a recognized prim type.
75  ///
76  /// \sa \ref Usd_OM_FallbackPrimTypes
77  const TfToken &GetSchemaTypeName() const { return _schemaTypeName; }
78 
79  /// Returns the prim definition associated with this prim type's schema
80  /// type and applied API schemas.
82  // First check if we've already cached the prim definition pointer;
83  // we can just return it. Note that we use memory_order_acquire for
84  // the case wher _FindOrCreatePrimDefinition needs to build its own
85  // prim definition.
86  if (const UsdPrimDefinition *primDef =
87  _primDefinition.load(std::memory_order_acquire)) {
88  return *primDef;
89  }
90  return *_FindOrCreatePrimDefinition();
91  }
92 
93  bool operator==(const UsdPrimTypeInfo &other) const {
94  // Only need to compare typeId as a typeId is expected to always produce
95  // the same schema type and prim definition.
96  return _typeId == other._typeId;
97  }
98 
99  bool operator!=(const UsdPrimTypeInfo &other) const {
100  return !(*this == other);
101  }
102 
103  /// Returns the empty prim type info.
104  USD_API
105  static const UsdPrimTypeInfo &GetEmptyPrimType();
106 
107 private:
108  // Only the PrimTypeInfoCache can create the PrimTypeInfo prims.
109  // These are cached, one for each unique, prim type/applied schema list
110  // encountered. This provides the PrimData with lazy access to the unique
111  // prim definition for this exact prim type in a thread safe way.
112  friend class Usd_PrimTypeInfoCache;
113 
114  // This struct holds the information used to uniquely identify the type of a
115  // UsdPrimTypeInfo and can be used to key each prim type info in the type
116  // info cache.
117  struct _TypeId
118  {
119  // Authored type name of the prim.
120  TfToken primTypeName;
121 
122  // Optional type name that the type name should be mapped to instead.
123  // Will be used typically to provide a fallback schema type for an
124  // unrecognized prim type name.
125  TfToken mappedTypeName;
126 
127  // The list of applied API schemas authored on the prim.
128  TfTokenVector appliedAPISchemas;
129 
130  _TypeId() = default;
131 
132  // Have both move and copy constructors to minimize the number vector
133  // copies when possible.
134  _TypeId(const _TypeId &typeId) = default;
135  _TypeId(_TypeId &&typeId) = default;
136 
137  // Explicit constructor from just a prim type name.
138  explicit _TypeId(const TfToken &primTypeName_)
139  : primTypeName(primTypeName_) {}
140 
141  // Is empty type
142  bool IsEmpty() const {
143  return primTypeName.IsEmpty() &&
144  mappedTypeName.IsEmpty() &&
145  appliedAPISchemas.empty();
146  }
147 
148  // Hash function for hash map keying.
149  size_t Hash() const {
150  size_t hash = primTypeName.Hash();
151  if (!mappedTypeName.IsEmpty()) {
152  hboost::hash_combine(hash, mappedTypeName.Hash());
153  }
154  if (!appliedAPISchemas.empty()) {
155  size_t appliedHash = appliedAPISchemas.size();
156  for (const TfToken &apiSchema : appliedAPISchemas) {
157  hboost::hash_combine(appliedHash, apiSchema);
158  }
159  hboost::hash_combine(hash, appliedHash);
160  }
161  return hash;
162  }
163 
164  bool operator==(const _TypeId &other) const {
165  return primTypeName == other.primTypeName &&
166  mappedTypeName == other.mappedTypeName &&
167  appliedAPISchemas == other.appliedAPISchemas;
168  }
169 
170  bool operator!=(const _TypeId &other) const {
171  return !(*this == other);
172  }
173  };
174 
175  // Default constructor. Empty type.
176  UsdPrimTypeInfo() : _primDefinition(nullptr) {}
177 
178  // Move constructor from a _TypeId.
179  UsdPrimTypeInfo(_TypeId &&typeId);
180 
181  // Returns the full type ID.
182  const _TypeId &_GetTypeId() const { return _typeId; }
183 
184  // Finds the prim definition, creating it if it doesn't already exist. This
185  // cache access must be thread safe.
186  USD_API
187  const UsdPrimDefinition *_FindOrCreatePrimDefinition() const;
188 
189  _TypeId _typeId;
190  TfType _schemaType;
191  TfToken _schemaTypeName;
192 
193  // Cached pointer to the prim definition.
194  mutable std::atomic<const UsdPrimDefinition *> _primDefinition;
195 
196  // When there are applied API schemas, _FindOrCreatePrimDefinition will
197  // build a custom prim definition that it will own for its lifetime. This
198  // is here to make sure it is explicit when the prim type info owns the
199  // prim definition.
200  // Note that we will always return the prim definition via the atomic
201  // _primDefinition pointer regardless of whether the _ownedPrimDefinition
202  // is set.
203  mutable std::unique_ptr<UsdPrimDefinition> _ownedPrimDefinition;
204 };
205 
207 
208 #endif //PXR_USD_USD_PRIM_TYPE_INFO_H
#define USD_API
Definition: api.h:40
bool operator!=(const UsdPrimTypeInfo &other) const
Definition: primTypeInfo.h:99
const TfToken & GetSchemaTypeName() const
Definition: primTypeInfo.h:77
size_t OIIO_API Hash(const char *s, size_t len)
const UsdPrimDefinition & GetPrimDefinition() const
Definition: primTypeInfo.h:81
Definition: token.h:87
friend class Usd_PrimTypeInfoCache
Definition: primTypeInfo.h:112
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:446
const TfTokenVector & GetAppliedAPISchemas() const
Definition: primTypeInfo.h:56
bool operator==(const UsdPrimTypeInfo &other) const
Definition: primTypeInfo.h:93
const TfToken & GetTypeName() const
Returns the concrete prim type name.
Definition: primTypeInfo.h:50
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
Definition: type.h:64
static USD_API const UsdPrimTypeInfo & GetEmptyPrimType()
Returns the empty prim type info.
const TfType & GetSchemaType() const
Definition: primTypeInfo.h:68