Skip to content

Commit

Permalink
Fixed World Progress Reporting and Asynchronous Saving. (#1915)
Browse files Browse the repository at this point in the history
* Fixed world progress reporting & asynchronous save

* Fixed world progress reporting & asynchronous save
  • Loading branch information
RussDev7 committed Jul 22, 2024
1 parent 5844e5e commit 506e94e
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 19 deletions.
81 changes: 79 additions & 2 deletions src/TEdit.Terraria/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,85 @@ public World(int height, int width, string title, int seed = -1)
CharacterNames.Clear();
}

public static Task SaveAsync(World world, string filename, bool resetTime = false, int versionOverride = 0, bool incrementRevision = true, IProgress<ProgressChangedEventArgs>? progress = null)
=> Task.Run(() => Save(world, filename, resetTime, versionOverride, incrementRevision, progress));
public static async Task SaveAsync(World world, string filename, bool resetTime = false, int versionOverride = 0, bool incrementRevision = true, IProgress<ProgressChangedEventArgs>? progress = null)

Check warning on line 51 in src/TEdit.Terraria/World.cs

View workflow job for this annotation

GitHub Actions / build (Release)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 51 in src/TEdit.Terraria/World.cs

View workflow job for this annotation

GitHub Actions / build (Release)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
{
await Task.Run(() =>
{
lock (_fileLock)
{
uint currentWorldVersion = world.Version;
try
{
// Set the world version for this save
if (versionOverride > 0)
{
world.Version = (uint)(versionOverride);
}
if (resetTime)
{
progress?.Report(new ProgressChangedEventArgs(0, "Resetting Time..."));
// world.ResetTime();
}
if (filename == null)
return;
string temp = filename + ".tmp";
using (var fs = new FileStream(temp, FileMode.Create))
{
using (var bw = new BinaryWriter(fs))
{
if (versionOverride < 0 || world.IsV0 || world.Version == 38)
{
bool addLight = (currentWorldVersion > world.Version); // Check if world is being downgraded.
world.Version = (uint)Math.Abs(versionOverride);
SaveV0(world, bw, addLight, progress);
}
else if (world.Version > 87 && world.Version != 38)
{
SaveV2(world, bw, incrementRevision, progress);
}
else
{
bool addLight = (currentWorldVersion >= 87); // Check if world is being downgraded.
SaveV1(world, bw, addLight, progress);
}
if (world.IsConsole)
{
ConsoleCompressor.CompressStream(fs);
}
bw.Close();
fs.Close();
// Make a backup of the current file if it exists
if (File.Exists(filename))
{
string backup = filename + "." + DateTime.Now.ToString("yyyyMMddHHmmss") + ".TEdit";
File.Copy(filename, backup, true);
}
// Replace the actual file with temp save file
File.Copy(temp, filename, true);
// Delete temp save file
File.Delete(temp);
progress?.Report(new ProgressChangedEventArgs(100, "World Save Complete."));
}
}
world.LastSave = File.GetLastWriteTimeUtc(filename);
}
finally
{
// Restore the version
if (versionOverride > 0)
{
world.Version = currentWorldVersion;
}
}
}
});
}

public static void Save(
World world,
Expand Down
26 changes: 9 additions & 17 deletions src/TEdit/ViewModel/WorldViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,37 +1140,29 @@ private void SaveWorldThreaded(string filename, uint version = 0)
Task.Factory.StartNew(async () =>
{
ErrorLogging.TelemetryClient?.TrackEvent(nameof(SaveWorldThreaded));
try
{
OnProgressChanged(CurrentWorld, new ProgressChangedEventArgs(0, "Validating World..."));
// await CurrentWorld.ValidateAsync();
}
catch (ArgumentOutOfRangeException err)
{
string msg = "There is a problem in your world.\r\n" +
$"{err.ParamName}\r\n" +
$"This world may not open in Terraria\r\n" +
"Would you like to save anyways??\r\n";
if (MessageBox.Show(msg, "World Error", MessageBoxButton.YesNo, MessageBoxImage.Error) !=
MessageBoxResult.Yes)
string msg = "There is a problem in your world.\r\n" + $"{err.ParamName}\r\n" + $"This world may not open in Terraria\r\n" + "Would you like to save anyways??\r\n";
if (MessageBox.Show(msg, "World Error", MessageBoxButton.YesNo, MessageBoxImage.Error) != MessageBoxResult.Yes)
return;
}
catch (Exception ex)
{
string msg = "There is a problem in your world.\r\n" +
$"{ex.Message}\r\n" +
"This world may not open in Terraria\r\n" +
"Would you like to save anyways??\r\n";
if (MessageBox.Show(msg, "World Error", MessageBoxButton.YesNo, MessageBoxImage.Error) !=
MessageBoxResult.Yes)
string msg = "There is a problem in your world.\r\n" + $"{ex.Message}\r\n" + "This world may not open in Terraria\r\n" + "Would you like to save anyways??\r\n";
if (MessageBox.Show(msg, "World Error", MessageBoxButton.YesNo, MessageBoxImage.Error) != MessageBoxResult.Yes)
return;
}
World.Save(CurrentWorld, filename, versionOverride: (int)version);
})
.ContinueWith(t => CommandManager.InvalidateRequerySuggested(), TaskFactoryHelper.UiTaskScheduler);
await World.SaveAsync(CurrentWorld, filename, versionOverride: (int)version, progress: new Progress<ProgressChangedEventArgs>(e =>
{
DispatcherHelper.CheckBeginInvokeOnUI(() => OnProgressChanged(CurrentWorld, e));
}));
}).ContinueWith(t => CommandManager.InvalidateRequerySuggested(), TaskFactoryHelper.UiTaskScheduler);
}

public void LoadWorld(string filename)
Expand Down

0 comments on commit 506e94e

Please sign in to comment.