diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-02-24 19:56:08 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-09-14 16:59:29 -0400 |
commit | bad2ac2a29b8775be97133e4c4cfb67a4a7406ee (patch) | |
tree | 9cc61caa21be489a9eb6b67368e2c40aca17af80 /src/SMAPI/Framework/Events/ManagedEvent.cs | |
parent | 4a297e29eb0c97be799ee3939e9747dc1c631427 (diff) | |
download | SMAPI-bad2ac2a29b8775be97133e4c4cfb67a4a7406ee.tar.gz SMAPI-bad2ac2a29b8775be97133e4c4cfb67a4a7406ee.tar.bz2 SMAPI-bad2ac2a29b8775be97133e4c4cfb67a4a7406ee.zip |
remove deprecated APIs (#606)
Diffstat (limited to 'src/SMAPI/Framework/Events/ManagedEvent.cs')
-rw-r--r-- | src/SMAPI/Framework/Events/ManagedEvent.cs | 105 |
1 files changed, 55 insertions, 50 deletions
diff --git a/src/SMAPI/Framework/Events/ManagedEvent.cs b/src/SMAPI/Framework/Events/ManagedEvent.cs index f9e7f6ec..2afe7a03 100644 --- a/src/SMAPI/Framework/Events/ManagedEvent.cs +++ b/src/SMAPI/Framework/Events/ManagedEvent.cs @@ -1,11 +1,12 @@ using System; +using System.Collections.Generic; using System.Linq; namespace StardewModdingAPI.Framework.Events { /// <summary>An event wrapper which intercepts and logs errors in handler code.</summary> /// <typeparam name="TEventArgs">The event arguments type.</typeparam> - internal class ManagedEvent<TEventArgs> : ManagedEventBase<EventHandler<TEventArgs>> + internal class ManagedEvent<TEventArgs> { /********* ** Fields @@ -13,6 +14,21 @@ namespace StardewModdingAPI.Framework.Events /// <summary>The underlying event.</summary> private event EventHandler<TEventArgs> Event; + /// <summary>A human-readable name for the event.</summary> + private readonly string EventName; + + /// <summary>Writes messages to the log.</summary> + private readonly IMonitor Monitor; + + /// <summary>The mod registry with which to identify mods.</summary> + protected readonly ModRegistry ModRegistry; + + /// <summary>The display names for the mods which added each delegate.</summary> + private readonly IDictionary<EventHandler<TEventArgs>, IModMetadata> SourceMods = new Dictionary<EventHandler<TEventArgs>, IModMetadata>(); + + /// <summary>The cached invocation list.</summary> + private EventHandler<TEventArgs>[] CachedInvocationList; + /********* ** Public methods @@ -22,7 +38,17 @@ namespace StardewModdingAPI.Framework.Events /// <param name="monitor">Writes messages to the log.</param> /// <param name="modRegistry">The mod registry with which to identify mods.</param> public ManagedEvent(string eventName, IMonitor monitor, ModRegistry modRegistry) - : base(eventName, monitor, modRegistry) { } + { + this.EventName = eventName; + this.Monitor = monitor; + this.ModRegistry = modRegistry; + } + + /// <summary>Get whether anything is listening to the event.</summary> + public bool HasListeners() + { + return this.CachedInvocationList?.Length > 0; + } /// <summary>Add an event handler.</summary> /// <param name="handler">The event handler.</param> @@ -91,71 +117,50 @@ namespace StardewModdingAPI.Framework.Events } } } - } - -#if !SMAPI_3_0_STRICT - /// <summary>An event wrapper which intercepts and logs errors in handler code.</summary> - internal class ManagedEvent : ManagedEventBase<EventHandler> - { - /********* - ** Fields - *********/ - /// <summary>The underlying event.</summary> - private event EventHandler Event; /********* - ** Public methods + ** Private methods *********/ - /// <summary>Construct an instance.</summary> - /// <param name="eventName">A human-readable name for the event.</param> - /// <param name="monitor">Writes messages to the log.</param> - /// <param name="modRegistry">The mod registry with which to identify mods.</param> - public ManagedEvent(string eventName, IMonitor monitor, ModRegistry modRegistry) - : base(eventName, monitor, modRegistry) { } - - /// <summary>Add an event handler.</summary> + /// <summary>Track an event handler.</summary> + /// <param name="mod">The mod which added the handler.</param> /// <param name="handler">The event handler.</param> - public void Add(EventHandler handler) + /// <param name="invocationList">The updated event invocation list.</param> + protected void AddTracking(IModMetadata mod, EventHandler<TEventArgs> handler, IEnumerable<EventHandler<TEventArgs>> invocationList) { - this.Add(handler, this.ModRegistry.GetFromStack()); + this.SourceMods[handler] = mod; + this.CachedInvocationList = invocationList?.ToArray() ?? new EventHandler<TEventArgs>[0]; } - /// <summary>Add an event handler.</summary> + /// <summary>Remove tracking for an event handler.</summary> /// <param name="handler">The event handler.</param> - /// <param name="mod">The mod which added the event handler.</param> - public void Add(EventHandler handler, IModMetadata mod) + /// <param name="invocationList">The updated event invocation list.</param> + protected void RemoveTracking(EventHandler<TEventArgs> handler, IEnumerable<EventHandler<TEventArgs>> invocationList) { - this.Event += handler; - this.AddTracking(mod, handler, this.Event?.GetInvocationList().Cast<EventHandler>()); + this.CachedInvocationList = invocationList?.ToArray() ?? new EventHandler<TEventArgs>[0]; + if (!this.CachedInvocationList.Contains(handler)) // don't remove if there's still a reference to the removed handler (e.g. it was added twice and removed once) + this.SourceMods.Remove(handler); } - /// <summary>Remove an event handler.</summary> + /// <summary>Get the mod which registered the given event handler, if available.</summary> /// <param name="handler">The event handler.</param> - public void Remove(EventHandler handler) + protected IModMetadata GetSourceMod(EventHandler<TEventArgs> handler) { - this.Event -= handler; - this.RemoveTracking(handler, this.Event?.GetInvocationList().Cast<EventHandler>()); + return this.SourceMods.TryGetValue(handler, out IModMetadata mod) + ? mod + : null; } - /// <summary>Raise the event and notify all handlers.</summary> - public void Raise() + /// <summary>Log an exception from an event handler.</summary> + /// <param name="handler">The event handler instance.</param> + /// <param name="ex">The exception that was raised.</param> + protected void LogError(EventHandler<TEventArgs> handler, Exception ex) { - if (this.Event == null) - return; - - foreach (EventHandler handler in this.CachedInvocationList) - { - try - { - handler.Invoke(null, EventArgs.Empty); - } - catch (Exception ex) - { - this.LogError(handler, ex); - } - } + IModMetadata mod = this.GetSourceMod(handler); + if (mod != null) + mod.LogAsMod($"This mod failed in the {this.EventName} event. Technical details: \n{ex.GetLogSummary()}", LogLevel.Error); + else + this.Monitor.Log($"A mod failed in the {this.EventName} event. Technical details: \n{ex.GetLogSummary()}", LogLevel.Error); } } -#endif } |