From d160802fc0d8638d27ab706276be1f746e2c9f95 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 29 Sep 2006 21:37:01 +0000 Subject: [PATCH] Streamline type checking. Store a list of all base classes in a heirarchy table, so we don't have to iterate over lots of tables for every function dispatch. --- stepmania/src/LuaBinding.cpp | 82 ++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/stepmania/src/LuaBinding.cpp b/stepmania/src/LuaBinding.cpp index c59f920ef5..2d3927d146 100644 --- a/stepmania/src/LuaBinding.cpp +++ b/stepmania/src/LuaBinding.cpp @@ -101,10 +101,40 @@ void LuaBinding::Register( lua_State *L ) { lua_getfield( L, LUA_GLOBALSINDEX, GetBaseClassName() ); lua_setfield( L, methods_metatable, "__index" ); + + lua_pushstring( L, GetBaseClassName() ); + lua_setfield( L, metatable, "base" ); } lua_pushstring( L, GetClassName() ); - lua_setfield( L, methods_metatable, "type" ); + lua_setfield( L, methods_metatable, "class" ); + + lua_pushstring( L, GetClassName() ); + lua_setfield( L, metatable, "type" ); + + { + lua_newtable( L ); + int iHeirarchyTable = lua_gettop( L ); + + RString sClass = GetClassName(); + int iIndex = 0; + while( !sClass.empty() ) + { + lua_pushstring( L, sClass ); + lua_pushinteger( L, iIndex ); + lua_rawset( L, iHeirarchyTable ); + ++iIndex; + + luaL_getmetatable( L, sClass ); + ASSERT( !lua_isnil(L, -1) ); + lua_getfield( L, -1, "base" ); + + LuaHelpers::FromStack( L, sClass, -1 ); + lua_pop( L, 2 ); + } + + lua_setfield( L, metatable, "heirarchy" ); + } /* Set and pop the methods metatable. */ lua_setmetatable( L, methods ); @@ -196,48 +226,20 @@ bool LuaBinding::CheckLuaObjectType( lua_State *L, int iArg, const char *szType, return true; #endif - ASSERT_M( iArg > 0, ssprintf("%i", iArg) ); // negative offsets not supported - - int iTop = lua_gettop(L); - lua_pushvalue( L, iArg ); - - iArg = lua_gettop(L); - while(1) + /* Check that szType is in metatable.heirarchy. */ + if( !luaL_getmetafield(L, iArg, "heirarchy") ) + return false; + if( !lua_istable(L, -1) ) { - /* If the object on the stack has no metatable, it has no type; fail. */ - if( !lua_getmetatable(L, iArg) ) - { - lua_settop( L, iTop ); - return false; - } - int iMetatable = lua_gettop(L); - - /* Look up the type name. */ - lua_pushstring( L, "type" ); - lua_rawget( L, iMetatable ); - const char *szActualType = lua_tostring( L, -1 ); - - if( szActualType != NULL && !strcmp(szActualType, szType) ) - { - /* The type matches. */ - lua_settop( L, iTop ); - return true; - } - - /* The type doesn't match. Does the metatable have __index? */ - lua_pushstring( L, "__index" ); - lua_rawget( L, iMetatable ); - if( lua_isnil(L, -1) ) - { - /* There's no __index. The type doesn't match. */ - lua_settop( L, iTop ); - return false; - } - - /* Start over with __index. */ - lua_replace( L, iArg ); lua_pop( L, 1 ); + return false; } + + lua_getfield( L, -1, szType ); + bool bRet = !lua_isnil( L, -1 ); + lua_pop( L, 2 ); + + return bRet; } static void GetGlobalTable( Lua *L )