summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/Events/ManagedEvent.cs
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2019-02-24 19:56:08 -0500
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2019-09-14 16:59:29 -0400
commitbad2ac2a29b8775be97133e4c4cfb67a4a7406ee (patch)
tree9cc61caa21be489a9eb6b67368e2c40aca17af80 /src/SMAPI/Framework/Events/ManagedEvent.cs
parent4a297e29eb0c97be799ee3939e9747dc1c631427 (diff)
downloadSMAPI-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.cs105
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
}