fixes/updates: both tables and userdata can be instances of a class;
binding changes
This commit is contained in:
@@ -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 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user