mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Make loading mods for advanced editing async.
This commit is contained in:
parent
e5ff9cee9e
commit
5c5e45114f
2 changed files with 124 additions and 43 deletions
|
|
@ -25,6 +25,21 @@ public class ModEditor(
|
|||
public readonly MdlMaterialEditor MdlMaterialEditor = mdlMaterialEditor;
|
||||
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 int GroupIdx { get; private set; }
|
||||
public int DataIdx { get; private set; }
|
||||
|
|
@ -32,10 +47,9 @@ public class ModEditor(
|
|||
public IModGroup? Group { get; private set; }
|
||||
public IModDataContainer? Option { get; private set; }
|
||||
|
||||
public void LoadMod(Mod mod)
|
||||
=> LoadMod(mod, -1, 0);
|
||||
|
||||
public void LoadMod(Mod mod, int groupIdx, int dataIdx)
|
||||
public async Task LoadMod(Mod mod, int groupIdx, int dataIdx)
|
||||
{
|
||||
await AppendTask(() =>
|
||||
{
|
||||
Mod = mod;
|
||||
LoadOption(groupIdx, dataIdx, true);
|
||||
|
|
@ -44,9 +58,23 @@ public class ModEditor(
|
|||
MetaEditor.Load(Mod!, Option!);
|
||||
Duplicates.Clear();
|
||||
MdlMaterialEditor.ScanModels(Mod!);
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadOption(int groupIdx, int dataIdx)
|
||||
private Task AppendTask(Action run)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_loadingMod == null || _loadingMod.IsCompleted)
|
||||
return _loadingMod = Task.Run(run);
|
||||
|
||||
return _loadingMod = _loadingMod.ContinueWith(_ => run());
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadOption(int groupIdx, int dataIdx)
|
||||
{
|
||||
await AppendTask(() =>
|
||||
{
|
||||
LoadOption(groupIdx, dataIdx, true);
|
||||
SwapEditor.Revert(Option!);
|
||||
|
|
@ -54,6 +82,7 @@ public class ModEditor(
|
|||
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>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using ImGuiNET;
|
|||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
|
|
@ -53,12 +54,42 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
|
||||
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)
|
||||
{
|
||||
if (mod == Mod)
|
||||
return;
|
||||
|
||||
_editor.LoadMod(mod, -1, 0);
|
||||
WindowName = $"{mod.Name} (LOADING){WindowBaseLabel}";
|
||||
AppendTask(() =>
|
||||
{
|
||||
_editor.LoadMod(mod, -1, 0).Wait();
|
||||
Mod = mod;
|
||||
|
||||
SizeConstraints = new WindowSizeConstraints
|
||||
|
|
@ -73,12 +104,16 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
_itemSwapTab.UpdateMod(mod, _activeCollections.Current[mod.Index].Settings);
|
||||
UpdateModels();
|
||||
_forceTextureStartPath = true;
|
||||
});
|
||||
}
|
||||
|
||||
public void ChangeOption(IModDataContainer? subMod)
|
||||
{
|
||||
AppendTask(() =>
|
||||
{
|
||||
var (groupIdx, dataIdx) = subMod?.GetDataIndices() ?? (-1, 0);
|
||||
_editor.LoadOption(groupIdx, dataIdx);
|
||||
_editor.LoadOption(groupIdx, dataIdx).Wait();
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdateModels()
|
||||
|
|
@ -92,6 +127,9 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
|
||||
public override void PreDraw()
|
||||
{
|
||||
if (IsLoading)
|
||||
return;
|
||||
|
||||
using var performance = _performance.Measure(PerformanceType.UiAdvancedWindow);
|
||||
|
||||
var sb = new StringBuilder(256);
|
||||
|
|
@ -143,14 +181,17 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
}
|
||||
|
||||
public override void OnClose()
|
||||
{
|
||||
_config.Ephemeral.AdvancedEditingOpen = false;
|
||||
_config.Ephemeral.Save();
|
||||
AppendTask(() =>
|
||||
{
|
||||
_left.Dispose();
|
||||
_right.Dispose();
|
||||
_materialTab.Reset();
|
||||
_modelTab.Reset();
|
||||
_shaderPackageTab.Reset();
|
||||
_config.Ephemeral.AdvancedEditingOpen = false;
|
||||
_config.Ephemeral.Save();
|
||||
});
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
|
|
@ -163,6 +204,17 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
_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");
|
||||
if (!tabBar)
|
||||
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.",
|
||||
_editor.Option is DefaultSubMod))
|
||||
{
|
||||
_editor.LoadOption(-1, 0);
|
||||
_editor.LoadOption(-1, 0).Wait();
|
||||
ret = true;
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -430,7 +482,7 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
if (ImGui.Selectable(option.GetFullName(), option == _editor.Option))
|
||||
{
|
||||
var (groupIdx, dataIdx) = option.GetDataIndices();
|
||||
_editor.LoadOption(groupIdx, dataIdx);
|
||||
_editor.LoadOption(groupIdx, dataIdx).Wait();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue