Currently, expression handling in XML is spotting and inconsistent.

Each actor type needs to evaluate attributes; only a few do.  Strings
are handled with the "@foo()" notation.

Instead, after loading an XML file for loading as an actor,
precompile all XML attributes as Lua expressions.

The primary difference to code is:
 - previously, Attr="string" would act as a string if it was being
   read as one.  Now, specify Attr='"string"'.  Attr="@string" is
   a shorthand.  (note that @strings will not be parsed as Lua
   strings, so can not use Lua escape characters)
 - previously, Attr="@func()" would evaluate func(), and the value
   of the attribute would be the return value of the function.  This
   was only supported for a few attributes.  Now, say Attr="func()",
   and this will work for all fields.
 - Attributes of other types are unchanged, except that all attributes
   may be Lua expressions, eg. Width="SCREEN_WIDTH".
 - Attributes names ending with "Command" are special, like metrics.
   Prefix "%" to disable this.

This brings XML handling in line with metric handling.  (This is an intermediary
step; I have another idea that follows from this that should eliminate the annoying
"'foo'"/"@foo".)
This commit is contained in:
Glenn Maynard
2006-10-09 00:49:30 +00:00
parent 2e3b047880
commit 3cae60d6fd
6 changed files with 166 additions and 15 deletions
+33
View File
@@ -12,6 +12,7 @@
#include "RageUtil.h"
#include "DateTime.h"
#include "Foreach.h"
#include "LuaManager.h"
XNode::XNode()
{
@@ -62,11 +63,19 @@ void XNodeStringValue::GetValue( int &out ) const { out = atoi(m_sValue); }
void XNodeStringValue::GetValue( float &out ) const { out = StringToFloat(m_sValue); }
void XNodeStringValue::GetValue( bool &out ) const { out = atoi(m_sValue) != 0; }
void XNodeStringValue::GetValue( unsigned &out ) const { out = strtoul(m_sValue,NULL,0); }
void XNodeStringValue::PushValue( lua_State *L ) const
{
LuaHelpers::Push( L, m_sValue );
}
void XNodeStringValue::SetValue( const RString &v ) { m_sValue = v; }
void XNodeStringValue::SetValue( int v ) { m_sValue = ssprintf("%d",v); }
void XNodeStringValue::SetValue( float v ) { m_sValue = ssprintf("%f",v); }
void XNodeStringValue::SetValue( unsigned v ) { m_sValue = ssprintf("%u",v); }
void XNodeStringValue::SetValueFromStack( lua_State *L )
{
LuaHelpers::Pop( L, m_sValue );
}
const XNodeValue *XNode::GetAttr( const RString &attrname ) const
{
@@ -76,6 +85,18 @@ const XNodeValue *XNode::GetAttr( const RString &attrname ) const
return NULL;
}
bool XNode::PushAttrValue( lua_State *L, const RString &sName ) const
{
const XNodeValue *pAttr = GetAttr(sName);
if( pAttr == NULL )
{
lua_pushnil( L );
return false;
}
pAttr->PushValue( L );
return true;
}
XNodeValue *XNode::GetAttr( const RString &attrname )
{
XAttrs::iterator it = m_attrs.find( attrname );
@@ -95,6 +116,18 @@ XNode *XNode::GetChild( const RString &sName )
return NULL;
}
bool XNode::PushChildValue( lua_State *L, const RString &sName ) const
{
const XNode *pChild = GetChild(sName);
if( pChild == NULL )
{
lua_pushnil( L );
return false;
}
pChild->m_pValue->PushValue( L );
return true;
}
const XNode *XNode::GetChild( const RString &sName ) const
{
multimap<RString, XNode*>::const_iterator it = m_childs.find( sName );