source: trunk/src/lua/lua_types.cc

Last change on this file was 534, checked in by epyon, 8 years ago

CONTINUED:

  • getting rid of size_t
  • datatypes now restricted to uint32 size
  • 64-bit compatibility
  • copyright updates where modified
File size: 5.6 KB
Line 
1// Copyright (C) 2016-2017 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7#include "nv/lua/lua_types.hh"
8
9#include "nv/lua/lua_raw.hh"
10
11using namespace nv;
12
13bool nv::lua::read_rtti_type( lua::state* state, const type_entry* entry, void* object, int index )
14{
15        const lua::type_data* td = state->get_type_data();
16        const type_database*  db = td->get_type_database();
17        NV_ASSERT_ALWAYS( db == entry->type_db, "Type database mismatch between Lua and entry!" );
18
19        const lua::lua_rtti_read_function* read = td->get_read( entry->hash );
20        if ( read )
21        {
22                return (*read)( state, entry, object, index );
23        }
24
25        lua_State* lstate = state->get_raw();
26        int ltype = lua_type( lstate, index );
27        index = nlua_absindex( lstate, index );
28        int fcount = int( entry->field_list.size() );
29
30        if ( fcount > 0 && ltype == LUA_TTABLE )
31        {
32                // numerical assignment
33                if ( lua_objlen( lstate, index ) > 0 )
34                {
35                        int i = 0;
36                        for (;;)
37                        {
38                                i++;
39                                lua_rawgeti( lstate, index, i );
40                                if ( lua_isnil( lstate, -1 ) || i > fcount )
41                                {
42                                        lua_pop( lstate, 1 );
43                                        break;
44                                }
45                                const type_field& f = entry->field_list[i - 1];
46                                read_rtti_type( state, f.type, (char*)object + f.offset, -1 );
47                                lua_pop( lstate, 1 );
48                        };
49
50                }
51
52                // by name assignment
53                lua_pushnil( lstate );
54                while ( lua_next( lstate, index ) != 0 )
55                {
56                        if ( lua_type( lstate, -2 ) == LUA_TSTRING )
57                        {
58                                string_view key = nlua_tostringview( lstate, -2 );
59                                auto fit = entry->field_names.find(key);
60                                if ( fit != entry->field_names.end() )
61                                {
62                                        const type_field& f = entry->field_list[ fit->second ];
63                                        read_rtti_type( state, f.type, (char*)object + f.offset, -1 );
64                                }
65                        }
66                        lua_pop( lstate, 1 );
67                }
68                return true;
69        }
70        int ecount = int( entry->enum_list.size() );
71        if ( ecount > 0 )
72        {
73                if ( ltype == LUA_TSTRING )
74                {
75                        string_view key = nlua_tostringview( lstate, index );
76                        auto eit = entry->enum_names.find( key );
77                        if ( eit != entry->enum_names.end() )
78                        {
79                                int error; // proper type instead of sint32?
80                                *(sint32*)object = entry->enum_list[eit->second].value;
81                                return true;
82                        }
83                }
84                if ( ltype == LUA_TNUMBER )
85                {
86                        int error; // proper type instead of sint32?
87                        *(sint32*)object = (sint32)lua_tointeger( lstate, index );
88                        return true;
89                }
90        }
91        return false;
92}
93
94static void nlua_rtti_proxy_push_field( lua_State * L, void* object, type_field& f )
95{
96        //throw std::logic_error( "The method or operation is not implemented." );
97}
98
99static void nlua_rtti_proxy_set_field( lua_State * L, void* object, type_field& f, int index )
100{
101        //throw std::logic_error( "The method or operation is not implemented." );
102}
103
104static int nlua_rtti_proxy_index( lua_State * L )
105{
106        type_entry* entry  = reinterpret_cast<type_entry*>( lua_touserdata( L, lua_upvalueindex( 1 ) ) );
107        void*       object = lua_touserdata( L, lua_upvalueindex( 2 ) );
108        nv::string_view index = nlua_tostringview( L, 2 );
109        auto f = entry->field_names.find( index );
110        if ( f != entry->field_names.end() )
111        {
112                nlua_rtti_proxy_push_field( L, object, entry->field_list[ f->second ] );
113        }
114        else
115        {
116                int error;
117                lua_pushnil( L );
118        }
119        return 1;
120}
121
122static int nlua_rtti_proxy_newindex( lua_State * L )
123{
124        type_entry* entry = reinterpret_cast<type_entry*>( lua_touserdata( L, lua_upvalueindex( 1 ) ) );
125        void*       object = lua_touserdata( L, lua_upvalueindex( 2 ) );
126        nv::string_view index = nlua_tostringview( L, 2 );
127        auto f = entry->field_names.find( index );
128        if ( f != entry->field_names.end() )
129        {
130                nlua_rtti_proxy_set_field( L, object, entry->field_list[f->second], 3 );
131        }
132        else
133        {
134                int error;
135        }
136        return 1;
137}
138
139/*
140
141static void nlua_push_function( lua_State* L, const type_entry* entry, lua_CFunction f )
142{
143        lua_pushlightuserdata( L, const_cast<type_entry*>( entry ) );
144        lua_pushcclosure( L, f, 1 );
145}
146
147static void nlua_rtti_requiref( lua_State *L, const type_entry* entry, const char *modname, lua_CFunction openf, int glb )
148{
149        int only_works_for_51;
150        nlua_push_function( L, entry, openf );
151        lua_pushstring( L, modname );
152        lua_call( L, 1, 1 );
153        if ( glb != 0 )
154        {
155                lua_pushvalue( L, LUA_GLOBALSINDEX );
156                lua_pushvalue( L, -2 );
157                lua_setfield( L, -2, modname );
158                lua_pop( L, 1 );
159        }
160}
161
162static void nlua_rtti_register( lua_State *L, const type_entry* entry, const luaL_Reg *l )
163{
164        int index = nlua_absindex( L, -1 );
165        for ( ; l->name != NULL; l++ )
166        {
167                lua_pushstring( L, l->name );
168                nlua_push_function( L, entry, l->func );
169                lua_rawset( L, index );
170        }
171}
172
173static int nlua_rtti_open( lua_State *L )
174{
175//      type_entry* entry = reinterpret_cast<type_entry*>( lua_touserdata( L, lua_upvalueindex( 1 ) ) );
176//
177//      luaL_newmetatable( L, entry->type_db->resolve_name( entry ).data() );
178//      nlua_register( L, nlua_vec_m, -1 );
179//      lua_createtable( L, 0, 0 );
180//      nlua_register( L, nlua_vec_f, -1 );
181//      lua_setfield( L, -2, "__functions" );
182//      lua_pop( L, 1 );
183//
184//      lua_createtable( L, 0, 0 );
185//      nlua_register( L, nlua_vec_sf, -1 );
186//      lua_createtable( L, 0, 0 );
187//      nlua_register( L, nlua_vec_sm, -1 );
188//      lua_setmetatable( L, -2 );
189        return 1;
190}
191
192void nv::lua::register_lua_rtti_type( const string_view& name, lua::state* state, const type_entry* entry )
193{
194        const type_database* db = state->get_type_db();
195        NV_ASSERT_ALWAYS( db == entry->type_db, "Type database mismatch between Lua and entry!" );
196        lua_pushlightuserdata( state->get_raw(), const_cast< type_entry* >( entry ) );
197        int lua_ref
198
199
200       
201}
202*/
Note: See TracBrowser for help on using the repository browser.