Fix LoadFallbackB for loading BGAs recursively. LoadFallbackB checking for either LuaThreadVariables or Lua globals is not very clean, but room for possible improvement.

This commit is contained in:
Chris Danford
2008-04-27 00:14:05 +00:00
parent 122473e9b9
commit 82976bc6ef
9 changed files with 107 additions and 45 deletions
@@ -27,7 +27,7 @@ function ComboGraph( pn )
end
local t = THEME:GetPathB("ScreenWithMenuElements2", "decorations" );
local t = LoadFallbackB();
t[#t+1] = GraphDisplay(PLAYER_1) .. {
InitCommand = cmd(x,SCREEN_CENTER_X-222;y,SCREEN_CENTER_Y-16;draworder,1;);
@@ -1,4 +1,4 @@
local t = LoadFallbackB( "decorations" );
local t = LoadFallbackB();
t[#t+1] = LoadActor( THEME:GetPathB('','_standard decoration required'), "StageFrame", "StageFrame" );
@@ -62,7 +62,7 @@ local function OptionsArea(pn)
end
local t = LoadFallbackB( "decorations" );
local t = LoadFallbackB();
t[#t+1] = Def.ActorFrame {
InitCommand=cmd(x,SCREEN_CENTER_X+140;y,SCREEN_CENTER_Y-10);
OnCommand=cmd(addx,-SCREEN_WIDTH*0.6;bounceend,0.5;addx,SCREEN_WIDTH*0.6);
+29 -7
View File
@@ -1,10 +1,32 @@
function LoadFallbackB( element )
-- TODO: This should fall back to the current lookup's fallback, and not LoadingScreen's fallback
-- TODO: Remove element parameter and make it a LuaThreadVar
local fallback_screen = THEME:GetMetric(Var 'LoadingScreen','Fallback');
local fallback_path = THEME:GetPathB(fallback_screen,element);
--Trace('fallback_path ' .. fallback_path );
return LoadActor( fallback_path );
local g_metrics_group = nil;
local g_element = nil;
function LoadFallbackB()
-- Load the fallback BGA for the element that is currently being loaded.
-- The fallback metrics group and element name will come either from LuaThreadVars
-- (loading from C++) or from the Lua globals above (loading from Lua).
--Warn( "g_element " .. (g_element or "") );
--Warn( "MatchingElement " .. (Var 'MatchingElement' or "") );
--Warn( "g_metrics_group " .. (g_metrics_group or "") );
--Warn( "MatchingMetricsGroup " .. (Var 'MatchingMetricsGroup' or "") );
local metrics_group = g_metrics_group or Var 'MatchingMetricsGroup';
local element = g_element or Var 'MatchingElement';
local fallback = THEME:GetMetric(metrics_group,'Fallback');
local old_metrics_group = g_metrics_group;
local old_element = g_element;
local path;
path, g_metrics_group, g_element = THEME:GetPathInfoB(fallback,element);
--Trace('path ' .. path );
local t = LoadActor( path );
g_metrics_group = old_metrics_group;
g_element = old_element;
return t;
end
function FormatNumSongsPlayed( num )
+10
View File
@@ -45,6 +45,16 @@ void AutoActor::Load( const RString &sPath )
m_pActor = new Actor;
}
void AutoActor::LoadB( const RString &sMetricsGroup, const RString &sElement )
{
ThemeManager::PathInfo pi;
bool b = THEME->GetPathInfo( pi, EC_BGANIMATIONS, sMetricsGroup, sElement );
ASSERT( b );
LuaThreadVariable var1( "MatchingMetricsGroup", pi.sMatchingMetricsGroup );
LuaThreadVariable var2( "MatchingElement", pi.sMatchingElement );
Load( pi.sResolvedPath );
}
void AutoActor::LoadActorFromNode( const XNode* pNode, Actor *pParent )
{
Unload();
+2 -1
View File
@@ -21,8 +21,9 @@ public:
Actor *operator->() { return m_pActor; }
void Unload();
bool IsLoaded() const { return m_pActor != NULL; }
void Load( Actor *pActor );
void Load( Actor *pActor ); // transfer pointer
void Load( const RString &sPath );
void LoadB( const RString &sMetricsGroup, const RString &sElement ); // load a background and set up LuaThreadVariables for recursive loading
void LoadActorFromNode( const XNode *pNode, Actor *pParent );
void LoadAndSetName( const RString &sScreenName, const RString &sActorName );
+1 -1
View File
@@ -78,7 +78,7 @@ void ScreenWithMenuElements::Init()
/* Experimental: Load "decorations" and make them children of the screen. */
{
AutoActor decorations;
decorations.Load( THEME->GetPathB(m_sName,"decorations") );
decorations.LoadB( m_sName, "decorations" );
ActorFrame *pFrame = dynamic_cast<ActorFrame*>((Actor*)decorations);
if( pFrame )
pFrame->TransferChildren( this );
+51 -28
View File
@@ -114,7 +114,7 @@ void ThemeManager::Unsubscribe( IThemeMetric *p )
/* We spend a lot of time doing redundant theme path lookups. Cache results. */
static map<RString, RString> g_ThemePathCache[NUM_ElementCategory];
static map<RString, ThemeManager::PathInfo> g_ThemePathCache[NUM_ElementCategory];
void ThemeManager::ClearThemePathCache()
{
for( int i = 0; i < NUM_ElementCategory; ++i )
@@ -503,10 +503,10 @@ void ThemeManager::FilterFileLanguages( vector<RString> &asPaths )
asPaths.erase( it, asPaths.end() );
}
RString ThemeManager::GetPathToRaw( const RString &sThemeName_, ElementCategory category, const RString &sMetricsGroup_, const RString &sElement_ )
bool ThemeManager::GetPathInfoToRaw( PathInfo &out, const RString &sThemeName_, ElementCategory category, const RString &sMetricsGroup_, const RString &sElement_ )
{
/* Ugly: the parameters to this function may be a reference into g_vThemes, or something
* else that might suddenly go away when we call ReloadMetrics. */
* else that might suddenly go away when we call ReloadMetrics, so make a copy. */
const RString sThemeName = sThemeName_;
const RString sMetricsGroup = sMetricsGroup_;
const RString sElement = sElement_;
@@ -578,7 +578,7 @@ try_element_again:
if( asElementPaths.size() == 0 )
return RString(); // This isn't fatal.
return false; // This isn't fatal.
FilterFileLanguages( asElementPaths );
@@ -613,7 +613,12 @@ try_element_again:
bool bIsARedirect = GetExtension(sPath).CompareNoCase("redir")==0;
if( !bIsARedirect )
return sPath;
{
out.sResolvedPath = sPath;
out.sMatchingMetricsGroup = sMetricsGroup;
out.sMatchingElement = sElement;
return true;
}
RString sNewFileName;
GetFileContents( sPath, sNewFileName, true );
@@ -629,10 +634,8 @@ try_element_again:
* up resolving to the overridden background. */
/* Use GetPathToOptional because we don't want report that there's an element
* missing. Instead we want to report that the redirect is invalid. */
RString sNewPath = GetPath(category, sNewClassName, sNewFile, true);
if( !sNewPath.empty() )
return sNewPath;
if( GetPathInfo(out,category,sNewClassName,sNewFile,true) )
return true;
RString sMessage = ssprintf(
"ThemeManager: The redirect '%s' points to the file '%s', which does not exist. "
@@ -645,13 +648,14 @@ try_element_again:
ReloadMetrics();
goto try_element_again;
case Dialog::ignore:
return GetPath( category, "", "_missing" );
GetPathInfo( out, category, "", "_missing" );
return true;
}
RageException::Throw( "%s", sMessage.c_str() );
}
RString ThemeManager::GetPathToAndFallback( ElementCategory category, const RString &sMetricsGroup_, const RString &sElement )
bool ThemeManager::GetPathInfoToAndFallback( PathInfo &out, ElementCategory category, const RString &sMetricsGroup_, const RString &sElement )
{
RString sMetricsGroup( sMetricsGroup_ );
@@ -661,18 +665,17 @@ RString ThemeManager::GetPathToAndFallback( ElementCategory category, const RStr
FOREACHD_CONST( Theme, g_vThemes, iter )
{
// search with requested name
RString sRet = GetPathToRaw( iter->sThemeName, category, sMetricsGroup, sElement );
if( !sRet.empty() )
return sRet;
if( GetPathInfoToRaw( out, iter->sThemeName, category, sMetricsGroup, sElement ) )
return true;
}
if( sMetricsGroup.empty() )
return RString();
return false;
// search fallback name (if any)
sMetricsGroup = GetMetricsGroupFallback( sMetricsGroup );
if( sMetricsGroup.empty() )
return RString();
return false;
}
RageException::Throw( "Infinite recursion looking up theme element \"%s\"",
@@ -682,7 +685,7 @@ RString ThemeManager::GetPathToAndFallback( ElementCategory category, const RStr
while( true ) {}
}
RString ThemeManager::GetPath( ElementCategory category, const RString &sMetricsGroup_, const RString &sElement_, bool bOptional )
bool ThemeManager::GetPathInfo( PathInfo &out, ElementCategory category, const RString &sMetricsGroup_, const RString &sElement_, bool bOptional )
{
/* Ugly: the parameters to this function may be a reference into g_vThemes, or something
* else that might suddenly go away when we call ReloadMetrics. */
@@ -691,29 +694,31 @@ RString ThemeManager::GetPath( ElementCategory category, const RString &sMetrics
RString sFileName = MetricsGroupAndElementToFileName( sMetricsGroup, sElement );
map<RString, RString> &Cache = g_ThemePathCache[category];
map<RString, PathInfo> &Cache = g_ThemePathCache[category];
{
map<RString, RString>::const_iterator i;
map<RString, PathInfo>::const_iterator i;
i = Cache.find( sFileName );
if( i != Cache.end() )
return i->second;
{
out = i->second;
return true;
}
}
try_element_again:
// search the current theme
RString ret = GetPathToAndFallback( category, sMetricsGroup, sElement );
if( !ret.empty() ) // we found something
if( GetPathInfoToAndFallback( out, category, sMetricsGroup, sElement ) ) // we found something
{
Cache[sFileName] = ret;
return ret;
Cache[sFileName] = out;
return true;
}
if( bOptional )
{
Cache[sFileName] = "";
return RString();
Cache[sFileName] = PathInfo(); // clear cache entry
return false;
}
const RString &sCategory = ElementCategoryToString(category);
@@ -740,8 +745,9 @@ try_element_again:
if( sFileName == "_missing" )
RageException::Throw( "\"_missing\" isn't present in \"%s%s\".", GetThemeDirFromName(SpecialFiles::BASE_THEME_NAME).c_str(), sCategory.c_str() );
Cache[sFileName] = GetPath( category, "", "_missing" );
return Cache[sFileName];
GetPathInfo( out, category, "", "_missing" );
Cache[sFileName] = out;
return true;
case Dialog::abort:
LOG->UserLog( "Theme element", sCategory + '/' + sFileName,
"could not be found in \"%s\" or \"%s\".",
@@ -757,6 +763,13 @@ try_element_again:
FAIL_M( "" ); // Silence gcc 4.
}
RString ThemeManager::GetPath( ElementCategory category, const RString &sMetricsGroup, const RString &sElement, bool bOptional )
{
PathInfo pi;
GetPathInfo( pi, category, sMetricsGroup, sElement, bOptional );
ASSERT( pi.sResolvedPath );
return pi.sResolvedPath;
}
RString ThemeManager::GetMetricsIniPath( const RString &sThemeName )
{
@@ -1123,6 +1136,15 @@ class LunaThemeManager: public Luna<ThemeManager>
public:
static int GetMetric( T* p, lua_State *L ) { p->PushMetric( L, SArg(1),SArg(2) ); return 1; }
static int GetString( T* p, lua_State *L ) { lua_pushstring(L, p->GetString(SArg(1),SArg(2)) ); return 1; }
static int GetPathInfoB( T* p, lua_State *L )
{
ThemeManager::PathInfo pi;
p->GetPathInfo( pi, EC_BGANIMATIONS, SArg(1), SArg(2) );
lua_pushstring(L, pi.sResolvedPath);
lua_pushstring(L, pi.sMatchingMetricsGroup);
lua_pushstring(L, pi.sMatchingElement);
return 3;
}
static int GetPathF( T* p, lua_State *L ) { lua_pushstring(L, p->GetPathF(SArg(1),SArg(2)) ); return 1; }
static int GetPathG( T* p, lua_State *L ) { lua_pushstring(L, p->GetPathG(SArg(1),SArg(2)) ); return 1; }
static int GetPathB( T* p, lua_State *L ) { lua_pushstring(L, p->GetPathB(SArg(1),SArg(2)) ); return 1; }
@@ -1133,6 +1155,7 @@ public:
{
ADD_METHOD( GetMetric );
ADD_METHOD( GetString );
ADD_METHOD( GetPathInfoB );
ADD_METHOD( GetPathF );
ADD_METHOD( GetPathG );
ADD_METHOD( GetPathB );
+11 -5
View File
@@ -55,9 +55,14 @@ public:
static void EvaluateString( RString &sText );
/* I renamed these for two reasons. The overload conflicts with the ones below:
* GetPathToB( str, str ) was matching the ones below instead of these. It's also
* easier to search for uses of obsolete functions if they have a different name. */
struct PathInfo
{
RString sResolvedPath;
RString sMatchingMetricsGroup;
RString sMatchingElement;
};
bool GetPathInfo( PathInfo &out, ElementCategory category, const RString &sMetricsGroup, const RString &sElement, bool bOptional=false );
RString GetPath( ElementCategory category, const RString &sMetricsGroup, const RString &sElement, bool bOptional=false );
RString GetPathB( const RString &sMetricsGroup, const RString &sElement, bool bOptional=false ) { return GetPath(EC_BGANIMATIONS,sMetricsGroup,sElement,bOptional); };
RString GetPathF( const RString &sMetricsGroup, const RString &sElement, bool bOptional=false ) { return GetPath(EC_FONTS,sMetricsGroup,sElement,bOptional); };
@@ -106,8 +111,9 @@ protected:
void LoadThemeMetrics( const RString &sThemeName, const RString &sLanguage_ );
RString GetMetricRaw( const IniFile &ini, const RString &sMetricsGroup, const RString &sValueName );
bool GetMetricRawRecursive( const IniFile &ini, const RString &sMetricsGroup, const RString &sValueName, RString &sRet );
RString GetPathToAndFallback( ElementCategory category, const RString &sMetricsGroup, const RString &sFile );
RString GetPathToRaw( const RString &sThemeName, ElementCategory category, const RString &sMetricsGroup, const RString &sFile );
bool GetPathInfoToAndFallback( PathInfo &out, ElementCategory category, const RString &sMetricsGroup, const RString &sFile );
bool GetPathInfoToRaw( PathInfo &out, const RString &sThemeName, ElementCategory category, const RString &sMetricsGroup, const RString &sFile );
static RString GetThemeDirFromName( const RString &sThemeName );
RString GetElementDir( const RString &sThemeName );
static RString GetMetricsIniPath( const RString &sThemeName );