Autosave completed but not tested.
This commit is contained in:
@@ -97,6 +97,7 @@ Create=Create New
|
||||
Delete=Delete Existing
|
||||
Edit=Edit Existing
|
||||
Practice=Practice
|
||||
LoadAutosave=Load Autosave
|
||||
|
||||
[EditMenu]
|
||||
Blank=Blank
|
||||
|
||||
@@ -31,6 +31,7 @@ static const char *EditMenuActionNames[] = {
|
||||
"Delete",
|
||||
"Create",
|
||||
"Practice",
|
||||
"LoadAutosave",
|
||||
};
|
||||
XToString( EditMenuAction );
|
||||
XToLocalizedString( EditMenuAction );
|
||||
@@ -659,6 +660,12 @@ void EditMenu::OnRowValueChanged( EditMenuRow row )
|
||||
m_StepsDisplaySource.SetVisible( !(bHideMeter || GetSelectedSteps()) );
|
||||
|
||||
m_Actions.clear();
|
||||
// Stick autosave in the list first so that people will see it. -Kyz
|
||||
Song* cur_song= GetSelectedSong();
|
||||
if(cur_song != NULL && cur_song->HasAutosaveFile() && !cur_song->WasLoadedFromAutosave())
|
||||
{
|
||||
m_Actions.push_back(EditMenuAction_LoadAutosave);
|
||||
}
|
||||
if( GetSelectedSteps() )
|
||||
{
|
||||
switch( mode )
|
||||
|
||||
@@ -42,6 +42,7 @@ enum EditMenuAction
|
||||
EditMenuAction_Delete, /**< Remove the current step from the Song. */
|
||||
EditMenuAction_Create, /**< Create a new step for the Song. */
|
||||
EditMenuAction_Practice, /**< Practice the current step for the Song. */
|
||||
EditMenuAction_LoadAutosave,
|
||||
NUM_EditMenuAction, /**< The number of MenuActions available to choose from. */
|
||||
EditMenuAction_Invalid
|
||||
};
|
||||
|
||||
+3
-3
@@ -25,16 +25,16 @@ void NotesLoader::GetMainAndSubTitlesFromFullTitle( const RString &sFullTitle, R
|
||||
sSubTitleOut = "";
|
||||
};
|
||||
|
||||
bool NotesLoader::LoadFromDir( const RString &sPath, Song &out, set<RString> &BlacklistedImages )
|
||||
bool NotesLoader::LoadFromDir( const RString &sPath, Song &out, set<RString> &BlacklistedImages, bool load_autosave )
|
||||
{
|
||||
vector<RString> list;
|
||||
|
||||
BlacklistedImages.clear();
|
||||
SSCLoader loaderSSC;
|
||||
loaderSSC.GetApplicableFiles( sPath, list );
|
||||
loaderSSC.GetApplicableFiles( sPath, list, load_autosave );
|
||||
if( !list.empty() )
|
||||
{
|
||||
if( !loaderSSC.LoadFromDir( sPath, out ) )
|
||||
if( !loaderSSC.LoadFromDir( sPath, out, load_autosave ) )
|
||||
return false;
|
||||
loaderSSC.TidyUpData( out, false );
|
||||
return true;
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ namespace NotesLoader
|
||||
* @param out the Song in question.
|
||||
* @param BlacklistedImages images to exclude (DWI files only for some reason).
|
||||
* @return its success or failure. */
|
||||
bool LoadFromDir( const RString &sPath, Song &out, set<RString> &BlacklistedImages );
|
||||
bool LoadFromDir( const RString &sPath, Song &out, set<RString> &BlacklistedImages, bool load_autosave= false );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+11
-5
@@ -23,10 +23,10 @@ RString SMLoader::GetSongTitle() const
|
||||
return this->songTitle;
|
||||
}
|
||||
|
||||
bool SMLoader::LoadFromDir( const RString &sPath, Song &out )
|
||||
bool SMLoader::LoadFromDir( const RString &sPath, Song &out, bool load_autosave )
|
||||
{
|
||||
vector<RString> aFileNames;
|
||||
GetApplicableFiles( sPath, aFileNames );
|
||||
GetApplicableFiles( sPath, aFileNames, load_autosave );
|
||||
return LoadFromSimfile( sPath + aFileNames[0], out );
|
||||
}
|
||||
|
||||
@@ -1217,10 +1217,16 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath
|
||||
return false;
|
||||
}
|
||||
|
||||
void SMLoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
|
||||
void SMLoader::GetApplicableFiles( const RString &sPath, vector<RString> &out, bool load_autosave )
|
||||
{
|
||||
GetDirListing( sPath + RString("*.ats" ), out );
|
||||
GetDirListing( sPath + RString("*" + this->GetFileExtension() ), out );
|
||||
if(load_autosave)
|
||||
{
|
||||
GetDirListing( sPath + RString("*.ats" ), out );
|
||||
}
|
||||
else
|
||||
{
|
||||
GetDirListing( sPath + RString("*" + this->GetFileExtension() ), out );
|
||||
}
|
||||
}
|
||||
|
||||
void SMLoader::TidyUpData( Song &song, bool bFromCache )
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ struct SMLoader
|
||||
* @param out a reference to the Song that will retrieve the song information.
|
||||
* @return its success or failure.
|
||||
*/
|
||||
virtual bool LoadFromDir( const RString &sPath, Song &out );
|
||||
virtual bool LoadFromDir( const RString &sPath, Song &out, bool load_autosave= false );
|
||||
/**
|
||||
* @brief Perform some cleanup on the loaded song.
|
||||
* @param song a reference to the song that may need cleaning up.
|
||||
@@ -61,7 +61,7 @@ struct SMLoader
|
||||
* @param sPath a const reference to the path on the hard drive to check.
|
||||
* @param out a vector of files found in the path.
|
||||
*/
|
||||
virtual void GetApplicableFiles( const RString &sPath, vector<RString> &out );
|
||||
virtual void GetApplicableFiles( const RString &sPath, vector<RString> &out, bool load_autosave= false );
|
||||
virtual bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL );
|
||||
virtual bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot, Song *givenSong=NULL );
|
||||
virtual bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL );
|
||||
|
||||
@@ -724,6 +724,10 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
|
||||
bHasOwnTiming = false;
|
||||
pNewNotes->SetSMNoteData( sParams[1] );
|
||||
pNewNotes->TidyUpData();
|
||||
// Unlike the song and timing filenames, the steps filenames do
|
||||
// need to point to the autosave file if that's where they were
|
||||
// loaded from, because that's where the actual steps data is.
|
||||
// -Kyz
|
||||
pNewNotes->SetFilename(sPath);
|
||||
out.AddSteps( pNewNotes );
|
||||
}
|
||||
|
||||
+2
-1
@@ -4187,6 +4187,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
return;
|
||||
case ANSWER_NO:
|
||||
// Don't save; just exit.
|
||||
m_pSong->RemoveAutosave();
|
||||
SCREENMAN->SendMessageToTopScreen( SM_DoExit );
|
||||
return;
|
||||
case ANSWER_CANCEL:
|
||||
@@ -4207,7 +4208,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
}
|
||||
else if( SM == SM_AutoSaveSuccessful )
|
||||
{
|
||||
LOG->Trace( "AutoSave successful." );
|
||||
LOG->Trace("AutoSave successful.");
|
||||
m_next_autosave_time= RageTimer::GetTimeSinceStartFast() + time_between_autosave;
|
||||
SCREENMAN->SystemMessage(AUTOSAVE_SUCCESSFUL);
|
||||
}
|
||||
|
||||
@@ -266,6 +266,18 @@ bool ScreenEditMenu::MenuStart( const InputEventPlus & )
|
||||
ScreenPrompt::Prompt( SM_None, STEPS_WILL_BE_LOST.GetValue() + "\n\n" + CONTINUE_WITH_DELETE.GetValue(),
|
||||
PROMPT_YES_NO, ANSWER_NO );
|
||||
break;
|
||||
case EditMenuAction_LoadAutosave:
|
||||
if(pSong)
|
||||
{
|
||||
FOREACH_PlayerNumber(pn)
|
||||
{
|
||||
GAMESTATE->m_pCurSteps[pn].Set(NULL);
|
||||
}
|
||||
pSong->LoadAutosaveFile();
|
||||
SONGMAN->Invalidate(pSong);
|
||||
SCREENMAN->SendMessageToTopScreen( SM_RefreshSelector );
|
||||
}
|
||||
break;
|
||||
case EditMenuAction_Create:
|
||||
ASSERT( !pSteps );
|
||||
{
|
||||
@@ -344,6 +356,7 @@ bool ScreenEditMenu::MenuStart( const InputEventPlus & )
|
||||
}
|
||||
return true;
|
||||
case EditMenuAction_Delete:
|
||||
case EditMenuAction_LoadAutosave:
|
||||
return true;
|
||||
default:
|
||||
FAIL_M(ssprintf("Invalid edit menu action: %i", action));
|
||||
|
||||
+75
-16
@@ -83,6 +83,7 @@ Song::Song()
|
||||
m_bHasMusic = false;
|
||||
m_bHasBanner = false;
|
||||
m_bHasBackground = false;
|
||||
m_loaded_from_autosave= false;
|
||||
}
|
||||
|
||||
Song::~Song()
|
||||
@@ -266,7 +267,7 @@ static set<RString> BlacklistedImages;
|
||||
* HasMusic(), HasBanner() or GetHashForDirectory().
|
||||
* If true, check the directory hash and reload the song from scratch if it's changed.
|
||||
*/
|
||||
bool Song::LoadFromSongDir( RString sDir )
|
||||
bool Song::LoadFromSongDir( RString sDir, bool load_autosave )
|
||||
{
|
||||
// LOG->Trace( "Song::LoadFromSongDir(%s)", sDir.c_str() );
|
||||
ASSERT_M( sDir != "", "Songs can't be loaded from an empty directory!" );
|
||||
@@ -293,7 +294,9 @@ bool Song::LoadFromSongDir( RString sDir )
|
||||
if( !DoesFileExist(sCacheFilePath) )
|
||||
bUseCache = false;
|
||||
if( !PREFSMAN->m_bFastLoad && GetHashForDirectory(m_sSongDir) != uCacheHash )
|
||||
bUseCache = false; // this cache is out of date
|
||||
bUseCache = false; // this cache is out of date
|
||||
if(load_autosave)
|
||||
{ bUseCache= false; }
|
||||
|
||||
if( bUseCache )
|
||||
{
|
||||
@@ -317,7 +320,7 @@ bool Song::LoadFromSongDir( RString sDir )
|
||||
// There was no entry in the cache for this song, or it was out of date.
|
||||
// Let's load it from a file, then write a cache entry.
|
||||
|
||||
if( !NotesLoader::LoadFromDir(sDir, *this, BlacklistedImages) )
|
||||
if(!NotesLoader::LoadFromDir(sDir, *this, BlacklistedImages, load_autosave))
|
||||
{
|
||||
LOG->UserLog( "Song", sDir, "has no SSC, SM, SMA, DWI, BMS, or KSF files." );
|
||||
|
||||
@@ -341,9 +344,14 @@ bool Song::LoadFromSongDir( RString sDir )
|
||||
}
|
||||
TidyUpData(false, true);
|
||||
|
||||
// save a cache file so we don't have to parse it all over again next time
|
||||
if( !SaveToCacheFile() )
|
||||
sCacheFilePath = RString();
|
||||
// Don't save a cache file if the autosave is being loaded, because the
|
||||
// cache file would contain the autosave filename. -Kyz
|
||||
if(!load_autosave)
|
||||
{
|
||||
// save a cache file so we don't have to parse it all over again next time
|
||||
if(!SaveToCacheFile())
|
||||
{ sCacheFilePath = RString(); }
|
||||
}
|
||||
}
|
||||
|
||||
FOREACH( Steps*, m_vpSteps, s )
|
||||
@@ -461,6 +469,43 @@ bool Song::ReloadFromSongDir( RString sDir )
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Song::HasAutosaveFile()
|
||||
{
|
||||
if(m_sSongFileName.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
RString autosave_path= SetExtension(m_sSongFileName, "ats");
|
||||
return FILEMAN->DoesFileExist(autosave_path);
|
||||
}
|
||||
|
||||
bool Song::LoadAutosaveFile()
|
||||
{
|
||||
if(m_sSongFileName.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Save these strings because they need to be restored after the reset.
|
||||
// The filenames need to point to the original instead of the autosave for
|
||||
// things like load from disk to work. -Kyz
|
||||
RString dir= GetSongDir();
|
||||
RString song_timing_file= m_SongTiming.m_sFile;
|
||||
RString song_file= m_sSongFileName;
|
||||
// Reset needs to be used to remove all the steps and other things that
|
||||
// will be loaded from the autosave. -Kyz
|
||||
Reset();
|
||||
if(LoadFromSongDir(dir, true))
|
||||
{
|
||||
m_loaded_from_autosave= true;
|
||||
m_sSongFileName= song_file;
|
||||
m_SongTiming.m_sFile= song_timing_file;
|
||||
return true;
|
||||
}
|
||||
// Loading the autosave failed, reload the original. -Kyz
|
||||
LoadFromSongDir(dir, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void GetImageDirListing( RString sPath, vector<RString> &AddTo )
|
||||
{
|
||||
GetDirListing( sPath + ".png", AddTo, false, false );
|
||||
@@ -1001,12 +1046,13 @@ void Song::Save(bool autosave)
|
||||
// Save the new files. These calls make backups on their own.
|
||||
if( !SaveToSSCFile(GetSongFilePath(), false, autosave) )
|
||||
return;
|
||||
SaveToCacheFile();
|
||||
// Skip saving the sm and .old files if we are autosaving. -Kyz
|
||||
// Skip saving the cache, sm, and .old files if we are autosaving. The
|
||||
// cache file should not contain the autosave filename. -Kyz
|
||||
if(autosave)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SaveToCacheFile();
|
||||
SaveToSMFile();
|
||||
//SaveToDWIFile();
|
||||
|
||||
@@ -1107,14 +1153,7 @@ bool Song::SaveToSSCFile( RString sPath, bool bSavingCache, bool autosave )
|
||||
if( !NotesWriterSSC::Write(path, *this, vpStepsToSave, bSavingCache) )
|
||||
return false;
|
||||
|
||||
// Remove the autosave file so that edit mode won't auto load it. -Kyz
|
||||
RString autosave_path= sPath;
|
||||
SetExtension(autosave_path, "ats");
|
||||
if(FILEMAN->DoesFileExist(autosave_path))
|
||||
{
|
||||
FILEMAN->Remove(autosave_path);
|
||||
}
|
||||
|
||||
RemoveAutosave();
|
||||
|
||||
if( g_BackUpAllSongSaves.Get() )
|
||||
{
|
||||
@@ -1169,6 +1208,26 @@ bool Song::SaveToDWIFile()
|
||||
return NotesWriterDWI::Write( sPath, *this );
|
||||
}
|
||||
|
||||
void Song::RemoveAutosave()
|
||||
{
|
||||
RString autosave_path= SetExtension(m_sSongFileName, "ats");
|
||||
if(FILEMAN->DoesFileExist(autosave_path))
|
||||
{
|
||||
// Change all the steps to point to the actual file, not the autosave
|
||||
// file. -Kyz
|
||||
RString extension= GetExtension(m_sSongFileName);
|
||||
for(size_t i= 0; i < m_vpSteps.size(); ++i)
|
||||
{
|
||||
if(!m_vpSteps[i]->IsAutogen())
|
||||
{
|
||||
m_vpSteps[i]->SetFilename(
|
||||
SetExtension(m_vpSteps[i]->GetFilename(), extension));
|
||||
}
|
||||
}
|
||||
FILEMAN->Remove(autosave_path);
|
||||
m_loaded_from_autosave= false;
|
||||
}
|
||||
}
|
||||
|
||||
void Song::AddAutoGenNotes()
|
||||
{
|
||||
|
||||
+7
-2
@@ -87,10 +87,13 @@ public:
|
||||
*
|
||||
* This assumes that there is no song present right now.
|
||||
* @param sDir the song directory from which to load. */
|
||||
bool LoadFromSongDir( RString sDir );
|
||||
bool LoadFromSongDir( RString sDir, bool load_autosave= false );
|
||||
// This one takes the effort to reuse Steps pointers as best as it can
|
||||
bool ReloadFromSongDir( RString sDir );
|
||||
|
||||
bool HasAutosaveFile();
|
||||
bool LoadAutosaveFile();
|
||||
|
||||
/**
|
||||
* @brief Call this after loading a song to clean up invalid data.
|
||||
* @param fromCache was this data loaded from the cache file?
|
||||
@@ -133,8 +136,9 @@ public:
|
||||
* @return its success or failure. */
|
||||
bool SaveToDWIFile();
|
||||
|
||||
void RemoveAutosave();
|
||||
bool WasLoadedFromAutosave() const
|
||||
{ return GetExtension(m_sSongFileName) == "ats"; }
|
||||
{ return m_loaded_from_autosave; }
|
||||
|
||||
const RString &GetSongFilePath() const;
|
||||
RString GetCacheFilePath() const;
|
||||
@@ -450,6 +454,7 @@ public:
|
||||
void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
bool m_loaded_from_autosave;
|
||||
/** @brief the Steps that belong to this Song. */
|
||||
vector<Steps*> m_vpSteps;
|
||||
/** @brief the Steps of a particular StepsType that belong to this Song. */
|
||||
|
||||
Reference in New Issue
Block a user