source: trunk/nv/types.hh @ 61

Last change on this file since 61 was 61, checked in by melon, 12 years ago

Modified LUA script to support Linux

Modified types.hh, still the header gives errors

Modified function in object.hh. By standarts, the typename is not needed

File size: 11.3 KB
Line 
1// Copyright (C) 2012 Kornel Kisielewicz
2// This file is part of NV Libraries.
3// For conditions of distribution and use, see copyright notice in nv.hh
4
5#ifndef NV_TYPES_HH
6#define NV_TYPES_HH
7
8#include <glm/glm.hpp>
9#include <nv/common.hh>
10#include <nv/object.hh>
11#include <type_traits>
12#include <utility>
13#include <unordered_map>
14#include <vector>
15#include <string>
16
17#define NV_REGISTER_NAME( s ) template <> inline const char* nv::get_type_name<s>   () { return #s; }
18
19namespace nv
20{
21
22        enum type
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        };
41
42        typedef glm::vec2 vec2;
43        typedef glm::vec3 vec3;
44        typedef glm::vec4 vec4;
45
46        typedef glm::ivec2 ivec2;
47        typedef glm::ivec3 ivec3;
48        typedef glm::ivec4 ivec4;
49
50        typedef glm::mat2 mat2;
51        typedef glm::mat3 mat3;
52        typedef glm::mat4 mat4;
53
54        template < type EnumType > struct enum_to_type {};
55
56        template <> struct enum_to_type< INT >   { typedef int type; };
57        template <> struct enum_to_type< UINT >  { typedef unsigned int type; };
58        template <> struct enum_to_type< SHORT > { typedef short type; };
59        template <> struct enum_to_type< USHORT >{ typedef unsigned short type; };
60        template <> struct enum_to_type< BYTE >  { typedef char type; };
61        template <> struct enum_to_type< UBYTE > { typedef unsigned char type; };
62        template <> struct enum_to_type< FLOAT > { typedef f32 type; };
63
64        template <> struct enum_to_type< FLOAT_VECTOR_2 > { typedef vec2 type; };
65        template <> struct enum_to_type< FLOAT_VECTOR_3 > { typedef vec3 type; };
66        template <> struct enum_to_type< FLOAT_VECTOR_4 > { typedef vec4 type; };
67
68        template <> struct enum_to_type< INT_VECTOR_2 > { typedef ivec2 type; };
69        template <> struct enum_to_type< INT_VECTOR_3 > { typedef ivec3 type; };
70        template <> struct enum_to_type< INT_VECTOR_4 > { typedef ivec4 type; };
71
72        template <> struct enum_to_type< FLOAT_MATRIX_2 > { typedef mat2 type; };
73        template <> struct enum_to_type< FLOAT_MATRIX_3 > { typedef mat3 type; };
74        template <> struct enum_to_type< FLOAT_MATRIX_4 > { typedef mat4 type; };
75
76        template < typename TYPE > struct type_to_enum {};
77
78        template <> struct type_to_enum< int >           { static const type type = INT; };
79        template <> struct type_to_enum< unsigned int >  { static const type type = UINT; };
80        template <> struct type_to_enum< short >         { static const type type = SHORT; };
81        template <> struct type_to_enum< unsigned short >{ static const type type = USHORT; };
82        template <> struct type_to_enum< char >          { static const type type = BYTE; };
83        template <> struct type_to_enum< unsigned char > { static const type type = UBYTE; };
84        template <> struct type_to_enum< f32 > { static const type type = FLOAT; };
85
86        template <> struct type_to_enum< vec2 > { static const type type = FLOAT_VECTOR_2; };
87        template <> struct type_to_enum< vec3 > { static const type type = FLOAT_VECTOR_3; };
88        template <> struct type_to_enum< vec4 > { static const type type = FLOAT_VECTOR_4; };
89
90        template <> struct type_to_enum< ivec2 > { static const type type = INT_VECTOR_2; };
91        template <> struct type_to_enum< ivec3 > { static const type type = INT_VECTOR_3; };
92        template <> struct type_to_enum< ivec4 > { static const type type = INT_VECTOR_4; };
93
94        template <> struct type_to_enum< mat2 > { static const type type = FLOAT_MATRIX_2; };
95        template <> struct type_to_enum< mat3 > { static const type type = FLOAT_MATRIX_3; };
96        template <> struct type_to_enum< mat4 > { static const type type = FLOAT_MATRIX_4; };
97
98        template <typename TYPE>
99    inline const char* get_type_name()
100    {
101        static_assert( false, "Type not implemented!" );
102    }
103
104        template <> inline const char* get_type_name<int>   () { return "sint"; }
105    template <> inline const char* get_type_name<sint8> () { return "sint8"; }
106    template <> inline const char* get_type_name<sint16>() { return "sint16"; }
107    template <> inline const char* get_type_name<sint32>() { return "sint32"; }
108    template <> inline const char* get_type_name<sint64>() { return "sint64"; }
109
110        template <> inline const char* get_type_name<unsigned int>() { return "uint"; }
111        template <> inline const char* get_type_name<uint8> ()       { return "uint8"; }
112    template <> inline const char* get_type_name<uint16>()       { return "uint16"; }
113    template <> inline const char* get_type_name<uint32>()       { return "uint32"; }
114    template <> inline const char* get_type_name<uint64>()       { return "uint64"; }
115
116        template <> inline const char* get_type_name<f32> () { return "f32"; }
117        template <> inline const char* get_type_name<f64> () { return "f64"; }
118
119        template <> inline const char* get_type_name< vec2 > () { return "vec2"; }
120        template <> inline const char* get_type_name< vec3 > () { return "vec3"; }
121        template <> inline const char* get_type_name< vec4 > () { return "vec4"; }
122
123        template <> inline const char* get_type_name< ivec2 > () { return "ivec2"; }
124        template <> inline const char* get_type_name< ivec3 > () { return "ivec3"; }
125        template <> inline const char* get_type_name< ivec4 > () { return "ivec4"; }
126
127        template <> inline const char* get_type_name< mat2 > () { return "mat2"; }
128        template <> inline const char* get_type_name< mat3 > () { return "mat3"; }
129        template <> inline const char* get_type_name< mat4 > () { return "mat4"; }
130
131        template <> inline const char* get_type_name<bool> () { return "bool"; }
132
133        template <> inline const char* get_type_name<std::string> () { return "string"; }
134        template <> inline const char* get_type_name<object>      () { return "object"; }
135
136        template<typename T>
137        struct is_container
138        {
139        private:
140                typedef char                      yes;
141                typedef struct { char array[2]; } no;
142                template<typename C> static yes test(typename C::iterator*);
143                template<typename C> static no  test(...);
144        public:
145                static const bool value = sizeof(test<T>(0)) == sizeof(yes);
146        };
147
148        template<>
149        struct is_container< std::string > {
150                static const bool value = false;
151        };
152
153
154        template <typename TYPE>
155    std::size_t get_type_id()
156    {
157        static std::size_t type_id = std::hash<std::string>()(std::string(get_type_name<TYPE>()));
158        return type_id;
159    };
160
161        struct hash_string
162    {
163        std::size_t hash;
164        const char* text;
165                hash_string() {}
166                hash_string( const char* a_text ) :
167                        text( a_text )
168                {
169                        hash = std::hash<std::string>()( std::string( a_text ) );
170                }
171                inline bool operator == (const hash_string& hs ) const
172                {
173                        return hs.hash == hash;
174                }
175    };
176
177}
178
179namespace std {
180        template<>
181        struct hash<nv::hash_string> {
182                size_t operator()(const nv::hash_string &hs) const
183                {
184                        return hs.hash;
185                }
186        };
187}
188
189namespace nv
190{
191        struct type_entry;
192
193        enum type_flag
194        {
195                TF_POINTER      = 0x01, //< field is a pointer
196                TF_NOSERIALIZE  = 0x02, //< ignore during serialization
197                TF_INVISIBLE    = 0x04, //< field invisible to API
198                TF_READONLY     = 0x08, //< read only field
199                TF_SIMPLETYPE   = 0x10, //< raw binary I/O possible
200                TF_OWNED        = 0x20,
201                TF_CONTAINER    = 0x40, //< is a container
202        };
203
204        struct type_field
205        {
206                hash_string  name;      //< name of the field
207                hash_string  type_name; //< name of the type of the field
208                type_entry*  type;      //< pointer to field type
209                unsigned int flags;     //< flags
210                size_t       offset;
211
212                template< typename TOBJECT, typename TFIELD >
213                type_field( hash_string name, TFIELD TOBJECT::*field, typename std::enable_if< is_container<TFIELD>::value, void* >::type = nullptr )
214                        : name(name)
215                        , type_name( get_type_name< std::remove_pointer<TFIELD::value_type>::type >() )
216                        , type( nullptr )
217                        , flags( 0 )
218                        , offset( offsetof( TOBJECT, *field ) )
219                        // NOTE: if offsetof behaves badly, check offset_of in common.hh
220                {
221                        flags = TF_CONTAINER |
222                                ( std::is_pointer<TFIELD::value_type>::value ? TF_POINTER : 0 ) |
223                                ( std::is_pod<TFIELD::value_type>::value ? TF_SIMPLETYPE : 0 );
224                }
225
226                template< typename TOBJECT, typename TFIELD >
227                type_field( hash_string name, TFIELD TOBJECT::*field, typename std::enable_if< !is_container<TFIELD>::value, void* >::type = nullptr )
228                        : name(name)
229                        , type_name( get_type_name< std::remove_pointer<TFIELD>::type >() )
230                        , type( nullptr )
231                        , flags( 0 )
232                        , offset( offsetof( TOBJECT, *field ) )
233                        // NOTE: if offsetof behaves badly, check offset_of in common.hh
234                {
235                        flags =
236                                ( std::is_pointer<TFIELD>::value ? TF_POINTER : 0 ) |
237                                ( std::is_pod<TFIELD>::value ? TF_SIMPLETYPE : 0 );
238                }
239
240                type_field& flag( unsigned int f )
241                {
242                        flags |= f;
243                        return *this;
244                }
245        };
246
247        struct type_enum
248        {
249                hash_string name;
250                int         value;
251                type_enum( hash_string name, int value ) : name(name), value(value) {}
252        };
253
254    struct type_entry
255    {
256                 // Function types for the constructor and destructor of registered types
257            typedef void (*constructor_func)(void*);
258            typedef void (*destructor_func)(void*);
259
260                // Parent type database
261        class type_database* type_db;
262
263        // Scoped C++ name of the type
264        hash_string name;
265 
266        // Pointers to the constructor and destructor functions
267        constructor_func constructor;
268        destructor_func  destructor;
269 
270        // Result of sizeof(type) operation
271        size_t size;
272
273                // Base type
274                type_entry* base_type;
275
276                // Field list
277                std::vector<type_field> field_list;
278
279                // Enum list
280                std::vector<type_enum> enum_list;
281
282                template <int TYPE>
283                type_entry& base()
284                {
285                        base_type = type_db->get_type( get_type_name<TYPE>() )
286                }
287
288                template <int SIZE>
289                type_entry& fields( type_field (&init_fields)[SIZE] )
290                {
291                        for (int i = 0; i < SIZE; i++)
292                        {
293                                type_field f = init_fields[i];
294                                f.type = type_db->get_type(f.type_name);
295                                field_list.push_back(f);
296                        }
297                        return *this;
298                }
299
300                template <int SIZE>
301                type_entry& enums( type_enum (&init_enums)[SIZE] )
302                {
303                        for (int i = 0; i < SIZE; i++)
304                        {
305                                enum_list.push_back( init_enums[i] )
306                        }
307                        return *this;
308                }
309    };
310
311    class type_database
312    {
313    public:
314                template< typename TYPE >
315        type_entry& create_type()
316                {
317                        hash_string name( get_type_name<TYPE>() );
318                        type_entry* i_type = nullptr;
319                        type_map::iterator it = m_types.find( name );
320                        if ( it != m_types.end() )
321                        {
322                                return *(it->second);
323                        }
324                        i_type          = new type_entry;
325                        i_type->type_db = this;
326                        i_type->name    = name;
327                        i_type->size    = sizeof(TYPE);
328                       
329                        i_type->constructor = ConstructObject<TYPE>;
330                        i_type->destructor  = DestructObject<TYPE>;
331
332                        m_types[name] = i_type;
333                        return *i_type;
334                }
335
336        type_entry* get_type( hash_string name )
337                {
338                        type_map::iterator it = m_types.find( name );
339                        if ( it != m_types.end() )
340                        {
341                                return it->second;
342                        }
343                        return nullptr;
344                }
345    private:
346        typedef std::unordered_map<hash_string, type_entry*> type_map;
347        type_map m_types;
348        };
349
350        template <typename TYPE> void ConstructObject(void* object)
351    {
352        // Use placement new to call the constructor
353        new (object) TYPE;
354    }
355    template <typename TYPE> void DestructObject(void* object)
356    {
357        // Explicit call of the destructor
358        ((TYPE*)object)->TYPE::~TYPE();
359    }
360
361}
362
363#endif
364
Note: See TracBrowser for help on using the repository browser.