Changeset 83
- Timestamp:
- 06/02/13 10:10:26 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/types.hh
r82 r83 20 20 namespace nv 21 21 { 22 23 enum datatype 24 { 25 INT, 26 BYTE, 27 SHORT, 28 UINT, 29 UBYTE, 30 USHORT, 31 FLOAT, 32 FLOAT_VECTOR_2, 33 FLOAT_VECTOR_3, 34 FLOAT_VECTOR_4, 35 FLOAT_MATRIX_2, 36 FLOAT_MATRIX_3, 37 FLOAT_MATRIX_4, 38 INT_VECTOR_2, 39 INT_VECTOR_3, 40 INT_VECTOR_4, 41 // unsupported gl conversion, remove? 42 BYTE_VECTOR_2, 43 BYTE_VECTOR_3, 44 BYTE_VECTOR_4, 45 }; 46 47 template <typename T> 48 struct datatype_traits 49 { 50 typedef T type; 51 typedef T base_type; 52 static const size_t size = 1; 53 }; 54 55 template <typename T> 56 struct datatype_traits< glm::detail::tvec2<T> > 57 { 58 typedef glm::detail::tvec2<T> type; 59 typedef typename type::value_type base_type; 60 static const size_t size = 2; 61 }; 62 63 template <typename T> 64 struct datatype_traits< glm::detail::tvec3<T> > 65 { 66 typedef glm::detail::tvec3<T> type; 67 typedef typename type::value_type base_type; 68 static const size_t size = 3; 69 }; 70 71 template <typename T> 72 struct datatype_traits< glm::detail::tvec4<T> > 73 { 74 typedef glm::detail::tvec4<T> type; 75 typedef typename type::value_type base_type; 76 static const size_t size = 4; 77 }; 78 79 typedef glm::detail::tvec2<sint8> i8vec2; 80 typedef glm::detail::tvec3<sint8> i8vec3; 81 typedef glm::detail::tvec4<sint8> i8vec4; 82 83 typedef glm::vec2 vec2; 84 typedef glm::vec3 vec3; 85 typedef glm::vec4 vec4; 86 87 typedef glm::ivec2 ivec2; 88 typedef glm::ivec3 ivec3; 89 typedef glm::ivec4 ivec4; 90 91 typedef glm::mat2 mat2; 92 typedef glm::mat3 mat3; 93 typedef glm::mat4 mat4; 94 95 template < datatype EnumType > struct enum_to_type {}; 96 97 template <> struct enum_to_type< INT > { typedef int type; }; 98 template <> struct enum_to_type< UINT > { typedef unsigned int type; }; 99 template <> struct enum_to_type< SHORT > { typedef short type; }; 100 template <> struct enum_to_type< USHORT >{ typedef unsigned short type; }; 101 template <> struct enum_to_type< BYTE > { typedef char type; }; 102 template <> struct enum_to_type< UBYTE > { typedef unsigned char type; }; 103 template <> struct enum_to_type< FLOAT > { typedef f32 type; }; 104 105 template <> struct enum_to_type< FLOAT_VECTOR_2 > { typedef vec2 type; }; 106 template <> struct enum_to_type< FLOAT_VECTOR_3 > { typedef vec3 type; }; 107 template <> struct enum_to_type< FLOAT_VECTOR_4 > { typedef vec4 type; }; 108 109 template <> struct enum_to_type< INT_VECTOR_2 > { typedef ivec2 type; }; 110 template <> struct enum_to_type< INT_VECTOR_3 > { typedef ivec3 type; }; 111 template <> struct enum_to_type< INT_VECTOR_4 > { typedef ivec4 type; }; 112 113 template <> struct enum_to_type< BYTE_VECTOR_2 > { typedef i8vec2 type; }; 114 template <> struct enum_to_type< BYTE_VECTOR_3 > { typedef i8vec3 type; }; 115 template <> struct enum_to_type< BYTE_VECTOR_4 > { typedef i8vec4 type; }; 116 117 template <> struct enum_to_type< FLOAT_MATRIX_2 > { typedef mat2 type; }; 118 template <> struct enum_to_type< FLOAT_MATRIX_3 > { typedef mat3 type; }; 119 template <> struct enum_to_type< FLOAT_MATRIX_4 > { typedef mat4 type; }; 120 121 template < typename TYPE > struct type_to_enum {}; 122 123 template <> struct type_to_enum< int > { static const datatype type = INT; }; 124 template <> struct type_to_enum< unsigned int > { static const datatype type = UINT; }; 125 template <> struct type_to_enum< short > { static const datatype type = SHORT; }; 126 template <> struct type_to_enum< unsigned short >{ static const datatype type = USHORT; }; 127 template <> struct type_to_enum< char > { static const datatype type = BYTE; }; 128 template <> struct type_to_enum< signed char > { static const datatype type = BYTE; }; 129 template <> struct type_to_enum< unsigned char > { static const datatype type = UBYTE; }; 130 template <> struct type_to_enum< f32 > { static const datatype type = FLOAT; }; 131 132 template <> struct type_to_enum< vec2 > { static const datatype type = FLOAT_VECTOR_2; }; 133 template <> struct type_to_enum< vec3 > { static const datatype type = FLOAT_VECTOR_3; }; 134 template <> struct type_to_enum< vec4 > { static const datatype type = FLOAT_VECTOR_4; }; 135 136 template <> struct type_to_enum< ivec2 > { static const datatype type = INT_VECTOR_2; }; 137 template <> struct type_to_enum< ivec3 > { static const datatype type = INT_VECTOR_3; }; 138 template <> struct type_to_enum< ivec4 > { static const datatype type = INT_VECTOR_4; }; 139 140 template <> struct type_to_enum< i8vec2 > { static const datatype type = BYTE_VECTOR_2; }; 141 template <> struct type_to_enum< i8vec3 > { static const datatype type = BYTE_VECTOR_3; }; 142 template <> struct type_to_enum< i8vec4 > { static const datatype type = BYTE_VECTOR_4; }; 143 144 template <> struct type_to_enum< mat2 > { static const datatype type = FLOAT_MATRIX_2; }; 145 template <> struct type_to_enum< mat3 > { static const datatype type = FLOAT_MATRIX_3; }; 146 template <> struct type_to_enum< mat4 > { static const datatype type = FLOAT_MATRIX_4; }; 147 148 template<typename T> 149 struct is_container 150 { 151 private: 152 typedef char yes; 153 typedef struct { char array[2]; } no; 154 template<typename C> static yes test(typename C::iterator*); 155 template<typename C> static no test(...); 156 public: 157 static const bool value = sizeof(test<T>(0)) == sizeof(yes); 158 }; 159 160 template<> 161 struct is_container< std::string > { 162 static const bool value = false; 163 }; 164 165 struct type_entry; 166 167 enum type_flag 168 { 169 TF_POINTER = 0x01, //< field is a pointer 170 TF_NOSERIALIZE = 0x02, //< ignore during serialization 171 TF_INVISIBLE = 0x04, //< field invisible to API 172 TF_READONLY = 0x08, //< read only field 173 TF_SIMPLETYPE = 0x10, //< raw binary I/O possible 174 TF_OWNED = 0x20, 175 TF_CONTAINER = 0x40, //< is a container 176 }; 177 178 struct type_field 179 { 180 std::string name; //< name of the field 181 std::string type_name; //< name of the type of the field 182 const std::type_info* type_inf; //< typeinfo for later retrieval of type 183 type_entry* type; //< pointer to field type 184 unsigned int flags; //< flags 185 size_t offset; 186 187 template< typename TOBJECT, typename TFIELD > 188 type_field( const char* name, TFIELD TOBJECT::*field, typename std::enable_if< is_container<TFIELD>::value, void* >::type = nullptr ) 189 : name(name) 190 , type_name() 191 , type_inf( &typeid( std::remove_pointer<typename TFIELD::value_type>::type ) ) 192 , type( nullptr ) 193 , flags( 0 ) 194 , offset( offsetof( TOBJECT, *field ) ) 195 // NOTE: if offsetof behaves badly, check offset_of in common.hh 196 { 197 flags = TF_CONTAINER | 198 ( std::is_pointer<TFIELD::value_type>::value ? TF_POINTER : 0 ) | 199 ( std::is_pod<TFIELD::value_type>::value ? TF_SIMPLETYPE : 0 ); 200 } 201 202 template< typename TOBJECT, typename TFIELD > 203 type_field( const char* name, TFIELD TOBJECT::*field, typename std::enable_if< !is_container<TFIELD>::value, void* >::type = nullptr ) 204 : name(name) 205 , type_name() 206 , type_inf( &typeid( std::remove_pointer<TFIELD>::type ) ) 207 , type( nullptr ) 208 , flags( 0 ) 209 , offset( offsetof( TOBJECT, *field ) ) 210 // NOTE: if offsetof behaves badly, check offset_of in common.hh 211 { 212 flags = 213 ( std::is_pointer<TFIELD>::value ? TF_POINTER : 0 ) | 214 ( std::is_pod<TFIELD>::value ? TF_SIMPLETYPE : 0 ); 215 } 216 217 type_field& flag( unsigned int f ) 218 { 219 flags |= f; 220 return *this; 221 } 222 }; 223 224 struct type_enum 225 { 226 std::string name; 227 int value; 228 type_enum( const char* name, int value ) : name(name), value(value) {} 229 }; 22 enum datatype 23 { 24 INT, 25 BYTE, 26 SHORT, 27 UINT, 28 UBYTE, 29 USHORT, 30 FLOAT, 31 FLOAT_VECTOR_2, 32 FLOAT_VECTOR_3, 33 FLOAT_VECTOR_4, 34 FLOAT_MATRIX_2, 35 FLOAT_MATRIX_3, 36 FLOAT_MATRIX_4, 37 INT_VECTOR_2, 38 INT_VECTOR_3, 39 INT_VECTOR_4, 40 // unsupported gl conversion, remove? 41 BYTE_VECTOR_2, 42 BYTE_VECTOR_3, 43 BYTE_VECTOR_4, 44 }; 45 46 template <typename T> 47 struct datatype_traits 48 { 49 typedef T type; 50 typedef T base_type; 51 static const size_t size = 1; 52 }; 53 54 template <typename T> 55 struct datatype_traits< glm::detail::tvec2<T> > 56 { 57 typedef glm::detail::tvec2<T> type; 58 typedef typename type::value_type base_type; 59 static const size_t size = 2; 60 }; 61 62 template <typename T> 63 struct datatype_traits< glm::detail::tvec3<T> > 64 { 65 typedef glm::detail::tvec3<T> type; 66 typedef typename type::value_type base_type; 67 static const size_t size = 3; 68 }; 69 70 template <typename T> 71 struct datatype_traits< glm::detail::tvec4<T> > 72 { 73 typedef glm::detail::tvec4<T> type; 74 typedef typename type::value_type base_type; 75 static const size_t size = 4; 76 }; 77 78 typedef glm::detail::tvec2<sint8> i8vec2; 79 typedef glm::detail::tvec3<sint8> i8vec3; 80 typedef glm::detail::tvec4<sint8> i8vec4; 81 82 typedef glm::vec2 vec2; 83 typedef glm::vec3 vec3; 84 typedef glm::vec4 vec4; 85 86 typedef glm::ivec2 ivec2; 87 typedef glm::ivec3 ivec3; 88 typedef glm::ivec4 ivec4; 89 90 typedef glm::mat2 mat2; 91 typedef glm::mat3 mat3; 92 typedef glm::mat4 mat4; 93 94 template < datatype EnumType > struct enum_to_type {}; 95 96 template <> struct enum_to_type< INT > { typedef int type; }; 97 template <> struct enum_to_type< UINT > { typedef unsigned int type; }; 98 template <> struct enum_to_type< SHORT > { typedef short type; }; 99 template <> struct enum_to_type< USHORT >{ typedef unsigned short type; }; 100 template <> struct enum_to_type< BYTE > { typedef char type; }; 101 template <> struct enum_to_type< UBYTE > { typedef unsigned char type; }; 102 template <> struct enum_to_type< FLOAT > { typedef f32 type; }; 103 104 template <> struct enum_to_type< FLOAT_VECTOR_2 > { typedef vec2 type; }; 105 template <> struct enum_to_type< FLOAT_VECTOR_3 > { typedef vec3 type; }; 106 template <> struct enum_to_type< FLOAT_VECTOR_4 > { typedef vec4 type; }; 107 108 template <> struct enum_to_type< INT_VECTOR_2 > { typedef ivec2 type; }; 109 template <> struct enum_to_type< INT_VECTOR_3 > { typedef ivec3 type; }; 110 template <> struct enum_to_type< INT_VECTOR_4 > { typedef ivec4 type; }; 111 112 template <> struct enum_to_type< BYTE_VECTOR_2 > { typedef i8vec2 type; }; 113 template <> struct enum_to_type< BYTE_VECTOR_3 > { typedef i8vec3 type; }; 114 template <> struct enum_to_type< BYTE_VECTOR_4 > { typedef i8vec4 type; }; 115 116 template <> struct enum_to_type< FLOAT_MATRIX_2 > { typedef mat2 type; }; 117 template <> struct enum_to_type< FLOAT_MATRIX_3 > { typedef mat3 type; }; 118 template <> struct enum_to_type< FLOAT_MATRIX_4 > { typedef mat4 type; }; 119 120 template < typename TYPE > struct type_to_enum {}; 121 122 template <> struct type_to_enum< int > { static const datatype type = INT; }; 123 template <> struct type_to_enum< unsigned int > { static const datatype type = UINT; }; 124 template <> struct type_to_enum< short > { static const datatype type = SHORT; }; 125 template <> struct type_to_enum< unsigned short >{ static const datatype type = USHORT; }; 126 template <> struct type_to_enum< char > { static const datatype type = BYTE; }; 127 template <> struct type_to_enum< signed char > { static const datatype type = BYTE; }; 128 template <> struct type_to_enum< unsigned char > { static const datatype type = UBYTE; }; 129 template <> struct type_to_enum< f32 > { static const datatype type = FLOAT; }; 130 131 template <> struct type_to_enum< vec2 > { static const datatype type = FLOAT_VECTOR_2; }; 132 template <> struct type_to_enum< vec3 > { static const datatype type = FLOAT_VECTOR_3; }; 133 template <> struct type_to_enum< vec4 > { static const datatype type = FLOAT_VECTOR_4; }; 134 135 template <> struct type_to_enum< ivec2 > { static const datatype type = INT_VECTOR_2; }; 136 template <> struct type_to_enum< ivec3 > { static const datatype type = INT_VECTOR_3; }; 137 template <> struct type_to_enum< ivec4 > { static const datatype type = INT_VECTOR_4; }; 138 139 template <> struct type_to_enum< i8vec2 > { static const datatype type = BYTE_VECTOR_2; }; 140 template <> struct type_to_enum< i8vec3 > { static const datatype type = BYTE_VECTOR_3; }; 141 template <> struct type_to_enum< i8vec4 > { static const datatype type = BYTE_VECTOR_4; }; 142 143 template <> struct type_to_enum< mat2 > { static const datatype type = FLOAT_MATRIX_2; }; 144 template <> struct type_to_enum< mat3 > { static const datatype type = FLOAT_MATRIX_3; }; 145 template <> struct type_to_enum< mat4 > { static const datatype type = FLOAT_MATRIX_4; }; 146 147 template<typename T> 148 struct is_container 149 { 150 private: 151 typedef char yes; 152 typedef struct { char array[2]; } no; 153 template<typename C> static yes test(typename C::iterator*); 154 template<typename C> static no test(...); 155 public: 156 static const bool value = sizeof(test<T>(0)) == sizeof(yes); 157 }; 158 159 template<> 160 struct is_container< std::string > { 161 static const bool value = false; 162 }; 163 164 struct type_entry; 165 166 enum type_flag 167 { 168 TF_POINTER = 0x01, //< field is a pointer 169 TF_NOSERIALIZE = 0x02, //< ignore during serialization 170 TF_INVISIBLE = 0x04, //< field invisible to API 171 TF_READONLY = 0x08, //< read only field 172 TF_SIMPLETYPE = 0x10, //< raw binary I/O possible 173 TF_OWNED = 0x20, 174 TF_CONTAINER = 0x40, //< is a container 175 }; 176 177 struct type_field 178 { 179 std::string name; //< name of the field 180 std::string type_name; //< name of the type of the field 181 const std::type_info* type_inf; //< typeinfo for later retrieval of type 182 type_entry* type; //< pointer to field type 183 unsigned int flags; //< flags 184 size_t offset; 185 186 template< typename TOBJECT, typename TFIELD > 187 type_field( const char* name, TFIELD TOBJECT::*field, typename std::enable_if< is_container<TFIELD>::value, void* >::type = nullptr ) 188 : name(name) 189 , type_name() 190 , type_inf( &typeid( std::remove_pointer<typename TFIELD::value_type>::type ) ) 191 , type( nullptr ) 192 , flags( 0 ) 193 , offset( offsetof( TOBJECT, *field ) ) 194 // NOTE: if offsetof behaves badly, check offset_of in common.hh 195 { 196 flags = TF_CONTAINER | 197 ( std::is_pointer<TFIELD::value_type>::value ? TF_POINTER : 0 ) | 198 ( std::is_pod<TFIELD::value_type>::value ? TF_SIMPLETYPE : 0 ); 199 } 200 201 template< typename TOBJECT, typename TFIELD > 202 type_field( const char* name, TFIELD TOBJECT::*field, typename std::enable_if< !is_container<TFIELD>::value, void* >::type = nullptr ) 203 : name(name) 204 , type_name() 205 , type_inf( &typeid( std::remove_pointer<TFIELD>::type ) ) 206 , type( nullptr ) 207 , flags( 0 ) 208 , offset( offsetof( TOBJECT, *field ) ) 209 // NOTE: if offsetof behaves badly, check offset_of in common.hh 210 { 211 flags = 212 ( std::is_pointer<TFIELD>::value ? TF_POINTER : 0 ) | 213 ( std::is_pod<TFIELD>::value ? TF_SIMPLETYPE : 0 ); 214 } 215 216 type_field& flag( unsigned int f ) 217 { 218 flags |= f; 219 return *this; 220 } 221 }; 222 223 struct type_enum 224 { 225 std::string name; 226 int value; 227 type_enum( const char* name, int value ) : name(name), value(value) {} 228 }; 230 229 231 230 struct type_entry … … 240 239 // Scoped C++ name of the type 241 240 std::string name; 242 241 243 242 // Pointers to the constructor and destructor functions 244 243 constructor_func constructor; 245 244 destructor_func destructor; 246 245 247 246 // Result of sizeof(type) operation 248 247 size_t size; … … 258 257 259 258 template <int TYPE> 260 type_entry& base()261 {262 base_type = type_db->get_type( typeid(TYPE) );263 }259 type_entry& base() 260 { 261 base_type = type_db->get_type( typeid(TYPE) ); 262 } 264 263 265 264 template <int SIZE> 266 type_entry& fields( type_field (&init_fields)[SIZE] )267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 }; 288 289 290 265 type_entry& fields( type_field (&init_fields)[SIZE] ) 266 { 267 for (int i = 0; i < SIZE; i++) 268 { 269 type_field f = init_fields[i]; 270 f.type = type_db->get_type(*(f.type_inf)); 271 f.type_name = f.type->name; 272 field_list.push_back(f); 273 } 274 return *this; 275 } 276 277 template <int SIZE> 278 type_entry& enums( type_enum (&init_enums)[SIZE] ) 279 { 280 for (int i = 0; i < SIZE; i++) 281 { 282 enum_list.push_back( init_enums[i] ); 283 } 284 return *this; 285 } 286 }; 287 288 // TODO: we don't need the get_type_name template? Can we just base on typeid now, and 289 // pass type name on creation? 291 290 class type_database 292 291 { 293 public:294 295 type_entry& create_type( const char* name )296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 private:336 337 338 339 340 341 342 typedef std::unordered_map<std::string, type_entry*> type_name_map;343 344 type_name_map m_name_types;345 346 347 348 292 public: 293 template< typename TYPE > 294 type_entry& create_type( const char* name ) 295 { 296 type_entry* i_type = nullptr; 297 type_name_map::iterator it = m_name_types.find( name ); 298 if ( it != m_name_types.end() ) 299 { 300 return *(it->second); 301 } 302 i_type = new type_entry; 303 i_type->type_db = this; 304 i_type->name = name; 305 i_type->size = sizeof(TYPE); 306 307 i_type->constructor = ConstructObject<TYPE>; 308 i_type->destructor = DestructObject<TYPE>; 309 310 m_name_types[name] = i_type; 311 m_idx_types[typeid(TYPE)] = i_type; 312 return *i_type; 313 } 314 315 type_entry* get_type( const std::string name ) 316 { 317 type_name_map::iterator it = m_name_types.find( name ); 318 if ( it != m_name_types.end() ) 319 { 320 return it->second; 321 } 322 return nullptr; 323 } 324 325 type_entry* get_type( const std::type_info& t ) 326 { 327 type_info_map::iterator it = m_idx_types.find( std::type_index(t) ); 328 if ( it != m_idx_types.end() ) 329 { 330 return it->second; 331 } 332 return nullptr; 333 } 334 private: 335 struct compare_type_info { 336 bool operator ()(const std::type_info* a, const std::type_info* b) const { 337 return a->before(*b); 338 } 339 }; 340 341 typedef std::unordered_map<std::string, type_entry*> type_name_map; 342 typedef std::unordered_map<std::type_index, type_entry*> type_info_map; 343 type_name_map m_name_types; 344 type_info_map m_idx_types; 345 }; 346 347 template <typename TYPE> void ConstructObject(void* object) 349 348 { 350 349 // Use placement new to call the constructor
Note: See TracChangeset
for help on using the changeset viewer.