Autosave completed but not tested.

This commit is contained in:
Kyzentun
2015-02-27 10:36:17 -07:00
parent 064aead73c
commit ddb1683bb7
12 changed files with 127 additions and 30 deletions
+1
View File
@@ -97,6 +97,7 @@ Create=Create New
Delete=Delete Existing
Edit=Edit Existing
Practice=Practice
LoadAutosave=Load Autosave
[EditMenu]
Blank=Blank
+7
View File
@@ -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 )
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 );
+4
View File
@@ -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
View File
@@ -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);
}
+13
View File
@@ -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
View File
@@ -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
View File
@@ -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. */