From b05180487e7b3bf6f7241fa7dfc0e19dc6b204af Mon Sep 17 00:00:00 2001 From: Arne Kiesewetter Date: Tue, 6 Aug 2024 23:18:50 +0200 Subject: [PATCH] Some changes --- .../DataFeeds/DataFeedBuilderMonkey.cs | 13 +++++ .../DataFeeds/DataFeedInjectorMonkey.cs | 53 ++++++++++++++++--- .../DataFeeds/EnumerateDataFeedEvent.cs | 10 +++- 3 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 MonkeyLoader.Resonite.Integration/DataFeeds/DataFeedBuilderMonkey.cs diff --git a/MonkeyLoader.Resonite.Integration/DataFeeds/DataFeedBuilderMonkey.cs b/MonkeyLoader.Resonite.Integration/DataFeeds/DataFeedBuilderMonkey.cs new file mode 100644 index 0000000..2f1ceee --- /dev/null +++ b/MonkeyLoader.Resonite.Integration/DataFeeds/DataFeedBuilderMonkey.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MonkeyLoader.Resonite.DataFeeds +{ + public abstract class DataFeedBuilderMonkey : ResoniteMonkey + where TMonkey : DataFeedBuilderMonkey, new() + { + } +} \ No newline at end of file diff --git a/MonkeyLoader.Resonite.Integration/DataFeeds/DataFeedInjectorMonkey.cs b/MonkeyLoader.Resonite.Integration/DataFeeds/DataFeedInjectorMonkey.cs index 5249420..3b62c88 100644 --- a/MonkeyLoader.Resonite.Integration/DataFeeds/DataFeedInjectorMonkey.cs +++ b/MonkeyLoader.Resonite.Integration/DataFeeds/DataFeedInjectorMonkey.cs @@ -1,32 +1,73 @@ using FrooxEngine; using HarmonyLib; using MonkeyLoader.Events; +using MonkeyLoader.Patching; +using MonkeyLoader.Resonite.Locale; using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; namespace MonkeyLoader.Resonite.DataFeeds { - internal abstract class DataFeedInjectorMonkey : ResoniteMonkey, + internal sealed class DataFeedInjectorMonkey : ResoniteAsyncEventHandlerMonkey, FallbackLocaleGenerationEvent>, IAsyncEventSource> - where TMonkey : DataFeedInjectorMonkey, new() where TDataFeed : IDataFeed { private static AsyncEventDispatching>? _dispatching; - [HarmonyPostfix] - [HarmonyPatch(nameof(IDataFeed.Enumerate), [typeof(IReadOnlyList), typeof(IReadOnlyList), typeof(string)])] - private static IAsyncEnumerable EnumeratePostfix(IAsyncEnumerable __result, TDataFeed __instance, IReadOnlyList path, IReadOnlyList groupKeys, string searchPhrase) + /// + public override bool CanBeDisabled => true; + + /// + public override string Id { get; } = typeof(DataFeedInjectorMonkey).CompactDescription(); + + /// + public override int Priority => HarmonyLib.Priority.Normal; + + protected override bool AppliesTo(FallbackLocaleGenerationEvent eventData) => !Failed && Enabled; + + protected override IEnumerable GetFeaturePatches() => []; + + protected override Task Handle(FallbackLocaleGenerationEvent eventData) + { + eventData.AddMessage(this.GetLocaleKey("Name"), $"{typeof(TDataFeed).CompactDescription()}-Injector"); + eventData.AddMessage(this.GetLocaleKey("Description"), $"Sends out the {typeof(EnumerateDataFeedEvent).CompactDescription()} event for monkeys to manipulate the items returned."); + + return Task.CompletedTask; + } + + protected override bool OnEngineReady() { - var eventData = new EnumerateDataFeedEvent(__instance, __result, path, groupKeys, searchPhrase); + if (!Prepare()) + { + Logger.Error(() => $"Failed to find Enumerate(IReadOnlyList, IReadOnlyList, string) method declared on type [{typeof(TDataFeed).CompactDescription()}]"); + + return false; + } + + Mod.RegisterEventSource(this); + + return base.OnEngineReady(); + } + + [HarmonyPrefix] + private static IAsyncEnumerable EnumeratePostfix(IAsyncEnumerable __result, TDataFeed __instance, IReadOnlyList path, IReadOnlyList groupKeys, string searchPhrase, object viewData) + { + var eventData = new EnumerateDataFeedEvent(__instance, __result, path, groupKeys, searchPhrase, viewData); _dispatching?.Invoke(eventData); return eventData.FinalResult; } + private static bool Prepare() => TargetMethod() is not null; + + private static MethodBase TargetMethod() + => AccessTools.DeclaredMethod(typeof(TDataFeed), nameof(IDataFeed.Enumerate), [typeof(IReadOnlyList), typeof(IReadOnlyList), typeof(string), typeof(object)]); + event AsyncEventDispatching>? IAsyncEventSource>.Dispatching { add => _dispatching += value; diff --git a/MonkeyLoader.Resonite.Integration/DataFeeds/EnumerateDataFeedEvent.cs b/MonkeyLoader.Resonite.Integration/DataFeeds/EnumerateDataFeedEvent.cs index 36fe727..4e64f1d 100644 --- a/MonkeyLoader.Resonite.Integration/DataFeeds/EnumerateDataFeedEvent.cs +++ b/MonkeyLoader.Resonite.Integration/DataFeeds/EnumerateDataFeedEvent.cs @@ -13,7 +13,7 @@ namespace MonkeyLoader.Resonite.DataFeeds /// Represents the event data for the Enumerate Data Feed Event. /// /// - /// This event is used by concrete + /// This event is used by concrete /// implementations to signal that the they're patching is being enumerated. /// /// The type of the data feed. @@ -106,14 +106,20 @@ public IAsyncEnumerable FinalResult /// public string? SearchPhrase { get; } + /// + /// Gets the view data for this enumeration request. + /// + public object ViewData { get; } + internal EnumerateDataFeedEvent(TDataFeed dataFeed, IAsyncEnumerable result, - IReadOnlyList? path, IReadOnlyList? groupKeys, string? searchPhrase) + IReadOnlyList? path, IReadOnlyList? groupKeys, string? searchPhrase, object viewData) { DataFeed = dataFeed; OriginalResult = result; Path = path ?? []; GroupKeys = groupKeys ?? []; SearchPhrase = searchPhrase; + ViewData = viewData; } ///