Make loading mods for advanced editing async.

This commit is contained in:
Ottermandias 2024-08-29 18:38:37 +02:00
parent e5ff9cee9e
commit 5c5e45114f
2 changed files with 124 additions and 43 deletions

View file

@ -25,6 +25,21 @@ public class ModEditor(
public readonly MdlMaterialEditor MdlMaterialEditor = mdlMaterialEditor; public readonly MdlMaterialEditor MdlMaterialEditor = mdlMaterialEditor;
public readonly FileCompactor Compactor = compactor; public readonly FileCompactor Compactor = compactor;
public bool IsLoading
{
get
{
lock (_lock)
{
return _loadingMod is { IsCompleted: false };
}
}
}
private readonly object _lock = new();
private Task? _loadingMod;
public Mod? Mod { get; private set; } public Mod? Mod { get; private set; }
public int GroupIdx { get; private set; } public int GroupIdx { get; private set; }
public int DataIdx { get; private set; } public int DataIdx { get; private set; }
@ -32,28 +47,42 @@ public class ModEditor(
public IModGroup? Group { get; private set; } public IModGroup? Group { get; private set; }
public IModDataContainer? Option { get; private set; } public IModDataContainer? Option { get; private set; }
public void LoadMod(Mod mod) public async Task LoadMod(Mod mod, int groupIdx, int dataIdx)
=> LoadMod(mod, -1, 0);
public void LoadMod(Mod mod, int groupIdx, int dataIdx)
{ {
Mod = mod; await AppendTask(() =>
LoadOption(groupIdx, dataIdx, true); {
Files.UpdateAll(mod, Option!); Mod = mod;
SwapEditor.Revert(Option!); LoadOption(groupIdx, dataIdx, true);
MetaEditor.Load(Mod!, Option!); Files.UpdateAll(mod, Option!);
Duplicates.Clear(); SwapEditor.Revert(Option!);
MdlMaterialEditor.ScanModels(Mod!); MetaEditor.Load(Mod!, Option!);
Duplicates.Clear();
MdlMaterialEditor.ScanModels(Mod!);
});
} }
public void LoadOption(int groupIdx, int dataIdx) private Task AppendTask(Action run)
{ {
LoadOption(groupIdx, dataIdx, true); lock (_lock)
SwapEditor.Revert(Option!); {
Files.UpdatePaths(Mod!, Option!); if (_loadingMod == null || _loadingMod.IsCompleted)
MetaEditor.Load(Mod!, Option!); return _loadingMod = Task.Run(run);
FileEditor.Clear();
Duplicates.Clear(); return _loadingMod = _loadingMod.ContinueWith(_ => run());
}
}
public async Task LoadOption(int groupIdx, int dataIdx)
{
await AppendTask(() =>
{
LoadOption(groupIdx, dataIdx, true);
SwapEditor.Revert(Option!);
Files.UpdatePaths(Mod!, Option!);
MetaEditor.Load(Mod!, Option!);
FileEditor.Clear();
Duplicates.Clear();
});
} }
/// <summary> Load the correct option by indices for the currently loaded mod if possible, unload if not. </summary> /// <summary> Load the correct option by indices for the currently loaded mod if possible, unload if not. </summary>

View file

@ -8,6 +8,7 @@ using ImGuiNET;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Services; using OtterGui.Services;
using OtterGui.Text;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Collections.Manager; using Penumbra.Collections.Manager;
using Penumbra.Communication; using Penumbra.Communication;
@ -51,34 +52,68 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
private Vector2 _iconSize = Vector2.Zero; private Vector2 _iconSize = Vector2.Zero;
private bool _allowReduplicate; private bool _allowReduplicate;
public Mod? Mod { get; private set; } public Mod? Mod { get; private set; }
public bool IsLoading
{
get
{
lock (_lock)
{
return _editor.IsLoading || _loadingMod is { IsCompleted: false };
}
}
}
private readonly object _lock = new();
private Task? _loadingMod;
private void AppendTask(Action run)
{
lock (_lock)
{
if (_loadingMod == null || _loadingMod.IsCompleted)
_loadingMod = Task.Run(run);
else
_loadingMod = _loadingMod.ContinueWith(_ => run());
}
}
public void ChangeMod(Mod mod) public void ChangeMod(Mod mod)
{ {
if (mod == Mod) if (mod == Mod)
return; return;
_editor.LoadMod(mod, -1, 0); WindowName = $"{mod.Name} (LOADING){WindowBaseLabel}";
Mod = mod; AppendTask(() =>
SizeConstraints = new WindowSizeConstraints
{ {
MinimumSize = new Vector2(1240, 600), _editor.LoadMod(mod, -1, 0).Wait();
MaximumSize = 4000 * Vector2.One, Mod = mod;
};
_selectedFiles.Clear(); SizeConstraints = new WindowSizeConstraints
_modelTab.Reset(); {
_materialTab.Reset(); MinimumSize = new Vector2(1240, 600),
_shaderPackageTab.Reset(); MaximumSize = 4000 * Vector2.One,
_itemSwapTab.UpdateMod(mod, _activeCollections.Current[mod.Index].Settings); };
UpdateModels(); _selectedFiles.Clear();
_forceTextureStartPath = true; _modelTab.Reset();
_materialTab.Reset();
_shaderPackageTab.Reset();
_itemSwapTab.UpdateMod(mod, _activeCollections.Current[mod.Index].Settings);
UpdateModels();
_forceTextureStartPath = true;
});
} }
public void ChangeOption(IModDataContainer? subMod) public void ChangeOption(IModDataContainer? subMod)
{ {
var (groupIdx, dataIdx) = subMod?.GetDataIndices() ?? (-1, 0); AppendTask(() =>
_editor.LoadOption(groupIdx, dataIdx); {
var (groupIdx, dataIdx) = subMod?.GetDataIndices() ?? (-1, 0);
_editor.LoadOption(groupIdx, dataIdx).Wait();
});
} }
public void UpdateModels() public void UpdateModels()
@ -92,6 +127,9 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
public override void PreDraw() public override void PreDraw()
{ {
if (IsLoading)
return;
using var performance = _performance.Measure(PerformanceType.UiAdvancedWindow); using var performance = _performance.Measure(PerformanceType.UiAdvancedWindow);
var sb = new StringBuilder(256); var sb = new StringBuilder(256);
@ -144,13 +182,16 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
public override void OnClose() public override void OnClose()
{ {
_left.Dispose();
_right.Dispose();
_materialTab.Reset();
_modelTab.Reset();
_shaderPackageTab.Reset();
_config.Ephemeral.AdvancedEditingOpen = false; _config.Ephemeral.AdvancedEditingOpen = false;
_config.Ephemeral.Save(); _config.Ephemeral.Save();
AppendTask(() =>
{
_left.Dispose();
_right.Dispose();
_materialTab.Reset();
_modelTab.Reset();
_shaderPackageTab.Reset();
});
} }
public override void Draw() public override void Draw()
@ -163,6 +204,17 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
_config.Ephemeral.Save(); _config.Ephemeral.Save();
} }
if (IsLoading)
{
var radius = 100 * ImUtf8.GlobalScale;
var thickness = (int) (20 * ImUtf8.GlobalScale);
var offsetX = ImGui.GetContentRegionAvail().X / 2 - radius;
var offsetY = ImGui.GetContentRegionAvail().Y / 2 - radius;
ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(offsetX, offsetY));
ImUtf8.Spinner("##spinner"u8, radius, thickness, ImGui.GetColorU32(ImGuiCol.Text));
return;
}
using var tabBar = ImRaii.TabBar("##tabs"); using var tabBar = ImRaii.TabBar("##tabs");
if (!tabBar) if (!tabBar)
return; return;
@ -405,14 +457,14 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
if (ImGuiUtil.DrawDisabledButton(defaultOption, width, "Switch to the default option for the mod.\nThis resets unsaved changes.", if (ImGuiUtil.DrawDisabledButton(defaultOption, width, "Switch to the default option for the mod.\nThis resets unsaved changes.",
_editor.Option is DefaultSubMod)) _editor.Option is DefaultSubMod))
{ {
_editor.LoadOption(-1, 0); _editor.LoadOption(-1, 0).Wait();
ret = true; ret = true;
} }
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiUtil.DrawDisabledButton("Refresh Data", width, "Refresh data for the current option.\nThis resets unsaved changes.", false)) if (ImGuiUtil.DrawDisabledButton("Refresh Data", width, "Refresh data for the current option.\nThis resets unsaved changes.", false))
{ {
_editor.LoadMod(_editor.Mod!, _editor.GroupIdx, _editor.DataIdx); _editor.LoadMod(_editor.Mod!, _editor.GroupIdx, _editor.DataIdx).Wait();
ret = true; ret = true;
} }
@ -430,7 +482,7 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
if (ImGui.Selectable(option.GetFullName(), option == _editor.Option)) if (ImGui.Selectable(option.GetFullName(), option == _editor.Option))
{ {
var (groupIdx, dataIdx) = option.GetDataIndices(); var (groupIdx, dataIdx) = option.GetDataIndices();
_editor.LoadOption(groupIdx, dataIdx); _editor.LoadOption(groupIdx, dataIdx).Wait();
ret = true; ret = true;
} }
} }