Initial interop

This commit is contained in:
Tyfon
2024-09-20 11:45:29 -07:00
parent 418cbedf5b
commit 2ff3fba9bc
4 changed files with 148 additions and 2 deletions

View File

@@ -0,0 +1,31 @@
using EFT.InventoryLogic;
using EFT.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace UIFixes;
// This class exists to create a layer between MultiSelectInterop and the MultiSelect implementation.
public static class MultiSelectController
{
public static int GetCount()
{
return MultiSelect.Count;
}
public static IEnumerable<Item> GetItems()
{
return MultiSelect.SortedItemContexts().Select(ic => ic.Item);
}
public static Task Apply(Func<Item, Task> func, ItemUiContext itemUiContext = null)
{
itemUiContext ??= ItemUiContext.Instance;
var taskSerializer = itemUiContext.gameObject.AddComponent<ItemTaskSerializer>();
return taskSerializer.Initialize(GetItems(), func);
}
}
public class ItemTaskSerializer : TaskSerializer<Item> { }

View File

@@ -0,0 +1,115 @@
using BepInEx;
using BepInEx.Bootstrap;
using EFT.InventoryLogic;
using EFT.UI;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
namespace UIFixesInterop;
/// <summary>
/// Provides access to UI Fixes' multiselect functionality.
/// </summary>
internal class MultiSelect
{
private static readonly Version RequiredVersion = new(2, 5);
private static bool? UIFixesLoaded;
private static Type MultiSelectType;
private static MethodInfo GetCountMethod;
private static MethodInfo GetItemsMethod;
private static MethodInfo ApplyMethod;
/// <value><c>Count</c> represents the number of items in the current selection, 0 if UI Fixes is not present.</value>
public int Count
{
get
{
if (!Loaded())
{
return 0;
}
return (int)GetCountMethod.Invoke(null, []);
}
}
/// <value><c>Items</c> is an enumerable list of items in the current selection, empty if UI Fixes is not present</value>
public IEnumerable<Item> Items
{
get
{
if (!Loaded())
{
return [];
}
return (IEnumerable<Item>)GetItemsMethod.Invoke(null, []);
}
}
/// <summary>
/// This method takes an <c>Action</c> and calls it *sequentially* on each item in the current selection.
/// Will no-op if UI Fixes is not present.
/// </summary>
/// <param name="action">The action to call on each item.</param>
/// <param name="itemUiContext">Optional <c>ItemUiContext</c>; will use <c>ItemUiContext.Instance</c> if not provided.</param>
public void Apply(Action<Item> action, ItemUiContext itemUiContext = null)
{
if (!Loaded())
{
return;
}
Func<Item, Task> func = item =>
{
action(item);
return Task.CompletedTask;
};
ApplyMethod.Invoke(null, [func, itemUiContext]);
}
/// <summary>
/// This method takes an <c>Func</c> that returns a <c>Task</c> and calls it *sequentially* on each item in the current selection.
/// Will return a completed task immediately if UI Fixes is not present.
/// </summary>
/// <param name="func">The function to call on each item</param>
/// <param name="itemUiContext">Optional <c>ItemUiContext</c>; will use <c>ItemUiContext.Instance</c> if not provided.</param>
/// <returns>A <c>Task</c> that will complete when all the function calls are complete.</returns>
public Task Apply(Func<Item, Task> func, ItemUiContext itemUiContext = null)
{
if (!Loaded())
{
return Task.CompletedTask;
}
return (Task)ApplyMethod.Invoke(null, [func, itemUiContext]);
}
private bool Loaded()
{
if (!UIFixesLoaded.HasValue)
{
bool present = Chainloader.PluginInfos.TryGetValue("Tyfon.UIFixes", out PluginInfo pluginInfo);
UIFixesLoaded = present && pluginInfo.Metadata.Version >= RequiredVersion;
if (UIFixesLoaded.Value)
{
MultiSelectType = Type.GetType("UIFixes.MultiSelectController, UIFixes");
if (MultiSelectType != null)
{
GetCountMethod = AccessTools.Method(MultiSelectType, "GetCount");
GetItemsMethod = AccessTools.Method(MultiSelectType, "GetItems");
ApplyMethod = AccessTools.Method(MultiSelectType, "Apply");
}
}
}
return UIFixesLoaded.Value;
}
}

View File

@@ -4,7 +4,7 @@
<TargetFramework>net471</TargetFramework> <TargetFramework>net471</TargetFramework>
<AssemblyName>Tyfon.UIFixes</AssemblyName> <AssemblyName>Tyfon.UIFixes</AssemblyName>
<Description>SPT UI Fixes</Description> <Description>SPT UI Fixes</Description>
<Version>2.4.5</Version> <Version>2.5.0</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Configurations>Debug;Release</Configurations> <Configurations>Debug;Release</Configurations>

View File

@@ -1,6 +1,6 @@
{ {
"name": "uifixes", "name": "uifixes",
"version": "2.4.5", "version": "2.5.0",
"main": "src/mod.js", "main": "src/mod.js",
"license": "MIT", "license": "MIT",
"author": "Tyfon", "author": "Tyfon",