fixes/updates: both tables and userdata can be instances of a class;

binding changes
This commit is contained in:
Glenn Maynard
2006-09-29 21:18:50 +00:00
parent f759525a80
commit 728f2d32b7
+31 -51
View File
@@ -247,19 +247,8 @@ XNode *LuaManager::GetLuaInformation() const
XNode *pEnumsNode = pLuaNode->AppendChild( "Enums" ); XNode *pEnumsNode = pLuaNode->AppendChild( "Enums" );
XNode *pConstantsNode = pLuaNode->AppendChild( "Constants" ); XNode *pConstantsNode = pLuaNode->AppendChild( "Constants" );
vector<RString> vFunctions;
for( const LuaFunctionList *p = g_LuaFunctions; p; p = p->next )
vFunctions.push_back( p->name );
sort( vFunctions.begin(), vFunctions.end() );
FOREACH_CONST( RString, vFunctions, func )
{
XNode *pFunctionNode = pGlobalsNode->AppendChild( "Function" );
pFunctionNode->AppendAttr( "name", *func );
}
// Tricky. We have to get the classes from lua. // Tricky. We have to get the classes from lua.
vector<RString> vFunctions;
map<RString, LClass> mClasses; map<RString, LClass> mClasses;
map<RString, RString> mSingletons; map<RString, RString> mSingletons;
map<RString, float> mConstants; map<RString, float> mConstants;
@@ -302,34 +291,33 @@ XNode *LuaManager::GetLuaInformation() const
lua_pop( L, 2 ); // pop table and key lua_pop( L, 2 ); // pop table and key
break; break;
} }
lua_pop( L, 1 ); // pop metatable
lua_pushliteral( L, "type" ); if( luaL_getmetafield(L, -1, "class") )
lua_rawget( L, -2 ); {
const char *name = lua_tostring( L, -1 ); const char *name = lua_tostring( L, -1 );
if( !name ) if( !name )
{ {
lua_pop( L, 2 ); // pop nil and metatable lua_pop( L, 1 ); // pop nil
break; break;
} }
LClass &c = mClasses[name]; LClass &c = mClasses[name];
lua_pop( L, 1 ); // pop name lua_pop( L, 1 ); // pop name
// Get base class. // Get base class.
lua_pushliteral( L, "__index" ); if( luaL_getmetafield( L, -1, "__index" ) )
lua_rawget( L, -2 ); {
if( lua_istable(L, -1) && lua_getmetatable(L, -1) ) if( luaL_getmetafield(L, -1, "class") )
{ {
lua_pushliteral( L, "type" );
lua_gettable( L, -2 );
name = lua_tostring( L, -1 ); name = lua_tostring( L, -1 );
if( name ) if( name )
c.m_sBaseName = name; c.m_sBaseName = name;
lua_pop( L, 2 ); // pop name and metatable lua_pop( L, 1 ); // pop name
}
lua_pop( L, 1 ); // pop base class
} }
lua_pop( L, 2 ); // pop (table or other) and metatable
// Get methods. // Get methods.
lua_pushnil( L ); // initial key lua_pushnil( L ); // initial key
@@ -345,35 +333,20 @@ XNode *LuaManager::GetLuaInformation() const
sort( c.m_vMethods.begin(), c.m_vMethods.end() ); sort( c.m_vMethods.begin(), c.m_vMethods.end() );
break; break;
} }
case LUA_TUSERDATA:
{
/* Tricky. The singletons have a metatable but it doesn't have a type key-value pair.
* Instead, we need to get the methods using the __index key and then get the
* metatable of the methods table. */
if( !lua_getmetatable(L, -1) )
break;
lua_pushliteral( L, "__index" );
lua_rawget( L, -2 );
if( !lua_istable(L, -1) || !lua_getmetatable(L, -1) )
{
lua_pop( L, 2 ); // pop method table and metatable
break;
} }
lua_pushliteral( L, "type" ); // fall through
lua_rawget( L, -2 ); case LUA_TUSERDATA: // table or userdata: class instance
{
/* The stack now looks like: if( luaL_getmetafield(L, -1, "type") )
* -1: type {
* -2: method metatable
* -3: method table
* -4: metatable
* -5: user data
* -6: key (object's name) */
const char *type = lua_tostring( L, -1 ); const char *type = lua_tostring( L, -1 );
if( type ) if( type )
mSingletons[sKey] = type; mSingletons[sKey] = type;
lua_pop( L, 4 ); // pop type, method metatable, method table, and metatable
lua_pop( L, 1 ); // pop type
}
break; break;
} }
case LUA_TNUMBER: case LUA_TNUMBER:
@@ -382,10 +355,20 @@ XNode *LuaManager::GetLuaInformation() const
case LUA_TSTRING: case LUA_TSTRING:
LuaHelpers::FromStack( L, mStringConstants[sKey], -1 ); LuaHelpers::FromStack( L, mStringConstants[sKey], -1 );
break; break;
case LUA_TFUNCTION:
vFunctions.push_back( sKey );
break;
} }
lua_pop( L, 1 ); // pop value lua_pop( L, 1 ); // pop value
} }
sort( vFunctions.begin(), vFunctions.end() );
FOREACH_CONST( RString, vFunctions, func )
{
XNode *pFunctionNode = pGlobalsNode->AppendChild( "Function" );
pFunctionNode->AppendAttr( "name", *func );
}
FOREACHM_CONST( RString, LClass, mClasses, c ) FOREACHM_CONST( RString, LClass, mClasses, c )
{ {
XNode *pClassNode = pClassesNode->AppendChild( "Class" ); XNode *pClassNode = pClassesNode->AppendChild( "Class" );
@@ -395,11 +378,8 @@ XNode *LuaManager::GetLuaInformation() const
pClassNode->AppendAttr( "base", c->second.m_sBaseName ); pClassNode->AppendAttr( "base", c->second.m_sBaseName );
FOREACH_CONST( RString, c->second.m_vMethods, m ) FOREACH_CONST( RString, c->second.m_vMethods, m )
{ {
XNode *pMethodNode = new XNode; XNode *pMethodNode = pClassNode->AppendChild( "Function" );
pMethodNode->m_sName = "Function";
pMethodNode->AppendAttr( "name", *m ); pMethodNode->AppendAttr( "name", *m );
pClassNode->AppendChild( pMethodNode );
} }
} }