Add ReverseResolvePlayerPathsAsync.

This commit is contained in:
Ottermandias 2023-10-22 15:36:47 +02:00
parent f2ef0e15d3
commit f910dcf1e0
6 changed files with 115 additions and 63 deletions

@ -1 +1 @@
Subproject commit 839cc8f270abb6a938d71596bef05b4a9b3ab0ea Subproject commit eb9e6d65d51db9c8ed11d74332f8390d5d813727

View file

@ -16,6 +16,7 @@ using Penumbra.Services;
using Penumbra.UI; using Penumbra.UI;
using Penumbra.Collections.Manager; using Penumbra.Collections.Manager;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using ImGuiScene;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
namespace Penumbra.Api; namespace Penumbra.Api;
@ -570,6 +571,7 @@ public class IpcTester : IDisposable
private string _currentResolveCharacter = string.Empty; private string _currentResolveCharacter = string.Empty;
private string _currentReversePath = string.Empty; private string _currentReversePath = string.Empty;
private int _currentReverseIdx = 0; private int _currentReverseIdx = 0;
private Task<(string[], string[][])> _task = Task.FromException<(string[], string[][])>(new Exception());
public Resolve(DalamudPluginInterface pi) public Resolve(DalamudPluginInterface pi)
=> _pi = pi; => _pi = pi;
@ -645,9 +647,6 @@ public class IpcTester : IDisposable
} }
} }
DrawIntro(Ipc.ResolvePlayerPaths.Label, "Resolved Paths (Player)");
if (_currentResolvePath.Length > 0 || _currentReversePath.Length > 0)
{
var forwardArray = _currentResolvePath.Length > 0 var forwardArray = _currentResolvePath.Length > 0
? new[] ? new[]
{ {
@ -660,22 +659,43 @@ public class IpcTester : IDisposable
_currentReversePath, _currentReversePath,
} }
: Array.Empty<string>(); : Array.Empty<string>();
var ret = Ipc.ResolvePlayerPaths.Subscriber(_pi).Invoke(forwardArray, reverseArray);
string ConvertText((string[], string[][]) data)
{
var text = string.Empty; var text = string.Empty;
if (ret.Item1.Length > 0) if (data.Item1.Length > 0)
{ {
if (ret.Item2.Length > 0) if (data.Item2.Length > 0)
text = $"Forward: {ret.Item1[0]} | Reverse: {string.Join("; ", ret.Item2[0])}."; text = $"Forward: {data.Item1[0]} | Reverse: {string.Join("; ", data.Item2[0])}.";
else else
text = $"Forward: {ret.Item1[0]}."; text = $"Forward: {data.Item1[0]}.";
} }
else if (ret.Item2.Length > 0) else if (data.Item2.Length > 0)
{ {
text = $"Reverse: {string.Join("; ", ret.Item2[0])}."; text = $"Reverse: {string.Join("; ", data.Item2[0])}.";
} }
ImGui.TextUnformatted(text); return text;
} }
;
DrawIntro(Ipc.ResolvePlayerPaths.Label, "Resolved Paths (Player)");
if (forwardArray.Length > 0 || reverseArray.Length > 0)
{
var ret = Ipc.ResolvePlayerPaths.Subscriber(_pi).Invoke(forwardArray, reverseArray);
ImGui.TextUnformatted(ConvertText(ret));
}
DrawIntro(Ipc.ResolvePlayerPathsAsync.Label, "Resolved Paths Async (Player)");
if (ImGui.Button("Start"))
_task = Ipc.ResolvePlayerPathsAsync.Subscriber(_pi).Invoke(forwardArray, reverseArray);
var hovered = ImGui.IsItemHovered();
ImGui.SameLine();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(_task.Status.ToString());
if ((hovered || ImGui.IsItemHovered()) && _task.IsCompletedSuccessfully)
ImGui.SetTooltip(ConvertText(_task.Result));
} }
} }

View file

