diff --git a/src/SMAPI/Framework/ModLoading/RewriteFacades/OptionsElementMethods.cs b/src/SMAPI/Framework/ModLoading/RewriteFacades/OptionsElementMethods.cs index dd13f06e..56250bfd 100644 --- a/src/SMAPI/Framework/ModLoading/RewriteFacades/OptionsElementMethods.cs +++ b/src/SMAPI/Framework/ModLoading/RewriteFacades/OptionsElementMethods.cs @@ -1,16 +1,46 @@ -using Microsoft.Xna.Framework.Graphics; +#nullable enable +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; +using HarmonyLib; +using Microsoft.Xna.Framework.Graphics; using StardewValley.Menus; namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades; -public class OptionsElementMethods : OptionsElement +public class OptionsElementMethods { - public OptionsElementMethods(string label) : base(label) - { - } + private static readonly ThreadLocal _recursiveCounter = new(() => 0); + private static readonly Dictionary MethodInfos = new(); - public virtual void draw(SpriteBatch b, int slotX, int slotY, IClickableMenu context = null) + public static void draw(OptionsElement instance, SpriteBatch b, int slotX, int slotY, IClickableMenu context = null) { - base.draw(b, slotX, slotY); + if (instance.GetType().IsAssignableFrom(typeof(OptionsElement))) + instance.draw(b, slotX, slotY); + else + { + if (!MethodInfos.ContainsKey(instance.GetType())) OptionsElementMethods.MethodInfos[instance.GetType()] = AccessTools.Method(instance.GetType(), "draw", new[] { typeof(SpriteBatch), typeof(int), typeof(int), typeof(IClickableMenu) }); + MethodInfo? pcDraw = MethodInfos[instance.GetType()]; + if (pcDraw != null) + { + if (_recursiveCounter.Value == 0) + { + _recursiveCounter.Value++; + try + { + pcDraw.Invoke(instance, new object[] { b, slotX, slotY, context }); + } + finally + { + _recursiveCounter.Value--; + } + } + else + instance.draw(b, slotX, slotY); + } + else + instance.draw(b, slotX, slotY); + } } } diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index e130ee10..f019868c 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -113,7 +113,7 @@ namespace StardewModdingAPI.Metadata yield return new MethodParentRewriter(typeof(IClickableMenu), typeof(IClickableMenuMethods)); yield return new MethodParentRewriter(typeof(SpriteText), typeof(SpriteTextMethods)); yield return new MethodParentRewriter(typeof(Utility), typeof(UtilityMethods)); - yield return new MethodParentRewriter(typeof(OptionsElement), typeof(OptionsElementMethods)); + yield return new MethodToAnotherStaticMethodRewriter(typeof(OptionsElement), (method) => method.Name == nameof(OptionsElementMethods.draw), typeof(OptionsElementMethods), "draw"); yield return new MethodToAnotherStaticMethodRewriter(typeof(ISoundBank), (method) => method.Name == nameof(SoundBankMethods.AddCue), typeof(SoundBankMethods), "AddCue"); yield return new MethodToAnotherStaticMethodRewriter(typeof(ISoundBank), (method) => method.Name == nameof(SoundBankMethods.GetCueDefinition), typeof(SoundBankMethods), "GetCueDefinition");