@@ -1840,6 +1840,7 @@ public bool RunLibretroCoreChooser()
18401840
18411841 // countdown for saveram autoflushing
18421842 public int AutoFlushSaveRamIn { get ; set ; }
1843+ private bool AutoFlushSaveRamFailed ;
18431844
18441845 private void SetStatusBar ( )
18451846 {
@@ -2063,7 +2064,7 @@ private void LoadSaveRam()
20632064 }
20642065 }
20652066
2066- public bool FlushSaveRAM ( bool autosave = false )
2067+ public FileWriteResult FlushSaveRAM ( bool autosave = false )
20672068 {
20682069 if ( Emulator . HasSaveRam ( ) )
20692070 {
@@ -2077,51 +2078,11 @@ public bool FlushSaveRAM(bool autosave = false)
20772078 path = Config . PathEntries . SaveRamAbsolutePath ( Game , MovieSession . Movie ) ;
20782079 }
20792080
2080- var file = new FileInfo ( path ) ;
2081- var newPath = $ "{ path } .new";
2082- var newFile = new FileInfo ( newPath ) ;
2083- var backupPath = $ "{ path } .bak";
2084- var backupFile = new FileInfo ( backupPath ) ;
2085-
20862081 var saveram = Emulator . AsSaveRam ( ) . CloneSaveRam ( ) ! ;
2087-
2088- try
2089- {
2090- Directory . CreateDirectory ( file . DirectoryName ! ) ;
2091- using ( var fs = File . Create ( newPath ) )
2092- {
2093- fs . Write ( saveram , 0 , saveram . Length ) ;
2094- fs . Flush ( flushToDisk : true ) ;
2095- }
2096-
2097- if ( file . Exists )
2098- {
2099- if ( Config . BackupSaveram )
2100- {
2101- if ( backupFile . Exists )
2102- {
2103- backupFile . Delete ( ) ;
2104- }
2105-
2106- file . MoveTo ( backupPath ) ;
2107- }
2108- else
2109- {
2110- file . Delete ( ) ;
2111- }
2112- }
2113-
2114- newFile . MoveTo ( path ) ;
2115- }
2116- catch ( IOException e )
2117- {
2118- AddOnScreenMessage ( "Failed to flush saveram!" ) ;
2119- Console . Error . WriteLine ( e ) ;
2120- return false ;
2121- }
2082+ return FileWriter . Write ( path , saveram , $ "{ path } .bak") ;
21222083 }
21232084
2124- return true ;
2085+ return new ( ) ;
21252086 }
21262087
21272088 private void RewireSound ( )
@@ -3180,8 +3141,22 @@ private void StepRunLoop_Core(bool force = false)
31803141 AutoFlushSaveRamIn -- ;
31813142 if ( AutoFlushSaveRamIn <= 0 )
31823143 {
3183- FlushSaveRAM ( true ) ;
3184- AutoFlushSaveRamIn = Config . FlushSaveRamFrames ;
3144+ FileWriteResult result = FlushSaveRAM ( true ) ;
3145+ if ( result . IsError )
3146+ {
3147+ // For autosave, allow one failure before bothering the user.
3148+ if ( AutoFlushSaveRamFailed )
3149+ {
3150+ this . ErrorMessageBox ( result , "Failed to flush saveram!" ) ;
3151+ }
3152+ AutoFlushSaveRamFailed = true ;
3153+ AutoFlushSaveRamIn = Math . Min ( 600 , Config . FlushSaveRamFrames ) ;
3154+ }
3155+ else
3156+ {
3157+ AutoFlushSaveRamFailed = false ;
3158+ AutoFlushSaveRamIn = Config . FlushSaveRamFrames ;
3159+ }
31853160 }
31863161 }
31873162 // why not skip audio if the user doesn't want sound
@@ -4101,41 +4076,34 @@ private bool CloseGame(bool clearSram = false)
41014076 var path = Config . PathEntries . SaveRamAbsolutePath ( Game , MovieSession . Movie ) ;
41024077 if ( File . Exists ( path ) )
41034078 {
4104- File . Delete ( path ) ;
4105- AddOnScreenMessage ( "SRAM cleared." ) ;
4079+ bool clearResult = this . DoWithTryAgainBox ( ( ) => {
4080+ try
4081+ {
4082+ File . Delete ( path ) ;
4083+ AddOnScreenMessage ( "SRAM cleared." ) ;
4084+ return new ( ) ;
4085+ }
4086+ catch ( Exception ex )
4087+ {
4088+ return new ( FileWriteEnum . FailedToDeleteGeneric , new ( path , "" ) , ex ) ;
4089+ }
4090+ } , "Failed to clear SRAM." ) ;
4091+ if ( ! clearResult )
4092+ {
4093+ return false ;
4094+ }
41064095 }
41074096 }
41084097 else if ( Emulator . HasSaveRam ( ) )
41094098 {
4110- while ( true )
4111- {
4112- if ( FlushSaveRAM ( ) ) break ;
4113-
4114- var result = ShowMessageBox3 (
4115- owner : this ,
4116- "Failed flushing the game's Save RAM to your disk.\n " +
4117- "Do you want to try again?" ,
4118- "IOError while writing SaveRAM" ,
4119- EMsgBoxIcon . Error ) ;
4120-
4121- if ( result is false ) break ;
4122- if ( result is null ) return false ;
4123- }
4099+ bool flushResult = this . DoWithTryAgainBox (
4100+ ( ) => FlushSaveRAM ( ) ,
4101+ "Failed flushing the game's Save RAM to your disk." ) ;
4102+ if ( ! flushResult ) return false ;
41244103 }
41254104
4126- bool ? tryAgain = null ;
4127- do
4128- {
4129- FileWriteResult stateSaveResult = AutoSaveStateIfConfigured ( ) ;
4130- if ( stateSaveResult . IsError )
4131- {
4132- tryAgain = this . ShowMessageBox3 (
4133- $ "Failed to auto-save state. Do you want to try again?\n \n Error details:\n { stateSaveResult . UserFriendlyErrorMessage ( ) } \n { stateSaveResult . Exception . Message } ",
4134- "IOError while writing savestate" ,
4135- EMsgBoxIcon . Error ) ;
4136- if ( tryAgain == null ) return false ;
4137- }
4138- } while ( tryAgain == true ) ;
4105+ bool stateSaveResult = this . DoWithTryAgainBox ( AutoSaveStateIfConfigured , "Failed to auto-save state." ) ;
4106+ if ( ! stateSaveResult ) return false ;
41394107
41404108 StopAv ( ) ;
41414109
@@ -4414,11 +4382,7 @@ public FileWriteResult SaveQuickSave(int slot, bool suppressOSD = false)
44144382 /// </summary>
44154383 private void SaveQuickSaveAndShowError ( int slot )
44164384 {
4417- FileWriteResult result = SaveQuickSave ( slot ) ;
4418- if ( result . IsError )
4419- {
4420- this . ErrorMessageBox ( result , "Quick save failed." ) ;
4421- }
4385+ ShowMessageIfError ( ( ) => SaveQuickSave ( slot ) , "Quick save failed." ) ;
44224386 }
44234387
44244388 public bool EnsureCoreIsAccurate ( )
@@ -4488,11 +4452,9 @@ private void SaveStateAs()
44884452 initFileName : $ "{ SaveStatePrefix ( ) } .QuickSave0.State") ;
44894453 if ( shouldSaveResult is not null )
44904454 {
4491- FileWriteResult saveResult = SaveState ( path : shouldSaveResult , userFriendlyStateName : shouldSaveResult ) ;
4492- if ( saveResult . IsError )
4493- {
4494- this . ErrorMessageBox ( saveResult , "Unable to save." ) ;
4495- }
4455+ ShowMessageIfError (
4456+ ( ) => SaveState ( path : shouldSaveResult , userFriendlyStateName : shouldSaveResult ) ,
4457+ "Unable to save state." ) ;
44964458 }
44974459
44984460 if ( Tools . IsLoaded < TAStudio > ( ) )
@@ -4783,6 +4745,15 @@ public bool ShowMessageBox2(
47834745 _ => null ,
47844746 } ;
47854747
4748+ public void ShowMessageIfError ( Func < FileWriteResult > action , string message )
4749+ {
4750+ FileWriteResult result = action ( ) ;
4751+ if ( result . IsError )
4752+ {
4753+ this . ErrorMessageBox ( result , message ) ;
4754+ }
4755+ }
4756+
47864757 public void StartSound ( ) => Sound . StartSound ( ) ;
47874758 public void StopSound ( ) => Sound . StopSound ( ) ;
47884759
0 commit comments