Bah. This is really two commits. I thought I already did the first and I'm too tired to try to separate them (I wrote a long commit message explaining the first one already.)
1. When iterating over the tables using lua_next(), using lua_tolstring() can modify the key which confuses lua_next(). Instead push the value onto the top of the stack and Pop() the string from there. 2. Handle integer, string, and float constants. Handle the enum values by looking for FooIndex and then reading the global table Foo. Stylesheet updating coming later this week.
This commit is contained in:
@@ -157,9 +157,6 @@ void LuaManager::Register( RegisterWithLuaFn pfn )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LuaManager::LuaManager()
|
LuaManager::LuaManager()
|
||||||
{
|
{
|
||||||
LUA = this; // so that LUA is available when we call the Register functions
|
LUA = this; // so that LUA is available when we call the Register functions
|
||||||
@@ -246,12 +243,14 @@ XNode *LuaManager::GetLuaInformation() const
|
|||||||
XNode *pGlobalsNode = new XNode;
|
XNode *pGlobalsNode = new XNode;
|
||||||
XNode *pClassesNode = new XNode;
|
XNode *pClassesNode = new XNode;
|
||||||
XNode *pSingletonsNode = new XNode;
|
XNode *pSingletonsNode = new XNode;
|
||||||
|
XNode *pEnumsNode = new XNode;
|
||||||
XNode *pConstantsNode = new XNode;
|
XNode *pConstantsNode = new XNode;
|
||||||
|
|
||||||
pLuaNode->m_sName = "Lua";
|
pLuaNode->m_sName = "Lua";
|
||||||
pGlobalsNode->m_sName = "GlobalFunctions";
|
pGlobalsNode->m_sName = "GlobalFunctions";
|
||||||
pClassesNode->m_sName = "Classes";
|
pClassesNode->m_sName = "Classes";
|
||||||
pSingletonsNode->m_sName = "Singletons";
|
pSingletonsNode->m_sName = "Singletons";
|
||||||
|
pEnumsNode->m_sName = "Enums";
|
||||||
pConstantsNode->m_sName = "Constants";
|
pConstantsNode->m_sName = "Constants";
|
||||||
|
|
||||||
vector<RString> vFunctions;
|
vector<RString> vFunctions;
|
||||||
@@ -272,21 +271,49 @@ XNode *LuaManager::GetLuaInformation() const
|
|||||||
// Tricky. We have to get the classes from lua.
|
// Tricky. We have to get the classes from lua.
|
||||||
map<RString, LClass> mClasses;
|
map<RString, LClass> mClasses;
|
||||||
map<RString, RString> mSingletons;
|
map<RString, RString> mSingletons;
|
||||||
map<RString, int> mConstants;
|
map<RString, float> mConstants;
|
||||||
|
map<RString, RString> mStringConstants;
|
||||||
|
map<RString, vector<RString> > mEnums;
|
||||||
|
|
||||||
lua_pushnil( L ); // initial key
|
lua_pushnil( L ); // initial key
|
||||||
while( lua_next(L, LUA_GLOBALSINDEX) )
|
while( lua_next(L, LUA_GLOBALSINDEX) )
|
||||||
{
|
{
|
||||||
// key is at -2, value is at -1
|
// key is at -2, value is at -1
|
||||||
|
|
||||||
|
/* Tricky. FromStack() calls lua_tolstring() which changes the underlying cell
|
||||||
|
* if it is not a string. This confuses lua_next(). Copy the value first.
|
||||||
|
* http://www.lua.org/manual/5.1/manual.html#lua_tolstring */
|
||||||
|
|
||||||
|
RString sKey;
|
||||||
|
|
||||||
|
lua_pushvalue( L, -2 );
|
||||||
|
LuaHelpers::Pop( L, sKey );
|
||||||
|
|
||||||
switch( lua_type(L, -1) )
|
switch( lua_type(L, -1) )
|
||||||
{
|
{
|
||||||
case LUA_TTABLE:
|
case LUA_TTABLE:
|
||||||
{
|
{
|
||||||
// Check for the metatable.
|
// Check for the metatable.
|
||||||
if( !lua_getmetatable(L, -1) )
|
if( !lua_getmetatable(L, -1) )
|
||||||
|
{
|
||||||
|
/* If the key ends in "Index", check for the non "Index" version.
|
||||||
|
* If both exist, then we have found an enum. */
|
||||||
|
if( !EndsWith(sKey, "Index") || sKey.size() <= 5 )
|
||||||
|
break;
|
||||||
|
sKey = sKey.substr( 0, sKey.size() - 5 );
|
||||||
|
LuaHelpers::Push( L, sKey );
|
||||||
|
lua_rawget( L, LUA_GLOBALSINDEX );
|
||||||
|
if( lua_istable(L, -1) )
|
||||||
|
{
|
||||||
|
vector<RString> &vEnum = mEnums[sKey];
|
||||||
|
LuaHelpers::ReadArrayFromTable( vEnum, L );
|
||||||
|
}
|
||||||
|
lua_pop( L, 2 ); // pop table and key
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
lua_pushliteral( L, "type" );
|
lua_pushliteral( L, "type" );
|
||||||
lua_gettable( L, -2 );
|
lua_rawget( L, -2 );
|
||||||
|
|
||||||
const char *name = lua_tostring( L, -1 );
|
const char *name = lua_tostring( L, -1 );
|
||||||
|
|
||||||
@@ -300,7 +327,7 @@ XNode *LuaManager::GetLuaInformation() const
|
|||||||
|
|
||||||
// Get base class.
|
// Get base class.
|
||||||
lua_pushliteral( L, "__index" );
|
lua_pushliteral( L, "__index" );
|
||||||
lua_gettable( L, -2 );
|
lua_rawget( L, -2 );
|
||||||
if( lua_istable(L, -1) && lua_getmetatable(L, -1) )
|
if( lua_istable(L, -1) && lua_getmetatable(L, -1) )
|
||||||
{
|
{
|
||||||
lua_pushliteral( L, "type" );
|
lua_pushliteral( L, "type" );
|
||||||
@@ -317,12 +344,15 @@ XNode *LuaManager::GetLuaInformation() const
|
|||||||
lua_pushnil( L ); // initial key
|
lua_pushnil( L ); // initial key
|
||||||
while( lua_next(L, -2) )
|
while( lua_next(L, -2) )
|
||||||
{
|
{
|
||||||
|
// Again, be careful about reading the key as a string.
|
||||||
lua_pop( L, 1 ); // pop value
|
lua_pop( L, 1 ); // pop value
|
||||||
RString sKey;
|
lua_pushvalue( L, -1 );
|
||||||
if( LuaHelpers::FromStack(L, sKey, -1) )
|
RString sMethod;
|
||||||
c.m_vMethods.push_back( sKey );
|
if( LuaHelpers::Pop(L, sMethod) )
|
||||||
|
c.m_vMethods.push_back( sMethod );
|
||||||
}
|
}
|
||||||
sort( c.m_vMethods.begin(), c.m_vMethods.end() );
|
sort( c.m_vMethods.begin(), c.m_vMethods.end() );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TUSERDATA:
|
case LUA_TUSERDATA:
|
||||||
{
|
{
|
||||||
@@ -332,14 +362,14 @@ XNode *LuaManager::GetLuaInformation() const
|
|||||||
if( !lua_getmetatable(L, -1) )
|
if( !lua_getmetatable(L, -1) )
|
||||||
break;
|
break;
|
||||||
lua_pushliteral( L, "__index" );
|
lua_pushliteral( L, "__index" );
|
||||||
lua_gettable( L, -2 );
|
lua_rawget( L, -2 );
|
||||||
if( !lua_istable(L, -1) || !lua_getmetatable(L, -1) )
|
if( !lua_istable(L, -1) || !lua_getmetatable(L, -1) )
|
||||||
{
|
{
|
||||||
lua_pop( L, 2 ); // pop method table and metatable
|
lua_pop( L, 2 ); // pop method table and metatable
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lua_pushliteral( L, "type" );
|
lua_pushliteral( L, "type" );
|
||||||
lua_gettable( L, -2 );
|
lua_rawget( L, -2 );
|
||||||
|
|
||||||
/* The stack now looks like:
|
/* The stack now looks like:
|
||||||
* -1: type
|
* -1: type
|
||||||
@@ -351,27 +381,22 @@ XNode *LuaManager::GetLuaInformation() const
|
|||||||
const char *type = lua_tostring( L, -1 );
|
const char *type = lua_tostring( L, -1 );
|
||||||
|
|
||||||
if( type )
|
if( type )
|
||||||
{
|
mSingletons[sKey] = type;
|
||||||
RString sKey;
|
|
||||||
if( LuaHelpers::FromStack(L, sKey, -6) )
|
|
||||||
mSingletons[sKey] = type;
|
|
||||||
}
|
|
||||||
lua_pop( L, 4 ); // pop type, method metatable, method table, and metatable
|
lua_pop( L, 4 ); // pop type, method metatable, method table, and metatable
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER:
|
||||||
{
|
{
|
||||||
// lua_Number is most likely a double unless LUA_NUMBER was defined to be float.
|
float fNum;
|
||||||
float fNum = float( lua_tonumber(L, -1) );
|
LuaHelpers::FromStack( L, fNum, -1 );
|
||||||
|
mConstants[sKey] = fNum;
|
||||||
if( fNum == truncf(fNum) )
|
|
||||||
{
|
|
||||||
RString sKey;
|
|
||||||
if( LuaHelpers::FromStack(L, sKey, -2) )
|
|
||||||
mConstants[sKey] = int( fNum );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case LUA_TSTRING:
|
||||||
|
RString sValue;
|
||||||
|
LuaHelpers::FromStack( L, sValue, -1 );
|
||||||
|
mStringConstants[sKey] = sValue;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
lua_pop( L, 1 ); // pop value
|
lua_pop( L, 1 ); // pop value
|
||||||
}
|
}
|
||||||
@@ -406,20 +431,53 @@ XNode *LuaManager::GetLuaInformation() const
|
|||||||
pSingletonNode->AppendAttr( "class", s->second );
|
pSingletonNode->AppendAttr( "class", s->second );
|
||||||
pSingletonsNode->AppendChild( pSingletonNode );
|
pSingletonsNode->AppendChild( pSingletonNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
FOREACHM_CONST( RString, int, mConstants, c )
|
for( map<RString, vector<RString> >::const_iterator iter = mEnums.begin(); iter != mEnums.end(); ++iter )
|
||||||
|
{
|
||||||
|
XNode *pEnumNode = new XNode;
|
||||||
|
const vector<RString> &vEnum = iter->second;
|
||||||
|
|
||||||
|
pEnumNode->m_sName = "Enum";
|
||||||
|
pEnumNode->AppendAttr( "name", iter->first );
|
||||||
|
|
||||||
|
for( unsigned i = 0; i < vEnum.size(); ++i )
|
||||||
|
{
|
||||||
|
XNode *pEnumValueNode = new XNode;
|
||||||
|
|
||||||
|
pEnumValueNode->m_sName = "EnumValue";
|
||||||
|
pEnumValueNode->AppendAttr( "name", vEnum[i] );
|
||||||
|
pEnumValueNode->AppendAttr( "value", i );
|
||||||
|
pEnumNode->AppendChild( pEnumValueNode );
|
||||||
|
}
|
||||||
|
pEnumsNode->AppendChild( pEnumNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
FOREACHM_CONST( RString, float, mConstants, c )
|
||||||
{
|
{
|
||||||
XNode *pConstantNode = new XNode;
|
XNode *pConstantNode = new XNode;
|
||||||
|
|
||||||
pConstantNode->m_sName = "Constant";
|
pConstantNode->m_sName = "Constant";
|
||||||
pConstantNode->AppendAttr( "name", c->first );
|
pConstantNode->AppendAttr( "name", c->first );
|
||||||
pConstantNode->AppendAttr( "value", c->second );
|
if( c->second == truncf(c->second) )
|
||||||
|
pConstantNode->AppendAttr( "value", int(c->second) );
|
||||||
|
else
|
||||||
|
pConstantNode->AppendAttr( "value", c->second );
|
||||||
|
pConstantsNode->AppendChild( pConstantNode );
|
||||||
|
}
|
||||||
|
FOREACHM_CONST( RString, RString, mStringConstants, s )
|
||||||
|
{
|
||||||
|
XNode *pConstantNode = new XNode;
|
||||||
|
|
||||||
|
pConstantNode->m_sName = "Constant";
|
||||||
|
pConstantNode->AppendAttr( "name", s->first );
|
||||||
|
pConstantNode->AppendAttr( "value", s->second );
|
||||||
pConstantsNode->AppendChild( pConstantNode );
|
pConstantsNode->AppendChild( pConstantNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
pLuaNode->AppendChild( pGlobalsNode );
|
pLuaNode->AppendChild( pGlobalsNode );
|
||||||
pLuaNode->AppendChild( pClassesNode );
|
pLuaNode->AppendChild( pClassesNode );
|
||||||
pLuaNode->AppendChild( pSingletonsNode );
|
pLuaNode->AppendChild( pSingletonsNode );
|
||||||
|
pLuaNode->AppendChild( pEnumsNode );
|
||||||
pLuaNode->AppendChild( pConstantsNode );
|
pLuaNode->AppendChild( pConstantsNode );
|
||||||
return pLuaNode;
|
return pLuaNode;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user