HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TypeDesc.h
Go to the documentation of this file.
1 //
2 // Copyright Contributors to the MaterialX Project
3 // SPDX-License-Identifier: Apache-2.0
4 //
5 
6 #ifndef MATERIALX_TYPEDESC_H
7 #define MATERIALX_TYPEDESC_H
8 
9 /// @file
10 /// Type descriptor for a MaterialX data type.
11 
13 #include <MaterialXCore/Value.h>
14 #include <MaterialXCore/Document.h>
15 
16 #include <string_view>
17 
19 
20 class TypeDesc;
21 class StructMemberDesc;
22 using TypeDescVec = vector<TypeDesc>;
23 using TypeDescMap = std::unordered_map<string, TypeDesc>;
24 using StructMemberDescVec = vector<StructMemberDesc>;
25 using StructMemberDescVecPtr = shared_ptr<const StructMemberDescVec>;
26 
27 /// @class TypeDesc
28 /// A type descriptor for MaterialX data types.
29 ///
30 /// All types need to have a type descriptor registered in order for shader generators
31 /// to know about the type. It can be used for type comparisons as well as getting more
32 /// information about the type. Type descriptors for all standard library data types are
33 /// defined by default and can be accessed from the Type namespace, e.g. Type::FLOAT.
34 /// Custom struct types defined through typedef elements in a data library are loaded in
35 /// and registered by calling the ShaderGenerator::registerTypeDefs method. The TypeSystem
36 /// class, see below, is used to manage all type descriptions. It can be used to query the
37 /// registered types.
38 ///
40 {
41  public:
42  enum BaseType
43  {
50  BASETYPE_LAST
51  };
52 
53  enum Semantic
54  {
64  SEMANTIC_LAST
65  };
66 
67  /// Data block holding large data needed by the type description.
68  class DataBlock
69  {
70  public:
71  DataBlock(const string& name, const StructMemberDescVecPtr members = nullptr) noexcept : _name(name), _members(members) {}
72 
73  const string& getName() const { return _name; }
74  StructMemberDescVecPtr getStructMembers() const { return _members; }
75 
76  private:
77  const string _name;
78  const StructMemberDescVecPtr _members;
79  };
80 
81  using DataBlockPtr = std::shared_ptr<DataBlock>;
82 
83  /// Empty constructor.
84  constexpr TypeDesc() noexcept :
85  _id(0),
86  _basetype(BASETYPE_NONE),
87  _semantic(SEMANTIC_NONE),
88  _size(0),
89  _data(nullptr)
90  {
91  }
92 
93  /// Constructor.
94  constexpr TypeDesc(std::string_view name, uint8_t basetype, uint8_t semantic, uint16_t size, const DataBlock* data) noexcept :
95  _id(constexpr_hash(name)), // Note: We only store the hash to keep the class size minimal.
96  _basetype(basetype),
97  _semantic(semantic),
98  _size(size),
99  _data(data)
100  {
101  }
102 
103  /// Return the unique id assigned to this type.
104  /// The id is a hash of the given type name.
105  uint32_t typeId() const { return _id; }
106 
107  /// Return the name of the type.
108  const string& getName() const;
109 
110  /// Return the basetype for the type.
111  unsigned char getBaseType() const { return _basetype; }
112 
113  /// Return the semantic for the type.
114  unsigned char getSemantic() const { return _semantic; }
115 
116  /// Return the number of elements the type is composed of.
117  /// Will return 1 for scalar types and a size greater than 1 for aggregate type.
118  /// For array types 0 is returned since the number of elements is undefined
119  /// until an array is instantiated.
120  size_t getSize() const { return _size; }
121 
122  /// Return true if the type is a scalar type.
123  bool isScalar() const { return _size == 1; }
124 
125  /// Return true if the type is an aggregate type.
126  bool isAggregate() const { return _size > 1; }
127 
128  /// Return true if the type is an array type.
129  bool isArray() const { return _size == 0; }
130 
131  /// Return true if the type is an aggregate of 2 floats.
132  bool isFloat2() const { return _size == 2 && (_semantic == SEMANTIC_COLOR || _semantic == SEMANTIC_VECTOR); }
133 
134  /// Return true if the type is an aggregate of 3 floats.
135  bool isFloat3() const { return _size == 3 && (_semantic == SEMANTIC_COLOR || _semantic == SEMANTIC_VECTOR); }
136 
137  /// Return true if the type is an aggregate of 4 floats.
138  bool isFloat4() const { return _size == 4 && (_semantic == SEMANTIC_COLOR || _semantic == SEMANTIC_VECTOR); }
139 
140  /// Return true if the type represents a closure.
141  bool isClosure() const { return (_semantic == SEMANTIC_CLOSURE || _semantic == SEMANTIC_SHADER || _semantic == SEMANTIC_MATERIAL); }
142 
143  /// Return true if the type represents a struct.
144  bool isStruct() const { return _basetype == BASETYPE_STRUCT; }
145 
146  /// Return a pointer to the struct member description.
147  /// Will return nullptr if this is not a struct type.
148  StructMemberDescVecPtr getStructMembers() const;
149 
150  /// Equality operator
151  bool operator==(TypeDesc rhs) const
152  {
153  return _id == rhs._id;
154  }
155 
156  /// Inequality operator
157  bool operator!=(TypeDesc rhs) const
158  {
159  return _id != rhs._id;
160  }
161 
162  /// Less-than operator
163  bool operator<(TypeDesc rhs) const
164  {
165  return _id < rhs._id;
166  }
167 
168  /// Hash operator
169  struct Hasher
170  {
171  size_t operator()(const TypeDesc& t) const
172  {
173  return t._id;
174  }
175  };
176 
177  static const string NONE_TYPE_NAME;
178 
179  /// Create a Value from a string for a given typeDesc
180  ValuePtr createValueFromStrings(const string& value) const;
181 
182  private:
183  /// Simple constexpr hash function, good enough for the small set of short strings that
184  /// are used for our data type names.
185  constexpr uint32_t constexpr_hash(std::string_view str, uint32_t n = 0, uint32_t h = 2166136261)
186  {
187  return n == uint32_t(str.size()) ? h : constexpr_hash(str, n + 1, (h * 16777619) ^ (str[n]));
188  }
189 
190  uint32_t _id;
191  uint8_t _basetype;
192  uint8_t _semantic;
193  uint16_t _size;
194  const DataBlock* _data;
195 };
196 
197 /// @class StructMemberDesc
198 /// Type descriptor for member of a struct type.
200 {
201 public:
202  StructMemberDesc(TypeDesc type, const string& name, const string& defaultValueStr) :
203  _type(type),
204  _name(name),
205  _defaultValueStr(defaultValueStr)
206  {
207  }
208 
209  TypeDesc getType() const { return _type; }
210  const string& getName() const { return _name; }
211  const string& getDefaultValueStr() const { return _defaultValueStr; }
212 
213 private:
214  const TypeDesc _type;
215  const string _name;
216  const string _defaultValueStr;
217 };
218 
219 using TypeSystemPtr = shared_ptr<class TypeSystem>;
220 
221 /// @class TypeSystem
222 /// Class handling registration, storage and query of type descriptions.
224 {
225 public:
226  /// Create a new type system.
227  static TypeSystemPtr create();
228 
229  /// Register an existing type decription.
230  void registerType(TypeDesc type);
231 
232  /// Create and register a new type description.
233  void registerType(const string& name, uint8_t basetype, uint8_t semantic, uint16_t size, StructMemberDescVecPtr members = nullptr);
234 
235  /// Return a type description by name.
236  /// If no type is found Type::NONE is returned.
237  TypeDesc getType(const string& name) const;
238 
239  /// Return all registered type descriptions.
240  const TypeDescVec& getTypes() const
241  {
242  return _types;
243  }
244 
245 protected:
246  // Protected constructor
247  TypeSystem();
248 
249 private:
250  TypeDescVec _types;
251  TypeDescMap _typesByName;
252  vector<TypeDesc::DataBlockPtr> _dataBlocks;
253 };
254 
255 /// Macro to define global type descriptions for commonly used types.
256 #define TYPEDESC_DEFINE_TYPE(T, name, basetype, semantic, size) \
257  inline const TypeDesc::DataBlock* T##_data() { static const TypeDesc::DataBlock _data(name); return &_data; } \
258  static const TypeDesc T(name, basetype, semantic, size, T##_data());
259 
260 namespace Type
261 {
262 
263 //
264 /// Define type descriptors for standard types.
265 //
286 TYPEDESC_DEFINE_TYPE(DISPLACEMENTSHADER, "displacementshader", TypeDesc::BASETYPE_NONE, TypeDesc::SEMANTIC_SHADER, 1)
289 
290 } // namespace Type
291 
293 
294 #endif
static const string NONE_TYPE_NAME
Definition: TypeDesc.h:177
uint32_t typeId() const
Definition: TypeDesc.h:105
bool operator<(TypeDesc rhs) const
Less-than operator.
Definition: TypeDesc.h:163
shared_ptr< const StructMemberDescVec > StructMemberDescVecPtr
Definition: TypeDesc.h:25
#define MATERIALX_NAMESPACE_BEGIN
Definition: Generated.h:25
FLOAT
Definition: ImfPixelType.h:24
GLsizei const GLfloat * value
Definition: glcorearb.h:824
unsigned char getSemantic() const
Return the semantic for the type.
Definition: TypeDesc.h:114
vector< StructMemberDesc > StructMemberDescVec
Definition: TypeDesc.h:24
const string & getDefaultValueStr() const
Definition: TypeDesc.h:211
bool operator==(TypeDesc rhs) const
Equality operator.
Definition: TypeDesc.h:151
#define MX_GENSHADER_API
Definition: Export.h:18
shared_ptr< class TypeSystem > TypeSystemPtr
Definition: TypeDesc.h:219
DataBlock(const string &name, const StructMemberDescVecPtr members=nullptr) noexcept
Definition: TypeDesc.h:71
const string & getName() const
Definition: TypeDesc.h:210
bool isStruct() const
Return true if the type represents a struct.
Definition: TypeDesc.h:144
const string & getName() const
Definition: TypeDesc.h:73
basic_string_view< char > string_view
Definition: core.h:501
GLdouble n
Definition: glcorearb.h:2008
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
size_t operator()(const TypeDesc &t) const
Definition: TypeDesc.h:171
unsigned char getBaseType() const
Return the basetype for the type.
Definition: TypeDesc.h:111
bool isClosure() const
Return true if the type represents a closure.
Definition: TypeDesc.h:141
PXL_API const char * getName(const ColorSpace *space)
Return the name of the color space.
StructMemberDescVecPtr getStructMembers() const
Definition: TypeDesc.h:74
bool isFloat2() const
Return true if the type is an aggregate of 2 floats.
Definition: TypeDesc.h:132
Hash operator.
Definition: TypeDesc.h:169
std::unordered_map< string, TypeDesc > TypeDescMap
Definition: TypeDesc.h:23
GLuint const GLchar * name
Definition: glcorearb.h:786
Data block holding large data needed by the type description.
Definition: TypeDesc.h:68
const TypeDescVec & getTypes() const
Return all registered type descriptions.
Definition: TypeDesc.h:240
StructMemberDesc(TypeDesc type, const string &name, const string &defaultValueStr)
Definition: TypeDesc.h:202
GLdouble t
Definition: glad.h:2397
#define TYPEDESC_DEFINE_TYPE(T, name, basetype, semantic, size)
Macro to define global type descriptions for commonly used types.
Definition: TypeDesc.h:256
bool isAggregate() const
Return true if the type is an aggregate type.
Definition: TypeDesc.h:126
constexpr TypeDesc() noexcept
Empty constructor.
Definition: TypeDesc.h:84
size_t getSize() const
Definition: TypeDesc.h:120
GLsizeiptr size
Definition: glcorearb.h:664
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
vector< TypeDesc > TypeDescVec
Definition: TypeDesc.h:22
std::shared_ptr< DataBlock > DataBlockPtr
Definition: TypeDesc.h:81
bool operator!=(TypeDesc rhs) const
Inequality operator.
Definition: TypeDesc.h:157
bool isFloat3() const
Return true if the type is an aggregate of 3 floats.
Definition: TypeDesc.h:135
bool isScalar() const
Return true if the type is a scalar type.
Definition: TypeDesc.h:123
#define MATERIALX_NAMESPACE_END
Definition: Generated.h:26
TypeDesc getType() const
Definition: TypeDesc.h:209
constexpr TypeDesc(std::string_view name, uint8_t basetype, uint8_t semantic, uint16_t size, const DataBlock *data) noexcept
Constructor.
Definition: TypeDesc.h:94
shared_ptr< Value > ValuePtr
A shared pointer to a Value.
Definition: Value.h:30
bool isArray() const
Return true if the type is an array type.
Definition: TypeDesc.h:129
Definition: format.h:1821
bool isFloat4() const
Return true if the type is an aggregate of 4 floats.
Definition: TypeDesc.h:138