source: trunk/nv/types.hh @ 262

Last change on this file since 262 was 262, checked in by epyon, 11 years ago
  • major decoupling lua system independent of nv::object nv::object support for lua opt-in lua system independent of types.hh
File size: 5.5 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 <nv/common.hh>
9#include <nv/math.hh>
10#include <nv/object.hh>
11#include <nv/type_traits.hh>
12#include <typeinfo>
13#include <typeindex>
14#include <utility>
15#include <unordered_map>
16#include <vector>
17#include <string>
18#include <cstddef>
19
20namespace nv
21{
22
23        struct type_entry;
24        class type_database;
25
26        enum type_flag
27        {
28                TF_POINTER      = 0x01, //!< field is a pointer
29                TF_NOSERIALIZE  = 0x02, //!< ignore during serialization
30                TF_INVISIBLE    = 0x04, //!< field invisible to API
31                TF_READONLY     = 0x08, //!< read only field
32                TF_SIMPLETYPE   = 0x10, //!< raw binary I/O possible
33                TF_OWNED        = 0x20,
34                TF_CONTAINER    = 0x40, //!< is a container
35        };
36
37        struct type_field
38        {
39                std::string      name;          //!< name of the field
40                std::string      type_name;     //!< name of the type of the field
41                const std::type_info* type_inf; //!< typeinfo for later retrieval of type
42                type_entry*      type;          //!< pointer to field type
43                unsigned int     flags;         //!< flags
44                size_t           offset;
45
46                template< typename TOBJECT, typename TFIELD >
47                type_field( const char* aname, TFIELD TOBJECT::*field, typename std::enable_if< is_container<TFIELD>::value, void* >::type = nullptr )
48                : name(aname)
49                        , type_name()
50                        , type_inf( &typeid( typename std::remove_pointer<typename TFIELD::value_type>::type ) )
51                        , type( nullptr )
52                        , flags( 0 )
53                        , offset( offset_of( field ) )
54                {
55                        NV_LOG( LOG_INFO, aname << "-" << offset);
56                        flags = TF_CONTAINER |
57                                ( std::is_pointer<typename TFIELD::value_type>::value ? TF_POINTER : 0 ) |
58                                ( std::is_pod<typename TFIELD::value_type>::value ? TF_SIMPLETYPE : 0 );
59                }
60
61                template< typename TOBJECT, typename TFIELD >
62                type_field( const char* aname, TFIELD TOBJECT::*field, typename std::enable_if< !is_container<TFIELD>::value, void* >::type = nullptr )
63                : name(aname)
64                        , type_name()
65                        , type_inf( &typeid( typename std::remove_pointer<TFIELD>::type ) )
66                        , type( nullptr )
67                        , flags( 0 )
68                        , offset( offset_of( field ) )
69                {
70                        NV_LOG( LOG_INFO, aname << "-" << offset);
71                        flags =
72                                ( std::is_pointer<TFIELD>::value ? TF_POINTER : 0 ) |
73                                ( std::is_pod<TFIELD>::value ? TF_SIMPLETYPE : 0 );
74                }
75
76                type_field& flag( unsigned int f )
77                {
78                        flags |= f;
79                        return *this;
80                }
81        };
82
83        struct type_enum
84        {
85                std::string name;
86                int         value;
87                type_enum( const char* aname, int avalue ) : name(aname), value(avalue) {}
88        };
89
90        struct type_entry
91        {
92                // Function types for the constructor and destructor of registered types
93                typedef void (*constructor_func)(void*);
94                typedef void (*destructor_func)(void*);
95
96                // Parent type database
97                type_database* type_db;
98
99                // Scoped C++ name of the type
100                std::string name;
101
102                // Pointers to the constructor and destructor functions
103                constructor_func constructor;
104                destructor_func  destructor;
105
106                // Result of sizeof(type) operation
107                size_t size;
108
109                // Base type
110                type_entry* base_type;
111
112                // Field list
113                std::vector<type_field> field_list;
114
115                // Enum list
116                std::vector<type_enum> enum_list;
117
118                template <typename TYPE>
119                type_entry& base();
120
121                template <int SIZE>
122                type_entry& fields( type_field (&init_fields)[SIZE] );
123
124                template <int SIZE>
125                type_entry& enums( type_enum (&init_enums)[SIZE] )
126                {
127                        for (int i = 0; i < SIZE; i++)
128                        {
129                                enum_list.push_back( init_enums[i] );
130                        }
131                        return *this;
132                }
133        };
134
135        class type_database
136        {
137        public:
138                template< typename TYPE >
139                type_entry& create_type( const char* name )
140                {
141                        type_entry* i_type = nullptr;
142                        type_name_map::iterator it = m_name_types.find( name );
143                        if ( it != m_name_types.end() )
144                        {
145                                return *(it->second);
146                        }
147                        i_type          = new type_entry;
148                        i_type->type_db = this;
149                        i_type->name    = name;
150                        i_type->size    = sizeof(TYPE);
151
152                        i_type->constructor = construct_object<TYPE>;
153                        i_type->destructor  = destroy_object<TYPE>;
154
155                        m_name_types[name]        = i_type;
156                        m_idx_types[typeid(TYPE)] = i_type;
157                        return *i_type;
158                }
159
160                type_entry* get_type( const std::string name )
161                {
162                        type_name_map::iterator it = m_name_types.find( name );
163                        if ( it != m_name_types.end() )
164                        {
165                                return it->second;
166                        }
167                        return nullptr;
168                }
169
170                type_entry* get_type( const std::type_info& t )
171                {
172                        type_info_map::iterator it = m_idx_types.find( std::type_index(t) );
173                        if ( it != m_idx_types.end() )
174                        {
175                                return it->second;
176                        }
177                        return nullptr;
178                }
179        private:
180                struct compare_type_info {
181                        bool operator ()(const std::type_info* a, const std::type_info* b) const {
182                                return a->before(*b);
183                        }
184                };
185
186                typedef std::unordered_map<std::string, type_entry*>     type_name_map;
187                typedef std::unordered_map<std::type_index, type_entry*> type_info_map;
188                type_name_map m_name_types;
189                type_info_map m_idx_types;
190        };
191   
192    template < typename TYPE >
193    type_entry& type_entry::base()
194    {
195        base_type = type_db->get_type( typeid(TYPE) );
196                return *this;
197    }
198   
199    template <int SIZE>
200    type_entry& type_entry::fields( type_field (&init_fields)[SIZE] )
201    {
202        for (int i = 0; i < SIZE; i++)
203        {
204            type_field f = init_fields[i];
205            f.type = type_db->get_type(*(f.type_inf));
206            f.type_name = f.type->name;
207            field_list.push_back(f);
208        }
209        return *this;
210    }
211
212}
213
214#endif
215
Note: See TracBrowser for help on using the repository browser.