@ -388,6 +388,30 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return (resolved, reverseResolved.Select(a => a.Select(p => p.ToString()).ToArray()).ToArray()); return (resolved, reverseResolved.Select(a => a.Select(p => p.ToString()).ToArray()).ToArray());
} }
public async Task<(string[], string[][])> ResolvePlayerPathsAsync(string[] forward, string[] reverse)
{
CheckInitialized();
if (!_config.EnableMods)
return (forward, reverse.Select(p => new[]
{
p,
}).ToArray());
return await Task.Run(async () =>
{
var playerCollection = await _dalamud.Framework.RunOnFrameworkThread(_collectionResolver.PlayerCollection).ConfigureAwait(false);
var forwardTask = Task.Run(() =>
{
var forwardRet = new string[forward.Length];
Parallel.For(0, forward.Length, idx => forwardRet[idx] = ResolvePath(forward[idx], _modManager, playerCollection));
return forwardRet;
}).ConfigureAwait(false);
var reverseTask = Task.Run(() => playerCollection.ReverseResolvePaths(reverse)).ConfigureAwait(false);
var reverseResolved = (await reverseTask).Select(a => a.Select(p => p.ToString()).ToArray()).ToArray();
return (await forwardTask, reverseResolved);
});
}
public T? GetFile<T>(string gamePath) where T : FileResource public T? GetFile<T>(string gamePath) where T : FileResource
=> GetFileIntern<T>(ResolveDefaultPath(gamePath)); => GetFileIntern<T>(ResolveDefaultPath(gamePath));

View file

@ -62,6 +62,7 @@ public class PenumbraIpcProviders : IDisposable
internal readonly FuncProvider<string, int, string[]> ReverseResolveGameObjectPath; internal readonly FuncProvider<string, int, string[]> ReverseResolveGameObjectPath;
internal readonly FuncProvider<string, string[]> ReverseResolvePlayerPath; internal readonly FuncProvider<string, string[]> ReverseResolvePlayerPath;
internal readonly FuncProvider<string[], string[], (string[], string[][])> ResolvePlayerPaths; internal readonly FuncProvider<string[], string[], (string[], string[][])> ResolvePlayerPaths;
internal readonly FuncProvider<string[], string[], Task<(string[], string[][])>> ResolvePlayerPathsAsync;
// Collections // Collections
internal readonly FuncProvider<IList<string>> GetCollections; internal readonly FuncProvider<IList<string>> GetCollections;
@ -121,8 +122,13 @@ public class PenumbraIpcProviders : IDisposable
// Resource Tree // Resource Tree
internal readonly FuncProvider<ushort[], IReadOnlyDictionary<string, string[]>?[]> GetGameObjectResourcePaths; internal readonly FuncProvider<ushort[], IReadOnlyDictionary<string, string[]>?[]> GetGameObjectResourcePaths;
internal readonly FuncProvider<IReadOnlyDictionary<ushort, IReadOnlyDictionary<string, string[]>>> GetPlayerResourcePaths; internal readonly FuncProvider<IReadOnlyDictionary<ushort, IReadOnlyDictionary<string, string[]>>> GetPlayerResourcePaths;
internal readonly FuncProvider<ResourceType, bool, ushort[], IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>?[]> GetGameObjectResourcesOfType;
internal readonly FuncProvider<ResourceType, bool, IReadOnlyDictionary<ushort, IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>>> GetPlayerResourcesOfType; internal readonly FuncProvider<ResourceType, bool, ushort[], IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>?[]>
GetGameObjectResourcesOfType;
internal readonly
FuncProvider<ResourceType, bool, IReadOnlyDictionary<ushort, IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>>>
GetPlayerResourcesOfType;
public PenumbraIpcProviders(DalamudServices dalamud, IPenumbraApi api, ModManager modManager, CollectionManager collections, public PenumbraIpcProviders(DalamudServices dalamud, IPenumbraApi api, ModManager modManager, CollectionManager collections,
TempModManager tempMods, TempCollectionManager tempCollections, SaveService saveService, Configuration config) TempModManager tempMods, TempCollectionManager tempCollections, SaveService saveService, Configuration config)
@ -184,6 +190,7 @@ public class PenumbraIpcProviders : IDisposable
ReverseResolveGameObjectPath = Ipc.ReverseResolveGameObjectPath.Provider(pi, Api.ReverseResolveGameObjectPath); ReverseResolveGameObjectPath = Ipc.ReverseResolveGameObjectPath.Provider(pi, Api.ReverseResolveGameObjectPath);
ReverseResolvePlayerPath = Ipc.ReverseResolvePlayerPath.Provider(pi, Api.ReverseResolvePlayerPath); ReverseResolvePlayerPath = Ipc.ReverseResolvePlayerPath.Provider(pi, Api.ReverseResolvePlayerPath);
ResolvePlayerPaths = Ipc.ResolvePlayerPaths.Provider(pi, Api.ResolvePlayerPaths); ResolvePlayerPaths = Ipc.ResolvePlayerPaths.Provider(pi, Api.ResolvePlayerPaths);
ResolvePlayerPathsAsync = Ipc.ResolvePlayerPathsAsync.Provider(pi, Api.ResolvePlayerPathsAsync);
// Collections // Collections
GetCollections = Ipc.GetCollections.Provider(pi, Api.GetCollections); GetCollections = Ipc.GetCollections.Provider(pi, Api.GetCollections);
@ -301,6 +308,7 @@ public class PenumbraIpcProviders : IDisposable
ReverseResolveGameObjectPath.Dispose(); ReverseResolveGameObjectPath.Dispose();
ReverseResolvePlayerPath.Dispose(); ReverseResolvePlayerPath.Dispose();
ResolvePlayerPaths.Dispose(); ResolvePlayerPaths.Dispose();
ResolvePlayerPathsAsync.Dispose();
// Collections // Collections
GetCollections.Dispose(); GetCollections.Dispose();

