From a3dc5596de57230e1445aac4fc91b10316261513 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 18 Jan 2006 01:34:45 +0000 Subject: [PATCH] OptionRow::Reload doesn't take an OptionRowDefinition. Implement Reload() explicitly, so we can clearly short- circuit for static rows. Fix up ScreenOptionsEditCourseEntry (broken during the course of things). --- stepmania/src/OptionRow.cpp | 10 +- stepmania/src/OptionRow.h | 2 +- stepmania/src/OptionRowHandler.h | 14 +- .../src/ScreenOptionsEditCourseEntry.cpp | 151 ++++++++++++------ stepmania/src/ScreenOptionsEditCourseEntry.h | 6 +- 5 files changed, 124 insertions(+), 59 deletions(-) diff --git a/stepmania/src/OptionRow.cpp b/stepmania/src/OptionRow.cpp index 8387bd1675..5d60dc7205 100644 --- a/stepmania/src/OptionRow.cpp +++ b/stepmania/src/OptionRow.cpp @@ -877,7 +877,7 @@ void OptionRow::SetExitText( CString sExitText ) bt->SetText( sExitText ); } -void OptionRow::Reload( const OptionRowDefinition &def ) +void OptionRow::Reload() { switch( GetRowType() ) { @@ -895,10 +895,8 @@ void OptionRow::Reload( const OptionRowDefinition &def ) // ExportOptions( vpns, bRowHasFocus ); //} - if( m_pHand == NULL ) - m_pHand->m_Def = def; - else - m_pHand->Reload(); + if( !m_pHand->Reload() ) + break; m_pHand->m_Def = m_pHand->m_Def; ASSERT( !m_pHand->m_Def.m_vsChoices.empty() ); @@ -953,7 +951,7 @@ void OptionRow::Reload( const OptionRowDefinition &def ) void OptionRow::HandleMessage( const CString& sMessage ) { - Reload( m_pHand->m_Def ); + Reload(); } diff --git a/stepmania/src/OptionRow.h b/stepmania/src/OptionRow.h index 72737b4845..d825bed648 100644 --- a/stepmania/src/OptionRow.h +++ b/stepmania/src/OptionRow.h @@ -189,7 +189,7 @@ public: void SetExitText( CString sExitText ); - void Reload( const OptionRowDefinition &def ); + void Reload(); // // Messages diff --git a/stepmania/src/OptionRowHandler.h b/stepmania/src/OptionRowHandler.h index 42e70e21d0..76d3a29fd8 100644 --- a/stepmania/src/OptionRowHandler.h +++ b/stepmania/src/OptionRowHandler.h @@ -32,7 +32,19 @@ public: this->LoadInternal( cmds ); } virtual void LoadInternal( const Commands &cmds ) = 0; - virtual void Reload() { this->Load(m_cmds); } + + /* + * We may re-use OptionRowHandlers. This is called before each + * use. If the contents of the row are dependent on external + * state (for example, the current song), clear the row contents + * and reinitialize them. As an optimization, rows which do not + * change can be initialized just once and left alone. + * + * If the row has been reinitialized, return true, and the graphic + * elements will also be reinitialized. If the row is static, and + * nothing has changed, return false. + */ + virtual bool Reload() { return false; } virtual void ImportOption( const OptionRowDefinition &row, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const = 0; /* Returns an OPT mask. */ virtual int ExportOption( const OptionRowDefinition &def, const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const = 0; diff --git a/stepmania/src/ScreenOptionsEditCourseEntry.cpp b/stepmania/src/ScreenOptionsEditCourseEntry.cpp index aebc7e40d6..2e31e9a74e 100644 --- a/stepmania/src/ScreenOptionsEditCourseEntry.cpp +++ b/stepmania/src/ScreenOptionsEditCourseEntry.cpp @@ -46,23 +46,61 @@ static void FillSongsAndChoices( const CString &sSongGroup, vector &vpSon } +class OptionRowHandlerSongChoices: public OptionRowHandler +{ +public: + // corresponds with m_vsChoices: + vector m_vpDisplayedSongs; + CString m_sSongGroup; + + OptionRowHandlerSongChoices() { Init(); } + void Init() + { + OptionRowHandler::Init(); + m_vpDisplayedSongs.clear(); + } + virtual void LoadInternal( const Commands &cmds ) + { + FillSongsAndChoices( m_sSongGroup, m_vpDisplayedSongs, m_Def.m_vsChoices ); + } + + virtual bool Reload() + { + FillSongsAndChoices( m_sSongGroup, m_vpDisplayedSongs, m_Def.m_vsChoices ); + return true; + } + + virtual void ImportOption( const OptionRowDefinition &row, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + { + vector::const_iterator iter = find( m_vpDisplayedSongs.begin(), m_vpDisplayedSongs.end(), GAMESTATE->m_pCurSong ); + int iChoice = 0; + if( iter != m_vpDisplayedSongs.end() ) + iChoice = iter - m_vpDisplayedSongs.begin(); + FOREACH_PlayerNumber(pn) + vbSelectedOut[pn][iChoice] = true; + } + virtual int ExportOption( const OptionRowDefinition &def, const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const + { + for( size_t iChoice = 0; iChoice < vbSelected[PLAYER_1].size(); ++iChoice ) + { + if( vbSelected[PLAYER_1][iChoice] ) + { + GAMESTATE->m_pCurSong.Set( m_vpDisplayedSongs[iChoice] ); + return 0; + } + } + + return 0; + } +}; + REGISTER_SCREEN_CLASS( ScreenOptionsEditCourseEntry ); void ScreenOptionsEditCourseEntry::Init() { ScreenOptions::Init(); -} - -void ScreenOptionsEditCourseEntry::BeginScreen() -{ - // save a backup that we'll use if we revert. - Course *pCourse = GAMESTATE->m_pCurCourse; - const CourseEntry &ce = pCourse->m_vEntries[ GAMESTATE->m_iEditCourseEntryIndex ]; - m_Original = ce; - vector vHands; - OptionRowHandler *pHand = OptionRowHandlerUtil::MakeNull(); pHand->m_Def.m_sName = "Song Group"; pHand->m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; @@ -75,13 +113,15 @@ void ScreenOptionsEditCourseEntry::BeginScreen() pHand->m_Def.m_vsChoices.push_back( *song ); vHands.push_back( pHand ); - pHand = OptionRowHandlerUtil::MakeNull(); - pHand->m_Def.m_sName = "Song"; - pHand->m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; - pHand->m_Def.m_bExportOnChange = true; - pHand->m_Def.m_vsChoices.clear(); - FillSongsAndChoices( ce.sSongGroup, m_vpDisplayedSongs, pHand->m_Def.m_vsChoices ); - vHands.push_back( pHand ); + { + m_pSongHandler = new OptionRowHandlerSongChoices; + // m_pSongHandler->m_sSongGroup = ce.sSongGroup; + m_pSongHandler->Load( Commands() ); + m_pSongHandler->m_Def.m_sName = "Song"; + m_pSongHandler->m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; + m_pSongHandler->m_Def.m_bExportOnChange = true; + vHands.push_back( m_pSongHandler ); + } pHand = OptionRowHandlerUtil::MakeNull(); pHand->m_Def.m_sName = "Base Difficulty"; @@ -131,16 +171,29 @@ void ScreenOptionsEditCourseEntry::BeginScreen() pHand->m_Def.m_vsChoices.push_back( FormatNumberAndSuffix(i+1) ); vHands.push_back( pHand ); - pHand = OptionRowHandlerUtil::MakeNull(); - pHand->m_Def.m_sName = "Set Mods"; - pHand->m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; - pHand->m_Def.m_bExportOnChange = true; - pHand->m_Def.m_vsChoices.clear(); - CString s = ssprintf( "%d mod changes", ce.GetNumModChanges() ); - pHand->m_Def.m_vsChoices.push_back( s ); - vHands.push_back( pHand ); + m_pModChangesHandler = OptionRowHandlerUtil::MakeNull(); + m_pModChangesHandler->m_Def.m_sName = "Set Mods"; + m_pModChangesHandler->m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; + m_pModChangesHandler->m_Def.m_bExportOnChange = true; + m_pModChangesHandler->m_Def.m_vsChoices.clear(); + m_pModChangesHandler->m_Def.m_vsChoices.push_back( "" ); + vHands.push_back( m_pModChangesHandler ); ScreenOptions::InitMenu( vHands ); +} + +void ScreenOptionsEditCourseEntry::BeginScreen() +{ + // save a backup that we'll use if we revert. + const Course *pCourse = GAMESTATE->m_pCurCourse; + const CourseEntry &ce = pCourse->m_vEntries[ GAMESTATE->m_iEditCourseEntryIndex ]; + m_Original = ce; + + + m_pSongHandler->m_sSongGroup = ce.sSongGroup; + + CString s = ssprintf( "%d mod changes", ce.GetNumModChanges() ); + m_pModChangesHandler->m_Def.m_vsChoices[0] = s; ScreenOptions::BeginScreen(); } @@ -214,22 +267,12 @@ void ScreenOptionsEditCourseEntry::AfterChangeValueInRow( int iRow, PlayerNumber vpns.push_back( PLAYER_1 ); ExportOptions( ROW_SONG_GROUP, vpns ); + m_pSongHandler->m_sSongGroup = ce.sSongGroup; + OptionRow &row = *m_pRows[ROW_SONG]; - OptionRowDefinition def = row.GetRowDef(); - FillSongsAndChoices( ce.sSongGroup, m_vpDisplayedSongs, def.m_vsChoices ); - - row.Reload( def ); - - vector::const_iterator iter = find( m_vpDisplayedSongs.begin(), m_vpDisplayedSongs.end(), ce.pSong ); - if( iter == m_vpDisplayedSongs.end() ) - { - this->ChangeValueInRowAbsolute( ROW_SONG, PLAYER_1, 0, false ); - } - else - { - int iSongIndex = iter - m_vpDisplayedSongs.begin(); - this->ChangeValueInRowAbsolute( ROW_SONG, PLAYER_1, iSongIndex, false ); - } + row.Reload(); + ImportOptions( ROW_SONG, vpns ); + row.AfterImportOptions(); } break; } @@ -266,12 +309,13 @@ void ScreenOptionsEditCourseEntry::ImportOptions( int iRow, const vector::const_iterator iter = find( m_vpDisplayedSongs.begin(), m_vpDisplayedSongs.end(), ce.pSong ); - int iChoice = 0; - if( iter != m_vpDisplayedSongs.end() ) - iChoice = iter - m_vpDisplayedSongs.begin(); - OptionRow &row = *m_pRows[ROW_SONG]; - row.SetOneSharedSelection( iChoice ); + GAMESTATE->m_pCurSong.Set( ce.pSong ); + + // XXX: copy and pasted from ScreenOptionsMaster + FOREACH_CONST( PlayerNumber, vpns, pn ) + ASSERT( GAMESTATE->IsHumanPlayer(*pn) ); + OptionRow &row = *m_pRows[iRow]; + row.ImportOptions( vpns ); } break; case ROW_BASE_DIFFICULTY: @@ -339,9 +383,18 @@ void ScreenOptionsEditCourseEntry::ExportOptions( int iRow, const vectorm_MasterPlayerNumber ); - ce.pSong = m_vpDisplayedSongs[iChoice]; + // XXX: copy and pasted from ScreenOptionsMaster + OptionRow &row = *m_pRows[iRow]; + bool bRowHasFocus[NUM_PLAYERS]; + ZERO( bRowHasFocus ); + FOREACH_CONST( PlayerNumber, vpns, p ) + { + int iCurRow = m_iCurrentRow[*p]; + bRowHasFocus[*p] = iCurRow == iRow; + } + row.ExportOptions( vpns, bRowHasFocus ); + + ce.pSong = GAMESTATE->m_pCurSong; } break; case ROW_BASE_DIFFICULTY: diff --git a/stepmania/src/ScreenOptionsEditCourseEntry.h b/stepmania/src/ScreenOptionsEditCourseEntry.h index 51d0339501..5b6eaf51d1 100644 --- a/stepmania/src/ScreenOptionsEditCourseEntry.h +++ b/stepmania/src/ScreenOptionsEditCourseEntry.h @@ -5,6 +5,8 @@ #include "Course.h" class Song; +class OptionRowHandler; +class OptionRowHandlerSongChoices; class ScreenOptionsEditCourseEntry : public ScreenOptionsEditCourseSubMenu { public: @@ -14,6 +16,8 @@ public: virtual void HandleScreenMessage( const ScreenMessage SM ); protected: + OptionRowHandler *m_pModChangesHandler; + OptionRowHandlerSongChoices *m_pSongHandler; virtual void ImportOptions( int iRow, const vector &vpns ); virtual void ExportOptions( int iRow, const vector &vpns ); @@ -21,8 +25,6 @@ protected: virtual void AfterChangeValueInRow( int iRow, PlayerNumber pn ); virtual void ProcessMenuStart( const InputEventPlus &input ); - vector m_vpDisplayedSongs; // corresponds with the choices in the Song row - CourseEntry m_Original; // use this to revert when cancelling };