Index: trunk/src/lua/lua_state.cc
===================================================================
--- trunk/src/lua/lua_state.cc	(revision 490)
+++ trunk/src/lua/lua_state.cc	(revision 503)
@@ -9,4 +9,5 @@
 #include "nv/lua/lua_raw.hh"
 #include "nv/lua/lua_nova.hh"
+#include "nv/lua/lua_types.hh"
 #include "nv/core/logging.hh"
 #include "nv/stl/string.hh"
@@ -143,5 +144,5 @@
 
 lua::table_guard::table_guard( lua::state* lstate, const path& p, bool global )
-	: state_wrapper( lstate->get_raw(), false ), m_level(0)
+	: state_wrapper( lstate->get_raw(), lstate->m_lua_types, false ), m_parent( lstate ), m_level(0)
 {
 	m_global = false;
@@ -155,5 +156,5 @@
 
 lua::table_guard::table_guard( const table_guard& parent, const path& p )
-	: state_wrapper( parent.m_state, false ), m_level(0)
+	: state_wrapper( parent.m_state, parent.m_lua_types, false ), m_parent( parent.m_parent ), m_level(0)
 {
 	m_global = false;
@@ -350,12 +351,32 @@
 
 
+bool nv::lua::table_guard::read( const string_view& element, const type_entry* entry, void* object )
+{
+	NV_ASSERT_ALWAYS( m_lua_types->get_type_database() == entry->type_db, "Type database mismatch between Lua and entry!" );
+	lua_getfield( m_state, -1, element.data() );
+	if ( lua_type( m_state, -1 ) != LUA_TTABLE )
+	{
+		lua_pop( m_state, 1 );
+		return false;
+	}
+	if ( !nv::lua::read_rtti_type( m_parent, entry, object, -1 ) )
+	{
+		lua_pop( m_state, 1 );
+		return false;
+	}
+	lua_pop( m_state, 1 );
+	return true;
+}
+
 // state
 
-lua::state::state( lua_State* state ) : state_wrapper( state, false )
-{
-
-}
-
-lua::state::state( bool load_libs /*= false*/ ) : state_wrapper( nullptr, true )
+lua::state::state( lua_State* state, type_database* types )
+	: state_wrapper( state, new type_data( types ), false )
+{
+
+}
+
+lua::state::state( bool load_libs /*= false*/, type_database* types )
+	: state_wrapper( nullptr, new type_data( types ), true )
 {
 	load_lua_library();
@@ -575,4 +596,9 @@
 }
 
+void nv::lua::state::register_rtti_type( thash64 tid, lua_rtti_push_function p, lua_rtti_read_function r )
+{
+	m_lua_types->insert( tid, p, r );
+}
+
 nv::lua::ref nv::lua::state::register_handle_component_impl( string_view id, bool empty )
 {
@@ -626,2 +652,103 @@
 }
 
+nv::lua::state::~state()
+{
+	delete m_lua_types;
+	m_lua_types = nullptr;
+}
+
+template < typename T >
+void nlua_rtti_signed_push( nv::lua::state* state, const type_entry*, void* object )
+{
+	T* value = reinterpret_cast<T*>( object );
+	lua_pushinteger( state->get_raw(), lua_Integer( *value ) );
+}
+
+template < typename T >
+void nlua_rtti_unsigned_push( nv::lua::state* state, const type_entry*, void* object )
+{
+	T* value = reinterpret_cast<T*>( object );
+	lua_pushinteger( state->get_raw(), lua_Unsigned( *value ) );
+}
+
+template < typename T >
+void nlua_rtti_floating_push( nv::lua::state* state, const type_entry*, void* object )
+{
+	T* value = reinterpret_cast< T* >( object );
+	lua_pushnumber( state->get_raw(), lua_Number( *value ) );
+}
+
+static void nlua_rtti_boolean_push( nv::lua::state* state, const type_entry*, void* object )
+{
+	bool* value = reinterpret_cast<bool*>( object );
+	lua_pushboolean( state->get_raw(), *value );
+}
+
+template < typename T >
+bool nlua_rtti_signed_read( nv::lua::state* state, const type_entry*, void* object, int index )
+{
+	T* value = reinterpret_cast<T*>( object );
+	if ( lua_type( state->get_raw(), index ) == LUA_TNUMBER )
+	{
+		*value = T( lua_tointeger( state->get_raw(), index ) );
+		return true;
+	}
+	return false;
+}
+
+template < typename T >
+bool nlua_rtti_unsigned_read( nv::lua::state* state, const type_entry*, void* object, int index )
+{
+	T* value = reinterpret_cast<T*>( object );
+	if ( lua_type( state->get_raw(), index ) == LUA_TNUMBER )
+	{
+		*value = T( lua_tointeger( state->get_raw(), index ) );
+		return true;
+	}
+	return false;
+}
+
+template < typename T >
+bool nlua_rtti_floating_read( nv::lua::state* state, const type_entry*, void* object, int index )
+{
+	T* value = reinterpret_cast<T*>( object );
+	if ( lua_type( state->get_raw(), index ) == LUA_TNUMBER )
+	{
+		*value = T( lua_tonumber( state->get_raw(), index ) );
+		return true;
+	}
+	return false;
+}
+
+static bool nlua_rtti_boolean_read( nv::lua::state* state, const type_entry*, void* object, int index )
+{
+	bool* value = reinterpret_cast<bool*>( object );
+	if ( lua_type( state->get_raw(), index ) == LUA_TBOOLEAN )
+	{
+		*value = bool( lua_toboolean( state->get_raw(), index ) );
+		return true;
+	}
+	return false;
+}
+
+
+void nv::lua::type_data::insert( thash64 tid, lua_rtti_push_function p, lua_rtti_read_function r )
+{
+	m_type_read.assign( tid, r );
+	m_type_push.assign( tid, p );
+}
+
+void nv::lua::type_data::register_standard_types()
+{
+	insert<bool>( nlua_rtti_boolean_push, nlua_rtti_boolean_read );
+	insert<nv::sint8> ( nlua_rtti_signed_push<nv::sint8>,    nlua_rtti_signed_read<nv::sint8> );
+	insert<nv::sint16>( nlua_rtti_signed_push<nv::sint16>,   nlua_rtti_signed_read<nv::sint16> );
+	insert<nv::sint32>( nlua_rtti_signed_push<nv::sint32>,   nlua_rtti_signed_read<nv::sint32> );
+	insert<nv::uint8> ( nlua_rtti_unsigned_push<nv::uint8>,  nlua_rtti_unsigned_read<nv::uint8> );
+	insert<nv::uint16>( nlua_rtti_unsigned_push<nv::uint16>, nlua_rtti_unsigned_read<nv::uint16> );
+	insert<nv::uint32>( nlua_rtti_unsigned_push<nv::uint32>, nlua_rtti_unsigned_read<nv::uint32> );
+	insert<nv::f32>   ( nlua_rtti_floating_push<nv::f32>,    nlua_rtti_floating_read<nv::f32> );
+	insert<nv::f64>   ( nlua_rtti_floating_push<nv::f64>,    nlua_rtti_floating_read<nv::f64> );
+//	insert<nv::sint64>( nlua_rtti_floating_push<nv::sint64>, nlua_rtti_floating_read<nv::sint64> );
+//	insert<nv::uint64>( nlua_rtti_floating_push<nv::uint64>, nlua_rtti_floating_read<nv::uint64> );
+}
