diff --git a/stepmania/src/EnumHelper.cpp b/stepmania/src/EnumHelper.cpp index d0913d4769..4ac479ab9d 100644 --- a/stepmania/src/EnumHelper.cpp +++ b/stepmania/src/EnumHelper.cpp @@ -63,6 +63,67 @@ const RString &EnumToString( int iVal, int iMax, const char **szNameArray, auto_ return *pNameCache[iVal]; } +namespace +{ + int GetName( lua_State *L ) + { + luaL_checktype( L, 1, LUA_TTABLE ); + + /* Look up the reverse table. */ + luaL_getmetafield( L, 1, "name" ); + + /* If there was no metafield, then we were called on the wrong type. */ + if( lua_isnil(L, -1) ) + luaL_typerror( L, 1, "enum" ); + + return 1; + } + + int Reverse( lua_State *L ) + { + luaL_checktype( L, 1, LUA_TTABLE ); + + /* Look up the reverse table. */ + luaL_getmetafield( L, 1, "reverse" ); + + /* If there was no metafield, then we were called on the wrong type. */ + if( lua_isnil(L, -1) ) + luaL_typerror( L, 1, "enum" ); + + return 1; + } +} + +static const luaL_Reg EnumLib[] = { + { "GetName", GetName }, + { "Reverse", Reverse }, + { NULL, NULL } +}; + +static void PushEnumMethodTable( lua_State *L ) +{ + luaL_register( L, "Enum", EnumLib ); +} + +void Enum::SetMetatable( lua_State *L, LuaReference &EnumTable, LuaReference &EnumIndexTable, const char *szName ) +{ + /* Create the EnumToString table: { "UnlockEntry_ArcadePoints", "UnlockEntry_DancePoints" } */ \ + EnumTable.PushSelf( L ); + { + lua_newtable( L ); + EnumIndexTable.PushSelf( L ); + lua_setfield( L, -2, "reverse" ); + + lua_pushstring( L, szName ); + lua_setfield( L, -2, "name" ); + + PushEnumMethodTable( L ); + lua_setfield( L, -2, "__index" ); + } + lua_setmetatable( L, -2 ); + lua_pop( L, 1 ); +} + /* * (c) 2006 Glenn Maynard * All rights reserved. diff --git a/stepmania/src/EnumHelper.h b/stepmania/src/EnumHelper.h index 72ab3cbfba..dea1c65659 100644 --- a/stepmania/src/EnumHelper.h +++ b/stepmania/src/EnumHelper.h @@ -86,6 +86,8 @@ namespace Enum lua_rawgeti( L, -1, iVal + 1 ); lua_remove( L, -2 ); } + + void SetMetatable( lua_State *L, LuaReference &EnumTable, LuaReference &EnumIndexTable, const char *szName ); }; const RString &EnumToString( int iVal, int iMax, const char **szNameArray, auto_ptr *pNameCache ); // XToString helper @@ -156,6 +158,7 @@ static void Lua##X(lua_State* L) \ EnumTraits::StringToEnum.SetFromStack( L ); \ EnumTraits::StringToEnum.PushSelf( L ); \ lua_setglobal( L, #X "Index" ); \ + Enum::SetMetatable( L, EnumTraits::EnumToString, EnumTraits::StringToEnum, #X ); \ } \ REGISTER_WITH_LUA_FUNCTION( Lua##X ); \ template<> X EnumTraits::Invalid = enum_add2( NUM_##X, 1 ); \