From a675190a55cbcb634d7d4bfec2bd5f0d375a390d Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Mon, 27 Dec 2004 10:24:54 +0000 Subject: [PATCH] Don't re-parse the ini file multiple times per BGALayer. Yuck. --- stepmania/src/ActorUtil.cpp | 42 ++++++---- stepmania/src/ActorUtil.h | 2 + stepmania/src/BGAnimation.cpp | 2 +- stepmania/src/BGAnimationLayer.cpp | 120 ++++++++++++----------------- stepmania/src/BGAnimationLayer.h | 12 +-- stepmania/src/IniFile.cpp | 39 +++++++--- stepmania/src/IniFile.h | 19 ++++- 7 files changed, 133 insertions(+), 103 deletions(-) diff --git a/stepmania/src/ActorUtil.cpp b/stepmania/src/ActorUtil.cpp index 226a5fb883..94d26b0af0 100644 --- a/stepmania/src/ActorUtil.cpp +++ b/stepmania/src/ActorUtil.cpp @@ -30,14 +30,24 @@ Actor* LoadFromActorFile( const CString &sIniPath, const CString &sLayer ) if( !ini.GetKey(sLayer) ) RageException::Throw( "The file '%s' doesn't have layer '%s'.", sIniPath.c_str(), sLayer.c_str() ); + CString sDir = Dirname( sIniPath ); + + const IniFile::key* k = ini.GetKey( sLayer ); + if( k == NULL ) + RageException::Throw( "The file '%s' doesn't have layer '%s'.", sIniPath.c_str(), sLayer.c_str() ); + + return LoadFromActorFile( sDir, *k ); +} + +Actor* LoadFromActorFile( const CString& sAniDir, const IniKey& layer ) +{ Actor* pActor = NULL; // fill this in before we return; CString sType; - ini.GetValue( sLayer, "Type", sType ); + layer.GetValue( "Type", sType ); CString sFile; - ini.GetValue( sLayer, "File", sFile ); + layer.GetValue( "File", sFile ); FixSlashesInPlace( sFile ); - CString sDir = Dirname( sIniPath ); if( sType == "SongCreditDisplay" ) { @@ -58,18 +68,18 @@ Actor* LoadFromActorFile( const CString &sIniPath, const CString &sLayer ) /* Be careful: if sFile is "", and we don't check it, then we can end up recursively * loading the BGAnimationLayer that we're in. */ if( sFile == "" ) - RageException::Throw( "The actor file '%s' layer %s is missing File", - sIniPath.c_str(), sLayer.c_str() ); + RageException::Throw( "The actor file in '%s' is missing the File argument", + sAniDir.c_str() ); CString text; - if( ini.GetValue ( sLayer, "Text", text ) ) + if( layer.GetValue("Text", text) ) { /* It's a BitmapText. Note that we could do the actual text setting with metrics, * by adding "text" and "alttext" commands, but right now metrics can't contain * commas or semicolons. It's useful to be able to refer to fonts in the real * theme font dirs, too. */ CString alttext; - ini.GetValue ( sLayer, "AltText", alttext ); + layer.GetValue("AltText", alttext ); text.Replace( "::", "\n" ); alttext.Replace( "::", "\n" ); @@ -164,7 +174,7 @@ Actor* LoadFromActorFile( const CString &sIniPath, const CString &sLayer ) retry: /* XXX: We need to do a theme search, since the file we're loading might * be overridden by the theme. */ - CString sNewPath = sDir+sFile; + CString sNewPath = sAniDir+sFile; // If we know this is an exact match, don't bother with the GetDirListing; // it's causing problems with partial matching BGAnimation directory names. @@ -175,7 +185,7 @@ retry: if( asPaths.empty() ) { - CString sError = ssprintf( "The actor file '%s' references a file '%s' which doesn't exist.", sIniPath.c_str(), sFile.c_str() ); + CString sError = ssprintf( "The actor file in '%s' references a file '%s' which doesn't exist.", sAniDir.c_str(), sFile.c_str() ); switch( Dialog::AbortRetryIgnore( sError, "BROKEN_ACTOR_REFERENCE" ) ) { case Dialog::abort: @@ -195,7 +205,7 @@ retry: } else if( asPaths.size() > 1 ) { - CString sError = ssprintf( "The actor file '%s' references a file '%s' which has multiple matches.", sIniPath.c_str(), sFile.c_str() ); + CString sError = ssprintf( "The actor file in '%s' references a file '%s' which has multiple matches.", sAniDir.c_str(), sFile.c_str() ); switch( Dialog::AbortRetryIgnore( sError, "DUPLICATE_ACTOR_REFERENCE" ) ) { case Dialog::abort: @@ -223,12 +233,12 @@ retry: } float f; - if( ini.GetValue ( sLayer, "BaseRotationXDegrees", f ) ) pActor->SetBaseRotationX( f ); - if( ini.GetValue ( sLayer, "BaseRotationYDegrees", f ) ) pActor->SetBaseRotationY( f ); - if( ini.GetValue ( sLayer, "BaseRotationZDegrees", f ) ) pActor->SetBaseRotationZ( f ); - if( ini.GetValue ( sLayer, "BaseZoomX", f ) ) pActor->SetBaseZoomX( f ); - if( ini.GetValue ( sLayer, "BaseZoomY", f ) ) pActor->SetBaseZoomY( f ); - if( ini.GetValue ( sLayer, "BaseZoomZ", f ) ) pActor->SetBaseZoomZ( f ); + if( layer.GetValue( "BaseRotationXDegrees", f ) ) pActor->SetBaseRotationX( f ); + if( layer.GetValue( "BaseRotationYDegrees", f ) ) pActor->SetBaseRotationY( f ); + if( layer.GetValue( "BaseRotationZDegrees", f ) ) pActor->SetBaseRotationZ( f ); + if( layer.GetValue( "BaseZoomX", f ) ) pActor->SetBaseZoomX( f ); + if( layer.GetValue( "BaseZoomY", f ) ) pActor->SetBaseZoomY( f ); + if( layer.GetValue( "BaseZoomZ", f ) ) pActor->SetBaseZoomZ( f ); ASSERT( pActor ); // we should have filled this in above return pActor; diff --git a/stepmania/src/ActorUtil.h b/stepmania/src/ActorUtil.h index 5547ae968e..c708873b5b 100644 --- a/stepmania/src/ActorUtil.h +++ b/stepmania/src/ActorUtil.h @@ -4,6 +4,7 @@ #include "Actor.h" #include "RageTexture.h" +class IniKey; #define SET_XY( actor ) UtilSetXY( actor, m_sName ) #define ON_COMMAND( actor ) UtilOnCommand( actor, m_sName ) @@ -33,6 +34,7 @@ inline void UtilSetXYAndOnCommand( Actor* pActor, const CString &sClassName ) { // Return a Sprite, BitmapText, or Model depending on the file type Actor* LoadFromActorFile( const CString &sIniPath, const CString &sLayer = "Actor" ); +Actor* LoadFromActorFile( const CString& sAniDir, const IniKey& layer ); Actor* MakeActor( const RageTextureID &ID ); diff --git a/stepmania/src/BGAnimation.cpp b/stepmania/src/BGAnimation.cpp index 342b39d326..4e2bd393bb 100644 --- a/stepmania/src/BGAnimation.cpp +++ b/stepmania/src/BGAnimation.cpp @@ -112,7 +112,7 @@ void AddLayersFromAniDir( CString sAniDir, vector &layersAddTo, bool Gen { // import as a single layer BGAnimationLayer* pLayer = new BGAnimationLayer( Generic ); - pLayer->LoadFromIni( sAniDir, sLayer ); + pLayer->LoadFromIni( sAniDir, *pKey ); layersAddTo.push_back( pLayer ); } } diff --git a/stepmania/src/BGAnimationLayer.cpp b/stepmania/src/BGAnimationLayer.cpp index 6ca1cf7730..385b3754f4 100644 --- a/stepmania/src/BGAnimationLayer.cpp +++ b/stepmania/src/BGAnimationLayer.cpp @@ -126,7 +126,7 @@ void BGAnimationLayer::Init() /* Static background layers are simple, uncomposited background images with nothing * behind them. Since they have nothing behind them, they have no need for alpha, * so turn that off. */ -void BGAnimationLayer::LoadFromStaticGraphic( CString sPath ) +void BGAnimationLayer::LoadFromStaticGraphic( const CString& sPath ) { Init(); Sprite* pSprite = new Sprite; @@ -135,7 +135,7 @@ void BGAnimationLayer::LoadFromStaticGraphic( CString sPath ) m_SubActors.push_back( pSprite ); } -void BGAnimationLayer::LoadFromMovie( CString sMoviePath ) +void BGAnimationLayer::LoadFromMovie( const CString& sMoviePath ) { Init(); Sprite* pSprite = new Sprite; @@ -145,7 +145,7 @@ void BGAnimationLayer::LoadFromMovie( CString sMoviePath ) m_SubActors.push_back( pSprite ); } -void BGAnimationLayer::LoadFromVisualization( CString sMoviePath ) +void BGAnimationLayer::LoadFromVisualization( const CString& sMoviePath ) { Init(); Sprite* pSprite = new Sprite; @@ -156,7 +156,7 @@ void BGAnimationLayer::LoadFromVisualization( CString sMoviePath ) } -void BGAnimationLayer::LoadFromAniLayerFile( CString sPath ) +void BGAnimationLayer::LoadFromAniLayerFile( const CString& sPath ) { /* Generic BGAs are new. Animation directories with no INI are old and obsolete. * Don't combine them. */ @@ -411,61 +411,43 @@ void BGAnimationLayer::LoadFromAniLayerFile( CString sPath ) m_SubActors[i]->SetBlendMode( BLEND_ADD ); } - - -void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) +void BGAnimationLayer::LoadFromIni( const CString& sAniDir_, const IniKey& layer ) { + CString sAniDir = sAniDir_; + Init(); if( sAniDir.Right(1) != "/" ) sAniDir += "/"; - ASSERT( IsADirectory(sAniDir) ); + DEBUG_ASSERT( IsADirectory(sAniDir) ); - CHECKPOINT_M( ssprintf( "BGAnimationLayer::LoadFromIni \"%s\"::%s %s", - sAniDir.c_str(), sLayer.c_str(), m_bGeneric? "(generic) ":"" ) ); + CHECKPOINT_M( ssprintf( "BGAnimationLayer::LoadFromIni \"%s\" %s", + sAniDir.c_str(), m_bGeneric? "(generic) ":"" ) ); - CString sPathToIni = sAniDir + "BGAnimation.ini"; - - IniFile ini; - ini.ReadFile( sPathToIni ); { - // - // Can we ditch this? It's the same as "Condition=IsPlayerEnabled(p)". -Chris - // - int player; - if( ini.GetValue( sLayer, "Player", player ) ) - { - PlayerNumber pn = (PlayerNumber)(player-1); - if( pn>=0 && pnIsPlayerEnabled(pn) ) - return; - } - else - { - LOG->Warn("BGA \"%s\" %s has an invalid Player field", sAniDir.c_str(), sLayer.c_str() ); - } - } + CString sPlayer; + if( layer.GetValue("Player", sPlayer) ) + ASSERT_M( 0, "The BGAnimation parameter 'Player' is deprecated. Please use 'Condition=IsPlayerEnabled(p)'." ); } { CString expr; - if( ini.GetValue(sLayer,"Cond",expr) || ini.GetValue(sLayer,"Condition",expr) ) + if( layer.GetValue("Cond",expr) || layer.GetValue("Condition",expr) ) { if( !Lua::RunExpressionB( expr ) ) return; } } - bool Stretch = false; + bool bStretch = false; { CString type = "sprite"; - ini.GetValue( sLayer, "Type", type ); + layer.GetValue( "Type", type ); type.MakeLower(); /* The preferred way of stretching a sprite to fit the screen is "Type=sprite" * and "stretch=1". "type=1" is for backwards-compatibility. */ - ini.GetValue( sLayer, "Stretch", Stretch ); + layer.GetValue( "Stretch", bStretch ); // Check for string match first, then do integer match. // "if(atoi(type)==0)" was matching against all string matches. @@ -485,7 +467,7 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) else if( atoi(type) == 1 ) { m_Type = TYPE_SPRITE; - Stretch = true; + bStretch = true; } else if( atoi(type) == 2 ) { @@ -502,10 +484,8 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) } { - const IniFile::key *key = ini.GetKey( sLayer ); - if( key ) - for( IniFile::key::const_iterator i = key->begin(); - i != key->end(); ++i) + for( IniKey::const_iterator i = layer.begin(); + i != layer.end(); ++i) { CString KeyName = i->first; /* "OnCommand" */ KeyName.MakeLower(); @@ -525,34 +505,34 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) } - ini.GetValue( sLayer, "CommandRepeatSeconds", m_fRepeatCommandEverySeconds ); + layer.GetValue( "CommandRepeatSeconds", m_fRepeatCommandEverySeconds ); m_fSecondsUntilNextCommand = m_fRepeatCommandEverySeconds; - ini.GetValue( sLayer, "FOV", m_fFOV ); - ini.GetValue( sLayer, "Lighting", m_bLighting ); - ini.GetValue( sLayer, "TexCoordVelocityX", m_fTexCoordVelocityX ); - ini.GetValue( sLayer, "TexCoordVelocityY", m_fTexCoordVelocityY ); - ini.GetValue( sLayer, "DrawCond", m_sDrawCond ); + layer.GetValue( "FOV", m_fFOV ); + layer.GetValue( "Lighting", m_bLighting ); + layer.GetValue( "TexCoordVelocityX", m_fTexCoordVelocityX ); + layer.GetValue( "TexCoordVelocityY", m_fTexCoordVelocityY ); + layer.GetValue( "DrawCond", m_sDrawCond ); // compat: - ini.GetValue( sLayer, "StretchTexCoordVelocityX", m_fTexCoordVelocityX ); - ini.GetValue( sLayer, "StretchTexCoordVelocityY", m_fTexCoordVelocityY ); - ini.GetValue( sLayer, "ZoomMin", m_fZoomMin ); - ini.GetValue( sLayer, "ZoomMax", m_fZoomMax ); - ini.GetValue( sLayer, "VelocityXMin", m_fVelocityXMin ); - ini.GetValue( sLayer, "VelocityXMax", m_fVelocityXMax ); - ini.GetValue( sLayer, "VelocityYMin", m_fVelocityYMin ); - ini.GetValue( sLayer, "VelocityYMax", m_fVelocityYMax ); - ini.GetValue( sLayer, "VelocityZMin", m_fVelocityZMin ); - ini.GetValue( sLayer, "VelocityZMax", m_fVelocityZMax ); - ini.GetValue( sLayer, "OverrideSpeed", m_fOverrideSpeed ); - ini.GetValue( sLayer, "NumParticles", m_iNumParticles ); - ini.GetValue( sLayer, "ParticlesBounce", m_bParticlesBounce ); - ini.GetValue( sLayer, "TilesStartX", m_fTilesStartX ); - ini.GetValue( sLayer, "TilesStartY", m_fTilesStartY ); - ini.GetValue( sLayer, "TilesSpacingX", m_fTilesSpacingX ); - ini.GetValue( sLayer, "TilesSpacingY", m_fTilesSpacingY ); - ini.GetValue( sLayer, "TileVelocityX", m_fTileVelocityX ); - ini.GetValue( sLayer, "TileVelocityY", m_fTileVelocityY ); + layer.GetValue( "StretchTexCoordVelocityX", m_fTexCoordVelocityX ); + layer.GetValue( "StretchTexCoordVelocityY", m_fTexCoordVelocityY ); + layer.GetValue( "ZoomMin", m_fZoomMin ); + layer.GetValue( "ZoomMax", m_fZoomMax ); + layer.GetValue( "VelocityXMin", m_fVelocityXMin ); + layer.GetValue( "VelocityXMax", m_fVelocityXMax ); + layer.GetValue( "VelocityYMin", m_fVelocityYMin ); + layer.GetValue( "VelocityYMax", m_fVelocityYMax ); + layer.GetValue( "VelocityZMin", m_fVelocityZMin ); + layer.GetValue( "VelocityZMax", m_fVelocityZMax ); + layer.GetValue( "OverrideSpeed", m_fOverrideSpeed ); + layer.GetValue( "NumParticles", m_iNumParticles ); + layer.GetValue( "ParticlesBounce", m_bParticlesBounce ); + layer.GetValue( "TilesStartX", m_fTilesStartX ); + layer.GetValue( "TilesStartY", m_fTilesStartY ); + layer.GetValue( "TilesSpacingX", m_fTilesSpacingX ); + layer.GetValue( "TilesSpacingY", m_fTilesSpacingY ); + layer.GetValue( "TileVelocityX", m_fTileVelocityX ); + layer.GetValue( "TileVelocityY", m_fTileVelocityY ); bool NeedTextureStretch = false; @@ -564,11 +544,11 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) { case TYPE_SPRITE: { - Actor* pActor = LoadFromActorFile( sPathToIni, sLayer ); + Actor* pActor = LoadFromActorFile( sAniDir, layer ); m_SubActors.push_back( pActor ); if( !m_bGeneric ) { - if( Stretch ) + if( bStretch ) pActor->StretchTo( FullScreenRectF ); else pActor->SetXY( SCREEN_CENTER_X, SCREEN_CENTER_Y ); @@ -578,7 +558,7 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) case TYPE_PARTICLES: { CString sFile; - ini.GetValue( sLayer, "File", sFile ); + layer.GetValue( "File", sFile ); FixSlashesInPlace( sFile ); CString sPath = sAniDir+sFile; @@ -608,7 +588,7 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) case TYPE_TILES: { CString sFile; - ini.GetValue( sLayer, "File", sFile ); + layer.GetValue( "File", sFile ); FixSlashesInPlace( sFile ); CString sPath = sAniDir+sFile; @@ -641,7 +621,7 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer ) } bool bStartOnRandomFrame = false; - ini.GetValue( sLayer, "StartOnRandomFrame", bStartOnRandomFrame ); + layer.GetValue( "StartOnRandomFrame", bStartOnRandomFrame ); if( bStartOnRandomFrame ) { for( unsigned i=0; i +class IniKey; + class BGAnimationLayer : public ActorFrame { public: @@ -15,11 +17,11 @@ public: void Init(); void Unload(); - void LoadFromStaticGraphic( CString sPath ); - void LoadFromAniLayerFile( CString sPath ); - void LoadFromMovie( CString sMoviePath ); - void LoadFromVisualization( CString sMoviePath ); - void LoadFromIni( CString sDir, CString sLayer ); + void LoadFromStaticGraphic( const CString& sPath ); + void LoadFromAniLayerFile( const CString& sPath ); + void LoadFromMovie( const CString& sMoviePath ); + void LoadFromVisualization( const CString& sMoviePath ); + void LoadFromIni( const CString& sAniDir, const IniKey& layer ); void Update( float fDeltaTime ); void DrawPrimitives(); diff --git a/stepmania/src/IniFile.cpp b/stepmania/src/IniFile.cpp index 6570fc1bad..b9377f799f 100644 --- a/stepmania/src/IniFile.cpp +++ b/stepmania/src/IniFile.cpp @@ -119,28 +119,49 @@ int IniFile::GetNumValues( const CString &keyname ) const return k->second.size(); } -bool IniFile::GetValue( const CString &keyname, const CString &valuename, CString& value ) const +bool IniKey::GetValue( const CString &valuename, CString& value ) const { - keymap::const_iterator k = keys.find(keyname); - if (k == keys.end()) - return false; + const_iterator i = find(valuename); - key::const_iterator i = k->second.find(valuename); - - if( i == k->second.end() ) + if( i == end() ) return false; value = i->second; return true; } +bool IniKey::SetValue( const CString &valuename, const CString &value ) +{ + (*this)[valuename] = value; + return true; +} + +bool IniFile::GetValue( const CString &keyname, const CString &valuename, CString& value ) const +{ + keymap::const_iterator k = keys.find(keyname); + if (k == keys.end()) + return false; + return k->second.GetValue( valuename, value ); +} + bool IniFile::SetValue( const CString &keyname, const CString &valuename, const CString &value ) { - keys[keyname][valuename] = value; + keys[keyname].SetValue( valuename, value ); return true; } #define TYPE(T) \ + bool IniKey::GetValue( const CString &valuename, T &value ) const \ + { \ + CString sValue; \ + if( !GetValue(valuename,sValue) ) \ + return false; \ + return FromString( sValue, value ); \ + } \ + bool IniKey::SetValue( const CString &valuename, T value ) \ + { \ + return SetValue( valuename, ToString(value) ); \ + } \ bool IniFile::GetValue( const CString &keyname, const CString &valuename, T &value ) const \ { \ CString sValue; \ @@ -182,7 +203,7 @@ bool IniFile::DeleteKey(const CString &keyname) return true; } -const IniFile::key *IniFile::GetKey(const CString &keyname) const +const IniKey *IniFile::GetKey(const CString &keyname) const { keymap::const_iterator i = keys.find(keyname); if( i == keys.end() ) diff --git a/stepmania/src/IniFile.h b/stepmania/src/IniFile.h index 0d84c66869..13ce988cfc 100644 --- a/stepmania/src/IniFile.h +++ b/stepmania/src/IniFile.h @@ -8,12 +8,27 @@ using namespace std; class RageFileBasic; +class IniKey : public map +{ +public: + bool GetValue( const CString &valuename, CString& value ) const; + bool GetValue( const CString &valuename, int& value ) const; + bool GetValue( const CString &valuename, unsigned& value ) const; + bool GetValue( const CString &valuename, float& value ) const; + bool GetValue( const CString &valuename, bool& value ) const; + + bool SetValue( const CString &valuename, const CString &value ); + bool SetValue( const CString &valuename, int value ); + bool SetValue( const CString &valuename, unsigned value ); + bool SetValue( const CString &valuename, float value ); + bool SetValue( const CString &valuename, bool value ); +}; + class IniFile { public: // all keys are of this type - - typedef map key; + typedef IniKey key; typedef map keymap; typedef keymap::const_iterator const_iterator;