diff --git a/S1API/Internal/Abstraction/EventHelper.cs b/S1API/Internal/Abstraction/EventHelper.cs new file mode 100644 index 00000000..1dd94e81 --- /dev/null +++ b/S1API/Internal/Abstraction/EventHelper.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Events; + +namespace S1API.Internal.Abstraction +{ + /// + /// INTERNAL: This static class provides us an easy wrapper for subscribing and unsubscribing unity actions. + /// + internal static class EventHelper + { + /// + /// INTERNAL: Tracking for subscribed actions. + /// + internal static readonly Dictionary SubscribedActions = new Dictionary(); + + /// + /// INTERNAL: Adds a listener to the event, as well as the subscription list. + /// + /// The action / method you want to subscribe. + /// The event you want to subscribe to. + internal static void AddListener(Action listener, UnityEvent unityEvent) + { + if (SubscribedActions.ContainsKey(listener)) + return; + + UnityAction wrappedListener = (UnityAction)listener.Invoke; + unityEvent.AddListener(wrappedListener); + SubscribedActions.Add(listener, wrappedListener); + } + + /// + /// INTERNAL: Removes a listener to the event, as well as the subscription list. + /// + /// The action / method you want to unsubscribe. + /// The event you want to unsubscribe from. + internal static void RemoveListener(Action listener, UnityEvent unityEvent) + { + SubscribedActions.TryGetValue(listener, out UnityAction wrappedAction); + SubscribedActions.Remove(listener); + unityEvent.RemoveListener(wrappedAction); + } + } +} \ No newline at end of file diff --git a/S1API/Quests/QuestEntry.cs b/S1API/Quests/QuestEntry.cs index daa316b3..956fb5f9 100644 --- a/S1API/Quests/QuestEntry.cs +++ b/S1API/Quests/QuestEntry.cs @@ -3,9 +3,10 @@ #elif (MONO) using S1Quests = ScheduleOne.Quests; #endif + using System; +using S1API.Internal.Abstraction; using UnityEngine; -using UnityEngine.Events; namespace S1API.Quests { @@ -31,8 +32,8 @@ internal QuestEntry(S1Quests.QuestEntry questEntry) => /// public event Action OnComplete { - add => S1QuestEntry.onComplete.AddListener((UnityAction)value.Invoke); - remove => S1QuestEntry.onComplete.RemoveListener((UnityAction)value.Invoke); + add => EventHelper.AddListener(value, S1QuestEntry.onComplete); + remove => EventHelper.RemoveListener(value, S1QuestEntry.onComplete); } /// diff --git a/S1API/Storages/StorageInstance.cs b/S1API/Storages/StorageInstance.cs index 7ca4bacd..217f49f1 100644 --- a/S1API/Storages/StorageInstance.cs +++ b/S1API/Storages/StorageInstance.cs @@ -6,8 +6,8 @@ using System; using System.Linq; +using S1API.Internal.Abstraction; using S1API.Items; -using UnityEngine.Events; namespace S1API.Storages { @@ -48,14 +48,14 @@ public bool CanItemFit(ItemInstance itemInstance, int quantity = 1) => /// The item instance you want to store. public void AddItem(ItemInstance itemInstance) => S1Storage.InsertItem(itemInstance.S1ItemInstance); - + /// /// An action fired when the storage container is opened by the player. /// public event Action OnOpened { - add => S1Storage.onOpened.AddListener((UnityAction)value.Invoke); - remove => S1Storage.onOpened.RemoveListener((UnityAction)value.Invoke); + add => EventHelper.AddListener(value, S1Storage.onOpened); + remove => EventHelper.RemoveListener(value, S1Storage.onOpened); } /// @@ -63,8 +63,8 @@ public event Action OnOpened /// public event Action OnClosed { - add => S1Storage.onClosed.AddListener((UnityAction)value.Invoke); - remove => S1Storage.onClosed.RemoveListener((UnityAction)value.Invoke); + add => EventHelper.AddListener(value, S1Storage.onClosed); + remove => EventHelper.RemoveListener(value, S1Storage.onClosed); } } } \ No newline at end of file