allow specifying a Lua function for a command with "%funciton(self) self:blah end"

This commit is contained in:
Chris Danford
2005-02-23 19:15:24 +00:00
parent 53f7fbd890
commit 42c5e2b3f9
15 changed files with 105 additions and 89 deletions
+72 -63
View File
@@ -6,79 +6,88 @@
#include <sstream>
#include "LuaBinding.h"
ActorCommands::ActorCommands( const Commands& cmds )
ActorCommands::ActorCommands( const CString &sCommands )
{
m_cmds = cmds;
if( sCommands.Left(1) == "%" )
{
m_sLuaFunction = sCommands;
m_sLuaFunction.erase( m_sLuaFunction.begin() );
m_sLuaFunction = "return " + m_sLuaFunction;
}
else
{
Commands cmds;
ParseCommands( sCommands, cmds );
//
// Convert cmds to a Lua function
//
ostringstream s;
s << "return function(self)\n";
FOREACH_CONST( Command, cmds.v, c )
{
const Command& cmd = (*c);
CString sName = cmd.GetName();
s << "\tself:" << sName << "(";
bool bFirstParamIsString =
sName == "horizalign" ||
sName == "vertalign" ||
sName == "effectclock" ||
sName == "blend" ||
sName == "ztestmode" ||
sName == "cullmode" ||
sName == "playcommand" ||
sName == "queuecommand";
for( unsigned i=1; i<cmd.m_vsArgs.size(); i++ )
{
CString sArg = cmd.m_vsArgs[i];
// "+200" -> "200"
if( sArg[0] == '+' )
sArg.erase( sArg.begin() );
if( i==1 && bFirstParamIsString ) // string literal
{
s << "'" << sArg << "'";
}
else if( sArg[0] == '#' ) // HTML color
{
RageColor c; // in case FromString fails
c.FromString( sArg );
// c is still valid if FromString fails
s << c.r << "," << c.g << "," << c.b << "," << c.a;
}
else
{
s << sArg;
}
if( i != cmd.m_vsArgs.size()-1 )
s << ",";
}
s << ")\n";
}
s << "end\n";
m_sLuaFunction = s.str();
}
Register();
}
void ActorCommands::Register()
{
//
// Convert cmds to a Lua function
//
ostringstream s;
s << "return function(self)\n";
FOREACH_CONST( Command, m_cmds.v, c )
{
const Command& cmd = (*c);
CString sName = cmd.GetName();
s << "\tself:" << sName << "(";
bool bFirstParamIsString =
sName == "horizalign" ||
sName == "vertalign" ||
sName == "effectclock" ||
sName == "blend" ||
sName == "ztestmode" ||
sName == "cullmode" ||
sName == "playcommand" ||
sName == "queuecommand";
for( unsigned i=1; i<cmd.m_vsArgs.size(); i++ )
{
CString sArg = cmd.m_vsArgs[i];
// "+200" -> "200"
if( sArg[0] == '+' )
sArg.erase( sArg.begin() );
if( i==1 && bFirstParamIsString ) // string literal
{
s << "'" << sArg << "'";
}
else if( sArg[0] == '#' ) // HTML color
{
RageColor c; // in case FromString fails
c.FromString( sArg );
// c is still valid if FromString fails
s << c.r << "," << c.g << "," << c.b << "," << c.a;
}
else
{
s << sArg;
}
if( i != cmd.m_vsArgs.size()-1 )
s << ",";
}
s << ")\n";
}
s << "end\n";
CString s2 = s.str();
CString sError;
if( !LUA->RunScript( s2, "in", sError, 1 ) )
if( !LUA->RunScript( m_sLuaFunction, "in", sError, 1 ) )
{
/* We're compiling a generated script, so it should never fail. */
FAIL_M( ssprintf("Compiling \"%s\": %s", s2.c_str(), sError.c_str()) );
FAIL_M( ssprintf("Compiling \"%s\": %s", m_sLuaFunction.c_str(), sError.c_str()) );
}
/* The function is now on the stack. */
this->SetFromStack();
}
+2 -2
View File
@@ -11,11 +11,11 @@
class ActorCommands: public LuaReference
{
public:
ActorCommands( const Commands& cmds );
ActorCommands( const CString &sCommands );
private:
void Register();
Commands m_cmds;
CString m_sLuaFunction;
};
typedef AutoPtrCopyOnWrite<ActorCommands> apActorCommands;
+1 -1
View File
@@ -183,7 +183,7 @@ void BGAnimation::LoadFromNode( const CString& sDir, const XNode* pNode )
ActorScroller::LoadFromNode( sDir, pNode );
this->RunCommandsOnChildren( ActorCommands(ParseCommands("PlayCommand,Init")) );
this->RunCommandsOnChildren( ActorCommands("PlayCommand,Init") );
/* Backwards-compatibility: if a "LengthSeconds" value is present, create a dummy
+1 -1
View File
@@ -473,7 +473,7 @@ void Background::LoadFromSong( const Song* pSong )
* may look something like "BGAnimation, BGAnimationLayer, Sprite" or it
* may be deeper, like "BGAnimation, BGAnimationLayer, BGAnimation,
* BGAnimationLayer, Sprite". */
ActorCommands acmds( ParseCommands("effectclock,music") );
ActorCommands acmds( "effectclock,music" );
pBGA->RunCommands( acmds );
}
}
+3 -3
View File
@@ -238,7 +238,7 @@ void DifficultyList::PositionItems()
if( m_bShown && m < (int)m_Rows.size() )
bHidden = m_Rows[m].m_bHidden;
ActorCommands c = ActorCommands( ParseCommands( ssprintf("diffusealpha,%f",bHidden?0.0f:1.0f) ) );
ActorCommands c = ActorCommands( ssprintf("diffusealpha,%f",bHidden?0.0f:1.0f) );
m_Lines[m].m_Description.RunCommands( c );
m_Lines[m].m_Meter.RunCommandsOnChildren( c );
m_Lines[m].m_Number.RunCommands( c );
@@ -359,7 +359,7 @@ void DifficultyList::HideRows()
{
for( unsigned m = 0; m < m_Rows.size(); ++m )
{
ActorCommands c = ActorCommands( ParseCommands( "finishtweening;diffusealpha,0" ) );
ActorCommands c = ActorCommands( "finishtweening;diffusealpha,0" );
m_Lines[m].m_Description.RunCommands( c );
m_Lines[m].m_Meter.RunCommandsOnChildren( c );
m_Lines[m].m_Number.RunCommands( c );
@@ -372,7 +372,7 @@ void DifficultyList::TweenOnScreen()
m_bShown = true;
for( unsigned m = 0; m < m_Rows.size(); ++m )
{
ActorCommands c = ActorCommands( ParseCommands( "finishtweening" ) );
ActorCommands c = ActorCommands( "finishtweening" );
m_Lines[m].m_Description.RunCommands( c );
m_Lines[m].m_Meter.RunCommandsOnChildren( c );
m_Lines[m].m_Number.RunCommands( c );
+1 -1
View File
@@ -31,7 +31,7 @@ void GhostArrow::Load( CString sNoteSkin, CString sButton, CString sElement )
{
CString sJudge = TapNoteScoreToString( i );
CString sCommand = Capitalize(sJudge)+"Command";
apActorCommands p( new ActorCommands(NOTESKIN->GetMetricA(sNoteSkin,m_sName,sCommand)) );
apActorCommands p( new ActorCommands(NOTESKIN->GetMetric(sNoteSkin,m_sName,sCommand)) );
m_acScoreCommand[i] = p;
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ HoldGhostArrow::HoldGhostArrow()
void HoldGhostArrow::Load( CString sNoteSkin, CString sButton, CString sElement )
{
Sprite::Load( NOTESKIN->GetPathToFromNoteSkinAndButton(sNoteSkin, sButton, sElement) ); // not optional
this->RunCommands( ActorCommands(NOTESKIN->GetMetricA(sNoteSkin,"HoldGhostArrow","OnCommand")) );
this->RunCommands( ActorCommands(NOTESKIN->GetMetric(sNoteSkin,"HoldGhostArrow","OnCommand")) );
}
void HoldGhostArrow::Update( float fDeltaTime )
+8 -1
View File
@@ -11,6 +11,7 @@
#include "Style.h"
#include "Command.h"
#include "ActorUtil.h"
#include "Foreach.h"
#define SHIFT_X(p) THEME->GetMetricF(m_sName, ssprintf("ShiftP%iX", p+1))
#define SHIFT_Y(p) THEME->GetMetricF(m_sName, ssprintf("ShiftP%iY", p+1))
@@ -105,7 +106,13 @@ void PaneDisplay::Load( PlayerNumber pn )
level.m_fIfLessThan = cmds.v[0].GetArg(0);
cmds.v.erase( cmds.v.begin(), cmds.v.begin()+1 );
level.m_Command = apActorCommands(new ActorCommands( cmds ));
// TODO: clean this up
vector<CString> vs;
FOREACH_CONST( Command, cmds.v, cmd )
vs.push_back( cmd->GetOriginalCommandString() );
level.m_Command = apActorCommands( new ActorCommands(join(";",vs)) );
}
}
+1 -1
View File
@@ -31,7 +31,7 @@ bool ReceptorArrow::Load( CString NoteSkin, const PlayerState* pPlayerState, int
{
CString sJudge = TapNoteScoreToString( i );
CString sCommand = Capitalize(sJudge)+"Command";
m_sScoreCommand[i] = apActorCommands( new ActorCommands(NOTESKIN->GetMetricA(NoteSkin,m_sName,sCommand)) );
m_sScoreCommand[i] = apActorCommands( new ActorCommands(NOTESKIN->GetMetric(NoteSkin,m_sName,sCommand)) );
}
m_pPressBlock.Load( NOTESKIN->GetPathToFromNoteSkinAndButton(NoteSkin,sButton,"KeypressBlock") );
+3 -3
View File
@@ -53,21 +53,21 @@ void ScoreDisplayBattle::Update( float fDelta )
if( sNewModifier == "" )
{
m_ItemIcon[s].RunCommands( ActorCommands( ParseCommands("linear,0.25;zoom,0") ) );
m_ItemIcon[s].RunCommands( ActorCommands( "linear,0.25;zoom,0" ) );
}
else
{
// TODO: Cache all of the icon graphics so we don't load them dynamically from disk.
m_ItemIcon[s].Load( THEME->GetPathG("ScoreDisplayBattle","icon "+sNewModifier) );
m_ItemIcon[s].StopTweening();
ActorCommands acmds( ParseCommands(
ActorCommands acmds(
"diffuse,1,1,1,1;zoom,1;"
"sleep,0.1;linear,0;diffusealpha,0;"
"sleep,0.1;linear,0;diffusealpha,1;"
"sleep,0.1;linear,0;diffusealpha,0;"
"sleep,0.1;linear,0;diffusealpha,1;"
"sleep,0.1;linear,0;diffusealpha,0;"
"sleep,0.1;linear,0;diffusealpha,1;" ) );
"sleep,0.1;linear,0;diffusealpha,1;" );
m_ItemIcon[s].RunCommands( acmds );
}
}
+2 -2
View File
@@ -414,10 +414,10 @@ void ScreenEz2SelectMusic::MenuBack( PlayerNumber pn )
void ScreenEz2SelectMusic::TweenOffScreen()
{
ActorCommands cmds( ParseCommands("linear,0.5;zoomy,0") );
ActorCommands cmds( "linear,0.5;zoomy,0" );
m_MusicBannerWheel.RunCommands( cmds );
ActorCommands cmds2( ParseCommands("Linear,1;DiffuseAlpha,0") );
ActorCommands cmds2( "Linear,1;DiffuseAlpha,0" );
m_PumpDifficultyCircle.RunCommands( cmds2 );
m_Guide.RunCommands( cmds2 );
m_PumpDifficultyRating.RunCommands( cmds2 );
+2 -2
View File
@@ -77,7 +77,7 @@ void HighScoreWheelItem::LoadBlank( int iRankIndex )
void HighScoreWheelItem::ShowFocus()
{
ActorCommands c( ParseCommands("diffuseshift;EffectColor1,1,1,0,1;EffectColor2,0,1,1,1") );
ActorCommands c( "diffuseshift;EffectColor1,1,1,0,1;EffectColor2,0,1,1,1" );
m_textRank.RunCommands( c );
m_textName.RunCommands( c );
m_textScore.RunCommands( c );
@@ -447,7 +447,7 @@ void ScreenNameEntryTraditional::PositionCharsAndCursor( int pn )
const bool hidden = ( Pos < First || Pos > Last );
const int ActualPos = clamp( Pos, First-1, Last+1 );
bt->RunCommands( ActorCommands(ParseCommands("stoptweening;decelerate,.12")) );
bt->RunCommands( ActorCommands("stoptweening;decelerate,.12") );
bt->SetX( ActualPos * ALPHABET_GAP_X );
bt->SetDiffuseAlpha( hidden? 0.0f:1.0f );
}
+1 -1
View File
@@ -106,7 +106,7 @@ void ScreenSystemLayer::ReloadCreditsText()
void ScreenSystemLayer::SystemMessage( const CString &sMessage )
{
m_textMessage.SetText( sMessage );
ActorCommands c = ActorCommands( ParseCommands("finishtweening;diffusealpha,1;addx,-640;linear,0.5;addx,+640;sleep,5;linear,0.5;diffusealpha,0") );
ActorCommands c = ActorCommands( "finishtweening;diffusealpha,1;addx,-640;linear,0.5;addx,+640;sleep,5;linear,0.5;diffusealpha,0" );
m_textMessage.RunCommands( c );
}
+6 -6
View File
@@ -171,12 +171,12 @@ void ScreenUnlock::Init()
LOG->Trace("Target Row: %f", TargetRow);
LOG->Trace("command for icon %d: %s", i, ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime * 2, ScrollingTextEndY).c_str() );
CString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime, ScrollingTextEndY);
text->RunCommands( ActorCommands(ParseCommands(sCommand)) );
text->RunCommands( ActorCommands(sCommand) );
}
else
{
CString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), SECS_PER_CYCLE * (ScrollingTextRows), ScrollingTextEndY);
text->RunCommands( ActorCommands(ParseCommands(sCommand)) );
text->RunCommands( ActorCommands(sCommand) );
}
item.push_back(text);
@@ -203,12 +203,12 @@ void ScreenUnlock::Init()
LOG->Trace("Target Row: %f", TargetRow);
LOG->Trace("command for icon %d: %s", i, ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime * 2, ScrollingTextEndY).c_str() );
CString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime, ScrollingTextEndY);
IconCount->RunCommands( ActorCommands(ParseCommands(sCommand)) );
IconCount->RunCommands( ActorCommands(sCommand) );
}
else
{
CString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), SECS_PER_CYCLE * (ScrollingTextRows), ScrollingTextEndY);
IconCount->RunCommands( ActorCommands(ParseCommands(sCommand)) );
IconCount->RunCommands( ActorCommands(sCommand) );
}
ItemIcons.push_back(IconCount);
@@ -274,7 +274,7 @@ void ScreenUnlock::Init()
NewText->SetXY(ScrollingTextX, ScrollingTextStartY);
{
CString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;", SECS_PER_CYCLE * (NumUnlocks + 2 * i - 2), SECS_PER_CYCLE * ((ScrollingTextRows - i) * 2 + 1 ), (ScrollingTextStartY + (ScrollingTextEndY - ScrollingTextStartY) * (ScrollingTextRows - i + 0.5) / ScrollingTextRows ));
NewText->RunCommands( ActorCommands(ParseCommands(sCommand)) );
NewText->RunCommands( ActorCommands(sCommand) );
}
// new unlock graphic
@@ -285,7 +285,7 @@ void ScreenUnlock::Init()
NewIcon->SetWidth(UNLOCK_TEXT_SCROLL_ICON_SIZE);
{
CString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;", SECS_PER_CYCLE * (NumUnlocks + 2 * i - 2), SECS_PER_CYCLE * ((ScrollingTextRows - i) * 2 + 1 ), (ScrollingTextStartY + (ScrollingTextEndY - ScrollingTextStartY) * (ScrollingTextRows - i + 0.5) / ScrollingTextRows ));
NewIcon->RunCommands( ActorCommands(ParseCommands(sCommand)) );
NewIcon->RunCommands( ActorCommands(sCommand) );
}
ItemIcons.push_back(NewIcon);
+1 -1
View File
@@ -750,7 +750,7 @@ Commands ThemeManager::GetMetricM( const CString &sClassName, const CString &sVa
apActorCommands ThemeManager::GetMetricA( const CString &sClassName, const CString &sValueName )
{
CString sValue = GetMetric( sClassName, sValueName ); // Use non-raw so that Lua expressions are allowed
return apActorCommands( new ActorCommands( ParseCommands( sValue ) ) );
return apActorCommands( new ActorCommands( sValue ) );
}
void ThemeManager::NextTheme()