primTypeInfo.h
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"
29 #include "pxr/usd/usd/primDefinition.h"
30 #include "pxr/base/tf/token.h"
31 #include "pxr/base/tf/hash.h"
32 
33 #include <atomic>
34 
35 PXR_NAMESPACE_OPEN_SCOPE
36 
48 {
49 public:
51  const TfToken &GetTypeName() const { return _typeId.primTypeName; }
52 
58  return _typeId.appliedAPISchemas;
59  }
60 
69  const TfType &GetSchemaType() const { return _schemaType; }
70 
78  const TfToken &GetSchemaTypeName() const { return _schemaTypeName; }
79 
83  // First check if we've already cached the prim definition pointer;
84  // we can just return it. Note that we use memory_order_acquire for
85  // the case wher _FindOrCreatePrimDefinition needs to build its own
86  // prim definition.
87  if (const UsdPrimDefinition *primDef =
88  _primDefinition.load(std::memory_order_acquire)) {
89  return *primDef;
90  }
91  return *_FindOrCreatePrimDefinition();
92  }
93 
94  bool operator==(const UsdPrimTypeInfo &other) const {
95  // Only need to compare typeId as a typeId is expected to always produce
96  // the same schema type and prim definition.
97  return _typeId == other._typeId;
98  }
99 
100  bool operator!=(const UsdPrimTypeInfo &other) const {
101  return !(*this == other);
102  }
103 
105  USD_API
106  static const UsdPrimTypeInfo &GetEmptyPrimType();
107 
108 private:
109  // Only the PrimTypeInfoCache can create the PrimTypeInfo prims.
110  // These are cached, one for each unique, prim type/applied schema list
111  // encountered. This provides the PrimData with lazy access to the unique
112  // prim definition for this exact prim type in a thread safe way.
113  friend class Usd_PrimTypeInfoCache;
114 
115  // This struct holds the information used to uniquely identify the type of a
116  // UsdPrimTypeInfo and can be used to key each prim type info in the type
117  // info cache.
118  struct _TypeId
119  {
120  // Authored type name of the prim.
121  TfToken primTypeName;
122 
123  // Optional type name that the type name should be mapped to instead.
124  // Will be used typically to provide a fallback schema type for an
125  // unrecognized prim type name.
126  TfToken mappedTypeName;
127 
128  // The list of applied API schemas authored on the prim.
129  TfTokenVector appliedAPISchemas;
130 
131  _TypeId() = default;
132 
133  // Have both move and copy constructors to minimize the number vector
134  // copies when possible.
135  _TypeId(const _TypeId &typeId) = default;
136  _TypeId(_TypeId &&typeId) = default;
137 
138  // Explicit constructor from just a prim type name.
139  explicit _TypeId(const TfToken &primTypeName_)
140  : primTypeName(primTypeName_) {}
141 
142  // Is empty type
143  bool IsEmpty() const {
144  return primTypeName.IsEmpty() &&
145  mappedTypeName.IsEmpty() &&
146  appliedAPISchemas.empty();
147  }
148 
149  // Hash function for hash map keying.
150  template <class HashState>
151  friend void TfHashAppend(HashState &h, const _TypeId &id)
152  {
153  h.Append(id.primTypeName, id.mappedTypeName, id.appliedAPISchemas);
154  }
155 
156  size_t Hash() const {
157  return TfHash()(*this);
158  }
159 
160  bool operator==(const _TypeId &other) const {
161  return primTypeName == other.primTypeName &&
162  mappedTypeName == other.mappedTypeName &&
163  appliedAPISchemas == other.appliedAPISchemas;
164  }
165 
166  bool operator!=(const _TypeId &other) const {
167  return !(*this == other);
168  }
169  };
170 
171  // Default constructor. Empty type.
172  UsdPrimTypeInfo() : _primDefinition(nullptr) {}
173 
174  // Move constructor from a _TypeId.
175  UsdPrimTypeInfo(_TypeId &&typeId);
176 
177  // Returns the full type ID.
178  const _TypeId &_GetTypeId() const { return _typeId; }
179 
180  // Finds the prim definition, creating it if it doesn't already exist. This
181  // cache access must be thread safe.
182  USD_API
183  const UsdPrimDefinition *_FindOrCreatePrimDefinition() const;
184 
185  _TypeId _typeId;
186  TfType _schemaType;
187  TfToken _schemaTypeName;
188 
189  // Cached pointer to the prim definition.
190  mutable std::atomic<const UsdPrimDefinition *> _primDefinition;
191 
192  // When there are applied API schemas, _FindOrCreatePrimDefinition will
193  // build a custom prim definition that it will own for its lifetime. This
194  // is here to make sure it is explicit when the prim type info owns the
195  // prim definition.
196  // Note that we will always return the prim definition via the atomic
197  // _primDefinition pointer regardless of whether the _ownedPrimDefinition
198  // is set.
199  mutable std::unique_ptr<UsdPrimDefinition> _ownedPrimDefinition;
200 };
201 
202 PXR_NAMESPACE_CLOSE_SCOPE
203 
204 #endif //PXR_USD_USD_PRIM_TYPE_INFO_H
bool IsEmpty() const
Returns true iff this token contains the empty string "".
Definition: token.h:302
const TfType & GetSchemaType() const
Returns the TfType of the actual concrete schema that prims of this type will use to create their pri...
Definition: primTypeInfo.h:69
const UsdPrimDefinition & GetPrimDefinition() const
Returns the prim definition associated with this prim type's schema type and applied API schemas.
Definition: primTypeInfo.h:82
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:447
static USD_API const UsdPrimTypeInfo & GetEmptyPrimType()
Returns the empty prim type info.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
const TfTokenVector & GetAppliedAPISchemas() const
Returns the list of applied API schemas, directly authored on the prim, that impart additional proper...
Definition: primTypeInfo.h:57
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:442
Class that holds the full type information for a prim.
Definition: primTypeInfo.h:47
Class representing the builtin definition of a prim given the schemas registered in the schema regist...
TfType represents a dynamic runtime type.
Definition: type.h:64
const TfToken & GetSchemaTypeName() const
Returns the type name associated with the schema type returned from GetSchemaType.
Definition: primTypeInfo.h:78
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
const TfToken & GetTypeName() const
Returns the concrete prim type name.
Definition: primTypeInfo.h:51