View file

@ -23,7 +23,7 @@ public class CollectionCache : IDisposable
private readonly ModCollection _collection; private readonly ModCollection _collection;
public readonly CollectionModData ModData = new(); public readonly CollectionModData ModData = new();
public readonly SortedList<string, (SingleArray<IMod>, object?)> _changedItems = new(); public readonly SortedList<string, (SingleArray<IMod>, object?)> _changedItems = new();
public readonly Dictionary<Utf8GamePath, ModPath> ResolvedFiles = new(); public readonly ConcurrentDictionary<Utf8GamePath, ModPath> ResolvedFiles = new();
public readonly MetaCache Meta; public readonly MetaCache Meta;
public readonly Dictionary<IMod, SingleArray<ModConflicts>> _conflicts = new(); public readonly Dictionary<IMod, SingleArray<ModConflicts>> _conflicts = new();
@ -146,7 +146,7 @@ public class CollectionCache : IDisposable
ModData.RemovePath(modPath.Mod, path); ModData.RemovePath(modPath.Mod, path);
if (fullPath.FullName.Length > 0) if (fullPath.FullName.Length > 0)
{ {
ResolvedFiles.Add(path, new ModPath(Mod.ForcedFiles, fullPath)); ResolvedFiles.TryAdd(path, new ModPath(Mod.ForcedFiles, fullPath));
InvokeResolvedFileChange(_collection, ResolvedFileChanged.Type.Replaced, path, fullPath, modPath.Path, InvokeResolvedFileChange(_collection, ResolvedFileChanged.Type.Replaced, path, fullPath, modPath.Path,
Mod.ForcedFiles); Mod.ForcedFiles);
} }
@ -157,7 +157,7 @@ public class CollectionCache : IDisposable
} }
else if (fullPath.FullName.Length > 0) else if (fullPath.FullName.Length > 0)
{ {
ResolvedFiles.Add(path, new ModPath(Mod.ForcedFiles, fullPath)); ResolvedFiles.TryAdd(path, new ModPath(Mod.ForcedFiles, fullPath));
InvokeResolvedFileChange(_collection, ResolvedFileChanged.Type.Added, path, fullPath, FullPath.Empty, Mod.ForcedFiles); InvokeResolvedFileChange(_collection, ResolvedFileChanged.Type.Added, path, fullPath, FullPath.Empty, Mod.ForcedFiles);
} }
} }

View file

@ -56,7 +56,7 @@ public partial class ModCollection
} }
internal IReadOnlyDictionary<Utf8GamePath, ModPath> ResolvedFiles internal IReadOnlyDictionary<Utf8GamePath, ModPath> ResolvedFiles
=> _cache?.ResolvedFiles ?? new Dictionary<Utf8GamePath, ModPath>(); => _cache?.ResolvedFiles ?? new ConcurrentDictionary<Utf8GamePath, ModPath>();
internal IReadOnlyDictionary<string, (SingleArray<IMod>, object?)> ChangedItems internal IReadOnlyDictionary<string, (SingleArray<IMod>, object?)> ChangedItems
=> _cache?.ChangedItems ?? new Dictionary<string, (SingleArray<IMod>, object?)>(); => _cache?.ChangedItems ?? new Dictionary<string, (SingleArray<IMod>, object?)>();