From e8dc0b8858e924d764fa4020d0cad725844bd137 Mon Sep 17 00:00:00 2001 From: ficedula Date: Sun, 24 Sep 2023 11:05:34 +0100 Subject: [PATCH] Fix GLTF plugin not disposing resources properly Add better field autosave options --- Braver.Core/BGame.cs | 10 +++++++- Braver/FGame.cs | 20 +++++++++++----- Braver/Field/FieldScreen.cs | 11 +++++---- Braver/Properties/launchSettings.json | 2 +- Braver/UI/Layout/Debug.cs | 12 ++++++---- Braver/UI/Splash.cs | 9 ++++--- .../Braver.GltfLoader/GLTFFieldModel.cs | 24 +++++++++++++++---- data/layout/debug.xml | 2 +- 8 files changed, 65 insertions(+), 25 deletions(-) diff --git a/Braver.Core/BGame.cs b/Braver.Core/BGame.cs index efb7dba..3e19dbb 100644 --- a/Braver.Core/BGame.cs +++ b/Braver.Core/BGame.cs @@ -88,11 +88,17 @@ namespace Braver { public override string ToString() => $"File source {_root}"; } + public enum FieldAutoSaveType { + None, + MostRecent3, + AllByLocationAndPPV, + } + public class GameOptions { public bool NoFieldScripts { get; set; } public bool NoRandomBattles { get; set; } public bool SkipBattleMenu { get; set; } - public bool AutoSaveOnFieldEntry { get; set; } + public FieldAutoSaveType AutoSaveOnFieldEntry { get; set; } public bool SeparateSaveFiles { get; set; } public float MusicVolume { get; set; } = 1f; public int BattleSpeed { get; set; } = 128; @@ -106,6 +112,8 @@ namespace Braver { prop.SetValue(this, float.Parse(value)); else if (prop.PropertyType == typeof(int)) prop.SetValue(this, int.Parse(value)); + else if (prop.PropertyType.IsEnum) + prop.SetValue(this, Enum.Parse(prop.PropertyType, value)); else throw new NotImplementedException(); } diff --git a/Braver/FGame.cs b/Braver/FGame.cs index d81a8e5..e45feb7 100644 --- a/Braver/FGame.cs +++ b/Braver/FGame.cs @@ -247,13 +247,21 @@ namespace Braver { NetConfig = new Net.NetConfig(); } - public void AutoSave() { + public void AutoSave(string location) { string path = GetPath("save"); - foreach (string file1 in Directory.GetFiles(path, "auto1.*")) - File.Move(file1, Path.Combine(path, "auto2" + Path.GetExtension(file1)), true); - foreach (string file0 in Directory.GetFiles(path, "auto.*")) - File.Move(file0, Path.Combine(path, "auto1" + Path.GetExtension(file0)), true); - Save(Path.Combine(path, "auto"), !GameOptions.SeparateSaveFiles); + + switch (GameOptions.AutoSaveOnFieldEntry) { + case FieldAutoSaveType.MostRecent3: + foreach (string file1 in Directory.GetFiles(path, "auto1.*")) + File.Move(file1, Path.Combine(path, "auto2" + Path.GetExtension(file1)), true); + foreach (string file0 in Directory.GetFiles(path, "auto.*")) + File.Move(file0, Path.Combine(path, "auto1" + Path.GetExtension(file0)), true); + Save(Path.Combine(path, "auto"), !GameOptions.SeparateSaveFiles); + break; + case FieldAutoSaveType.AllByLocationAndPPV: + Save(Path.Combine(path, $"auto_{location}_{SaveMap.PPV}"), !GameOptions.SeparateSaveFiles); + break; + } } public Stream WriteDebugBData(string category, string file) { diff --git a/Braver/Field/FieldScreen.cs b/Braver/Field/FieldScreen.cs index ca86080..2f7dfb1 100644 --- a/Braver/Field/FieldScreen.cs +++ b/Braver/Field/FieldScreen.cs @@ -157,11 +157,6 @@ namespace Braver.Field { public override void Init(FGame g, GraphicsDevice graphics) { base.Init(g, graphics); - UpdateSaveLocation(); - if (g.GameOptions.AutoSaveOnFieldEntry && !_isFirstLoad) - Game.AutoSave(); - _isFirstLoad = false; - g.Net.Listen(this); g.Net.Listen(this); g.Net.Listen(this); @@ -177,6 +172,12 @@ namespace Braver.Field { var mapList = g.Singleton(() => new MapList(g.Open("field", "maplist"))); _file = mapList.Items[_destination.DestinationFieldID]; + + UpdateSaveLocation(); + if (!_isFirstLoad) + Game.AutoSave(_file); + _isFirstLoad = false; + var cached = g.Singleton(() => new CachedField()); if (cached.FieldID == _destination.DestinationFieldID) field = cached.FieldFile; diff --git a/Braver/Properties/launchSettings.json b/Braver/Properties/launchSettings.json index 85f0b1c..8f0263b 100644 --- a/Braver/Properties/launchSettings.json +++ b/Braver/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Braver": { "commandName": "Project", - "commandLineArgs": "_debughost=localhost port=12508 key=GBGSTWNV ff7=C:\\games\\ff7 braver=C:\\Users\\ficed\\Projects\\F7\\data xbraver=C:\\Users\\ficed\\Projects\\F7\\temp xbdata=C:\\temp\\data.bpack _Options.AutoSaveOnFieldEntry=true Options.SeparateSaveFiles=true save=C:\\Users\\ficed\\AppData\\Roaming\\Braver\\save movies=C:\\games\\FF7\\data\\movies music=C:\\games\\FF7\\data\\music_ogg ff7exe=C:\\games\\FF7\\ff7.exe Options.MusicVolume=0.2 plugins=C:\\Users\\ficed\\Projects\\F7\\Braver\\bin\\Debug\\net7.0-windows\\plugins" + "commandLineArgs": "_debughost=localhost port=12508 key=GBGSTWNV ff7=C:\\games\\ff7 braver=C:\\Users\\ficed\\Projects\\F7\\data xbraver=C:\\Users\\ficed\\Projects\\F7\\temp xbdata=C:\\temp\\data.bpack Options.AutoSaveOnFieldEntry=AllByLocationAndPPV Options.SeparateSaveFiles=true save=C:\\Users\\ficed\\AppData\\Roaming\\Braver\\save movies=C:\\games\\FF7\\data\\movies music=C:\\games\\FF7\\data\\music_ogg ff7exe=C:\\games\\FF7\\ff7.exe Options.MusicVolume=0.2 plugins=C:\\Users\\ficed\\Projects\\F7\\Braver\\bin\\Debug\\net7.0-windows\\plugins" } } } \ No newline at end of file diff --git a/Braver/UI/Layout/Debug.cs b/Braver/UI/Layout/Debug.cs index d366288..09775fb 100644 --- a/Braver/UI/Layout/Debug.cs +++ b/Braver/UI/Layout/Debug.cs @@ -33,8 +33,9 @@ namespace Braver.UI.Layout { DoLabel(lNoFieldScripts, Game.GameOptions.NoFieldScripts); DoLabel(lNoRandomBattles, Game.GameOptions.NoRandomBattles); DoLabel(lSkipBattleMenu, Game.GameOptions.SkipBattleMenu); - DoLabel(lAutoSaveOnFieldEntry, Game.GameOptions.AutoSaveOnFieldEntry); DoLabel(lSeparateSaveFiles, Game.GameOptions.SeparateSaveFiles); + + lAutoSaveOnFieldEntry.Text = $"Auto Save on Field Entry: {Game.GameOptions.AutoSaveOnFieldEntry}"; } public void LabelClick(Label L) { @@ -44,9 +45,12 @@ namespace Braver.UI.Layout { Game.GameOptions.NoRandomBattles = !Game.GameOptions.NoRandomBattles; else if (L == lSkipBattleMenu) Game.GameOptions.SkipBattleMenu = !Game.GameOptions.SkipBattleMenu; - else if (L == lAutoSaveOnFieldEntry) - Game.GameOptions.AutoSaveOnFieldEntry = !Game.GameOptions.AutoSaveOnFieldEntry; - else if (L == lSeparateSaveFiles) + else if (L == lAutoSaveOnFieldEntry) { + int maxValue = Enum.GetValues() + .Select(e => (int)e) + .Max(); + Game.GameOptions.AutoSaveOnFieldEntry = (FieldAutoSaveType)(((int)Game.GameOptions.AutoSaveOnFieldEntry + 1) % (maxValue + 1)); + } else if (L == lSeparateSaveFiles) Game.GameOptions.SeparateSaveFiles = !Game.GameOptions.SeparateSaveFiles; Update(); diff --git a/Braver/UI/Splash.cs b/Braver/UI/Splash.cs index 8a39794..0d448af 100644 --- a/Braver/UI/Splash.cs +++ b/Braver/UI/Splash.cs @@ -110,9 +110,12 @@ namespace Braver.UI { break; case 1: - string autoPath = System.IO.Path.Combine(Game.GetPath("save"), "auto"); - if (System.IO.File.Exists(autoPath + ".sav")) - Game.Load(autoPath); + var mostRecent = System.IO.Directory.GetFiles(Game.GetPath("save"), "*.sav") + .Select(fn => new System.IO.FileInfo(fn)) + .OrderByDescending(info => info.LastWriteTime) + .FirstOrDefault(); + if (mostRecent != null) + Game.Load(System.IO.Path.ChangeExtension(mostRecent.FullName, "").TrimEnd('.')); else Game.Audio.PlaySfx(Sfx.Invalid, 1f, 0f); break; diff --git a/PluginImplementations/Braver.GltfLoader/GLTFFieldModel.cs b/PluginImplementations/Braver.GltfLoader/GLTFFieldModel.cs index 8ece58e..de520eb 100644 --- a/PluginImplementations/Braver.GltfLoader/GLTFFieldModel.cs +++ b/PluginImplementations/Braver.GltfLoader/GLTFFieldModel.cs @@ -40,18 +40,30 @@ namespace Braver.Field { } } - public class GltfModelLoader : IModelLoader { + public class GltfModelLoader : IModelLoader, IDisposable { + + private List _models = new(); + + public void Dispose() { + foreach (var model in _models) + model.Dispose(); + _models.Clear(); + } + public Plugins.Field.FieldModelRenderer Load(BGame game, string category, string hrc) { using (var s = game.TryOpen(category, Path.ChangeExtension(hrc, ".glb"))) { - if (s != null) - return new GLTFFieldModel(); + if (s != null) { + var model = new GLTFFieldModel(); + _models.Add(model); + return model; + } } return null; } } - internal class GLTFFieldModel : Plugins.Field.FieldModelRenderer { + internal class GLTFFieldModel : Plugins.Field.FieldModelRenderer, IDisposable { private SharpGLTF.Runtime.MonoGameDeviceContent _content; private SharpGLTF.Runtime.MonoGameModelInstance _model; @@ -160,5 +172,9 @@ namespace Braver.Field { //_model.Template._Meshes[0].Effects.First(). _model.Draw(projection, view, transform); } + + public void Dispose() { + _content.Dispose(); + } } } diff --git a/data/layout/debug.xml b/data/layout/debug.xml index c4134e1..1fe7b3d 100644 --- a/data/layout/debug.xml +++ b/data/layout/debug.xml @@ -6,7 +6,7 @@ No Field Scripts No Random Battles Skip Battle Menu - Auto Save on Field Entry + (dynamic) Separate Save Files