diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/StardewModdingAPI/Events/ContentEvents.cs | 37 | ||||
-rw-r--r-- | src/StardewModdingAPI/Events/GameEvents.cs | 98 | ||||
-rw-r--r-- | src/StardewModdingAPI/Events/PlayerEvents.cs | 48 | ||||
-rw-r--r-- | src/StardewModdingAPI/Events/TimeEvents.cs | 25 | ||||
-rw-r--r-- | src/StardewModdingAPI/Framework/InternalExtensions.cs | 38 | ||||
-rw-r--r-- | src/StardewModdingAPI/Framework/ModRegistry.cs | 10 | ||||
-rw-r--r-- | src/StardewModdingAPI/Program.cs | 1 |
7 files changed, 124 insertions, 133 deletions
diff --git a/src/StardewModdingAPI/Events/ContentEvents.cs b/src/StardewModdingAPI/Events/ContentEvents.cs index 0dcd2cc6..8fa9ae3c 100644 --- a/src/StardewModdingAPI/Events/ContentEvents.cs +++ b/src/StardewModdingAPI/Events/ContentEvents.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using StardewModdingAPI.Framework; namespace StardewModdingAPI.Events @@ -19,6 +20,9 @@ namespace StardewModdingAPI.Events /// <summary>The mods using the experimental API for which a warning has been raised.</summary> private static readonly HashSet<string> WarnedMods = new HashSet<string>(); + /// <summary>The backing field for <see cref="AfterAssetLoaded"/>.</summary> + [SuppressMessage("ReSharper", "InconsistentNaming")] + private static event EventHandler<IContentEventHelper> _AfterAssetLoaded; /********* ** Events @@ -32,7 +36,15 @@ namespace StardewModdingAPI.Events #else internal #endif - static event EventHandler<IContentEventHelper> AfterAssetLoaded; + static event EventHandler<IContentEventHelper> AfterAssetLoaded + { + add + { + ContentEvents.RaiseContentExperimentalWarning(); + ContentEvents._AfterAssetLoaded += value; + } + remove => ContentEvents._AfterAssetLoaded -= value; + } /********* @@ -61,30 +73,21 @@ namespace StardewModdingAPI.Events /// <param name="contentHelper">Encapsulates access and changes to content being read from a data file.</param> internal static void InvokeAfterAssetLoaded(IMonitor monitor, IContentEventHelper contentHelper) { - if (ContentEvents.AfterAssetLoaded != null) - { - Delegate[] handlers = ContentEvents.AfterAssetLoaded.GetInvocationList(); - ContentEvents.RaiseDeprecationWarning(handlers); - monitor.SafelyRaiseGenericEvent($"{nameof(ContentEvents)}.{nameof(ContentEvents.AfterAssetLoaded)}", handlers, null, contentHelper); - } + monitor.SafelyRaiseGenericEvent($"{nameof(ContentEvents)}.{nameof(ContentEvents.AfterAssetLoaded)}", ContentEvents._AfterAssetLoaded?.GetInvocationList(), null, contentHelper); } /********* ** Private methods *********/ - /// <summary>Raise a 'experimental API' warning for each mod using the content API.</summary> - /// <param name="handlers">The event handlers.</param> - private static void RaiseDeprecationWarning(Delegate[] handlers) + /// <summary>Raise an 'experimental API' warning for a mod using the content API.</summary> + private static void RaiseContentExperimentalWarning() { - foreach (Delegate handler in handlers) + string modName = ContentEvents.ModRegistry.GetModFromStack() ?? "An unknown mod"; + if (!ContentEvents.WarnedMods.Contains(modName)) { - string modName = ContentEvents.ModRegistry.GetModFrom(handler) ?? "An unknown mod"; - if (!ContentEvents.WarnedMods.Contains(modName)) - { - ContentEvents.WarnedMods.Add(modName); - ContentEvents.Monitor.Log($"{modName} used the undocumented and experimental content API, which may change or be removed without warning.", LogLevel.Warn); - } + ContentEvents.WarnedMods.Add(modName); + ContentEvents.Monitor.Log($"{modName} used the undocumented and experimental content API, which may change or be removed without warning.", LogLevel.Warn); } } } diff --git a/src/StardewModdingAPI/Events/GameEvents.cs b/src/StardewModdingAPI/Events/GameEvents.cs index 4f9ce7a7..8e3cf662 100644 --- a/src/StardewModdingAPI/Events/GameEvents.cs +++ b/src/StardewModdingAPI/Events/GameEvents.cs @@ -1,6 +1,8 @@ using System; +using System.Diagnostics.CodeAnalysis; using StardewModdingAPI.Framework; +#pragma warning disable 618 // Suppress obsolete-symbol errors in this file. Since several events are marked obsolete, this produces unnecessary warnings. namespace StardewModdingAPI.Events { /// <summary>Events raised when the game changes state.</summary> @@ -12,6 +14,22 @@ namespace StardewModdingAPI.Events /// <summary>Manages deprecation warnings.</summary> private static DeprecationManager DeprecationManager; + /// <summary>The backing field for <see cref="Initialize"/>.</summary> + [SuppressMessage("ReSharper", "InconsistentNaming")] + private static event EventHandler _Initialize; + + /// <summary>The backing field for <see cref="LoadContent"/>.</summary> + [SuppressMessage("ReSharper", "InconsistentNaming")] + private static event EventHandler _LoadContent; + + /// <summary>The backing field for <see cref="GameLoaded"/>.</summary> + [SuppressMessage("ReSharper", "InconsistentNaming")] + private static event EventHandler _GameLoaded; + + /// <summary>The backing field for <see cref="FirstUpdateTick"/>.</summary> + [SuppressMessage("ReSharper", "InconsistentNaming")] + private static event EventHandler _FirstUpdateTick; + /********* ** Events @@ -24,19 +42,51 @@ namespace StardewModdingAPI.Events /// <summary>Raised during launch after configuring XNA or MonoGame. The game window hasn't been opened by this point. Called after <see cref="Microsoft.Xna.Framework.Game.Initialize"/>.</summary> [Obsolete("The " + nameof(Mod) + "." + nameof(Mod.Entry) + " method is now called after the " + nameof(GameEvents.Initialize) + " event, so any contained logic can be done directly in " + nameof(Mod.Entry) + ".")] - public static event EventHandler Initialize; + public static event EventHandler Initialize + { + add + { + GameEvents.DeprecationManager.Warn($"{nameof(GameEvents)}.{nameof(GameEvents.Initialize)}", "1.10", DeprecationLevel.Info); + GameEvents._Initialize += value; + } + remove => GameEvents._Initialize -= value; + } /// <summary>Raised before XNA loads or reloads graphics resources. Called during <see cref="Microsoft.Xna.Framework.Game.LoadContent"/>.</summary> [Obsolete("The " + nameof(Mod) + "." + nameof(Mod.Entry) + " method is now called after the " + nameof(GameEvents.LoadContent) + " event, so any contained logic can be done directly in " + nameof(Mod.Entry) + ".")] - public static event EventHandler LoadContent; + public static event EventHandler LoadContent + { + add + { + GameEvents.DeprecationManager.Warn($"{nameof(GameEvents)}.{nameof(GameEvents.LoadContent)}", "1.10", DeprecationLevel.Info); + GameEvents._LoadContent += value; + } + remove => GameEvents._LoadContent -= value; + } /// <summary>Raised during launch after configuring Stardew Valley, loading it into memory, and opening the game window. The window is still blank by this point.</summary> [Obsolete("The " + nameof(Mod) + "." + nameof(Mod.Entry) + " method is now called after the game loads, so any contained logic can be done directly in " + nameof(Mod.Entry) + ".")] - public static event EventHandler GameLoaded; + public static event EventHandler GameLoaded + { + add + { + GameEvents.DeprecationManager.Warn($"{nameof(GameEvents)}.{nameof(GameEvents.GameLoaded)}", "1.12", DeprecationLevel.Info); + GameEvents._GameLoaded += value; + } + remove => GameEvents._GameLoaded -= value; + } /// <summary>Raised during the first game update tick.</summary> [Obsolete("The " + nameof(Mod) + "." + nameof(Mod.Entry) + " method is now called after the game loads, so any contained logic can be done directly in " + nameof(Mod.Entry) + ".")] - public static event EventHandler FirstUpdateTick; + public static event EventHandler FirstUpdateTick + { + add + { + GameEvents.DeprecationManager.Warn($"{nameof(GameEvents)}.{nameof(GameEvents.FirstUpdateTick)}", "1.12", DeprecationLevel.Info); + GameEvents._FirstUpdateTick += value; + } + remove => GameEvents._FirstUpdateTick -= value; + } /// <summary>Raised when the game updates its state (≈60 times per second).</summary> public static event EventHandler UpdateTick; @@ -74,62 +124,30 @@ namespace StardewModdingAPI.Events /// <param name="monitor">Encapsulates logging and monitoring.</param> internal static void InvokeInitialize(IMonitor monitor) { - // notify SMAPI monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.InitializeInternal)}", GameEvents.InitializeInternal?.GetInvocationList()); - - // notify mods - if (GameEvents.Initialize == null) - return; - string name = $"{nameof(GameEvents)}.{nameof(GameEvents.Initialize)}"; - Delegate[] handlers = GameEvents.Initialize.GetInvocationList(); - GameEvents.DeprecationManager.WarnForEvent(handlers, name, "1.10", DeprecationLevel.Info); - monitor.SafelyRaisePlainEvent(name, handlers); + monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.Initialize)}", GameEvents._Initialize?.GetInvocationList()); } /// <summary>Raise a <see cref="LoadContent"/> event.</summary> /// <param name="monitor">Encapsulates logging and monitoring.</param> internal static void InvokeLoadContent(IMonitor monitor) { - if (GameEvents.LoadContent == null) - return; - - string name = $"{nameof(GameEvents)}.{nameof(GameEvents.LoadContent)}"; - Delegate[] handlers = GameEvents.LoadContent.GetInvocationList(); - - GameEvents.DeprecationManager.WarnForEvent(handlers, name, "1.10", DeprecationLevel.Info); - monitor.SafelyRaisePlainEvent(name, handlers); + monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.LoadContent)}", GameEvents._LoadContent?.GetInvocationList()); } /// <summary>Raise a <see cref="GameLoaded"/> event.</summary> /// <param name="monitor">Encapsulates monitoring and logging.</param> internal static void InvokeGameLoaded(IMonitor monitor) { - // notify SMAPI monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.GameLoadedInternal)}", GameEvents.GameLoadedInternal?.GetInvocationList()); - - // notify mods - if (GameEvents.GameLoaded == null) - return; - - string name = $"{nameof(GameEvents)}.{nameof(GameEvents.GameLoaded)}"; - Delegate[] handlers = GameEvents.GameLoaded.GetInvocationList(); - - GameEvents.DeprecationManager.WarnForEvent(handlers, name, "1.12", DeprecationLevel.Info); - monitor.SafelyRaisePlainEvent(name, handlers); + monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.GameLoaded)}", GameEvents._GameLoaded?.GetInvocationList()); } /// <summary>Raise a <see cref="FirstUpdateTick"/> event.</summary> /// <param name="monitor">Encapsulates monitoring and logging.</param> internal static void InvokeFirstUpdateTick(IMonitor monitor) { - if (GameEvents.FirstUpdateTick == null) - return; - - string name = $"{nameof(GameEvents)}.{nameof(GameEvents.FirstUpdateTick)}"; - Delegate[] handlers = GameEvents.FirstUpdateTick.GetInvocationList(); - - GameEvents.DeprecationManager.WarnForEvent(handlers, name, "1.12", DeprecationLevel.Info); - monitor.SafelyRaisePlainEvent(name, handlers); + monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.FirstUpdateTick)}", GameEvents._FirstUpdateTick?.GetInvocationList()); } /// <summary>Raise an <see cref="UpdateTick"/> event.</summary> diff --git a/src/StardewModdingAPI/Events/PlayerEvents.cs b/src/StardewModdingAPI/Events/PlayerEvents.cs index b02ebfec..37649fee 100644 --- a/src/StardewModdingAPI/Events/PlayerEvents.cs +++ b/src/StardewModdingAPI/Events/PlayerEvents.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using StardewModdingAPI.Framework; using StardewValley; using SFarmer = StardewValley.Farmer; +#pragma warning disable 618 // Suppress obsolete-symbol errors in this file. Since several events are marked obsolete, this produces unnecessary warnings. namespace StardewModdingAPI.Events { /// <summary>Events raised when the player data changes.</summary> @@ -16,17 +18,41 @@ namespace StardewModdingAPI.Events /// <summary>Manages deprecation warnings.</summary> private static DeprecationManager DeprecationManager; + /// <summary>The backing field for <see cref="LoadedGame"/>.</summary> + [SuppressMessage("ReSharper", "InconsistentNaming")] + private static event EventHandler<EventArgsLoadedGameChanged> _LoadedGame; + + /// <summary>The backing field for <see cref="FarmerChanged"/>.</summary> + [SuppressMessage("ReSharper", "InconsistentNaming")] + private static event EventHandler<EventArgsFarmerChanged> _FarmerChanged; + /********* ** Events *********/ /// <summary>Raised after the player loads a saved game.</summary> [Obsolete("Use " + nameof(SaveEvents) + "." + nameof(SaveEvents.AfterLoad) + " instead")] - public static event EventHandler<EventArgsLoadedGameChanged> LoadedGame; + public static event EventHandler<EventArgsLoadedGameChanged> LoadedGame + { + add + { + PlayerEvents.DeprecationManager.Warn($"{nameof(PlayerEvents)}.{nameof(PlayerEvents.LoadedGame)}", "1.6", DeprecationLevel.Info); + PlayerEvents._LoadedGame += value; + } + remove => PlayerEvents._LoadedGame -= value; + } /// <summary>Raised after the game assigns a new player character. This happens just before <see cref="LoadedGame"/>; it's unclear how this would happen any other time.</summary> [Obsolete("should no longer be used")] - public static event EventHandler<EventArgsFarmerChanged> FarmerChanged; + public static event EventHandler<EventArgsFarmerChanged> FarmerChanged + { + add + { + PlayerEvents.DeprecationManager.Warn($"{nameof(PlayerEvents)}.{nameof(PlayerEvents.FarmerChanged)}", "1.6", DeprecationLevel.Info); + PlayerEvents._FarmerChanged += value; + } + remove => PlayerEvents._FarmerChanged -= value; + } /// <summary>Raised after the player's inventory changes in any way (added or removed item, sorted, etc).</summary> public static event EventHandler<EventArgsInventoryChanged> InventoryChanged; @@ -50,14 +76,7 @@ namespace StardewModdingAPI.Events /// <param name="loaded">Whether the save has been loaded. This is always true.</param> internal static void InvokeLoadedGame(IMonitor monitor, EventArgsLoadedGameChanged loaded) { - if (PlayerEvents.LoadedGame == null) - return; - - string name = $"{nameof(PlayerEvents)}.{nameof(PlayerEvents.LoadedGame)}"; - Delegate[] handlers = PlayerEvents.LoadedGame.GetInvocationList(); - - PlayerEvents.DeprecationManager.WarnForEvent(handlers, name, "1.6", DeprecationLevel.Info); - monitor.SafelyRaiseGenericEvent(name, handlers, null, loaded); + monitor.SafelyRaiseGenericEvent($"{nameof(PlayerEvents)}.{nameof(PlayerEvents.LoadedGame)}", PlayerEvents._LoadedGame?.GetInvocationList(), null, loaded); } /// <summary>Raise a <see cref="FarmerChanged"/> event.</summary> @@ -66,14 +85,7 @@ namespace StardewModdingAPI.Events /// <param name="newFarmer">The new player character.</param> internal static void InvokeFarmerChanged(IMonitor monitor, SFarmer priorFarmer, SFarmer newFarmer) { - if (PlayerEvents.FarmerChanged == null) - return; - - string name = $"{nameof(PlayerEvents)}.{nameof(PlayerEvents.FarmerChanged)}"; - Delegate[] handlers = PlayerEvents.FarmerChanged.GetInvocationList(); - - PlayerEvents.DeprecationManager.WarnForEvent(handlers, name, "1.6", DeprecationLevel.Info); - monitor.SafelyRaiseGenericEvent(name, handlers, null, new EventArgsFarmerChanged(priorFarmer, newFarmer)); + monitor.SafelyRaiseGenericEvent($"{nameof(PlayerEvents)}.{nameof(PlayerEvents.FarmerChanged)}", PlayerEvents._FarmerChanged?.GetInvocationList(), null, new EventArgsFarmerChanged(priorFarmer, newFarmer)); } /// <summary>Raise an <see cref="InventoryChanged"/> event.</summary> diff --git a/src/StardewModdingAPI/Events/TimeEvents.cs b/src/StardewModdingAPI/Events/TimeEvents.cs index 3f06a46b..572898c7 100644 --- a/src/StardewModdingAPI/Events/TimeEvents.cs +++ b/src/StardewModdingAPI/Events/TimeEvents.cs @@ -1,6 +1,8 @@ using System; +using System.Diagnostics.CodeAnalysis; using StardewModdingAPI.Framework; +#pragma warning disable 618 // Suppress obsolete-symbol errors in this file. Since several events are marked obsolete, this produces unnecessary warnings. namespace StardewModdingAPI.Events { /// <summary>Events raised when the in-game date or time changes.</summary> @@ -12,6 +14,10 @@ namespace StardewModdingAPI.Events /// <summary>Manages deprecation warnings.</summary> private static DeprecationManager DeprecationManager; + /// <summary>The backing field for <see cref="OnNewDay"/>.</summary> + [SuppressMessage("ReSharper", "InconsistentNaming")] + private static event EventHandler<EventArgsNewDay> _OnNewDay; + /********* ** Events @@ -33,7 +39,15 @@ namespace StardewModdingAPI.Events /// <summary>Raised when the player is transitioning to a new day and the game is performing its day update logic. This event is triggered twice: once after the game starts transitioning, and again after it finishes.</summary> [Obsolete("Use " + nameof(TimeEvents) + "." + nameof(TimeEvents.AfterDayStarted) + " or " + nameof(SaveEvents) + " instead")] - public static event EventHandler<EventArgsNewDay> OnNewDay; + public static event EventHandler<EventArgsNewDay> OnNewDay + { + add + { + TimeEvents.DeprecationManager.Warn($"{nameof(TimeEvents)}.{nameof(TimeEvents.OnNewDay)}", "1.6", DeprecationLevel.Info); + TimeEvents._OnNewDay += value; + } + remove => TimeEvents._OnNewDay -= value; + } /********* @@ -96,14 +110,7 @@ namespace StardewModdingAPI.Events /// <param name="isTransitioning">Whether the game just started the transition (<c>true</c>) or finished it (<c>false</c>).</param> internal static void InvokeOnNewDay(IMonitor monitor, int priorDay, int newDay, bool isTransitioning) { - if (TimeEvents.OnNewDay == null) - return; - - string name = $"{nameof(TimeEvents)}.{nameof(TimeEvents.OnNewDay)}"; - Delegate[] handlers = TimeEvents.OnNewDay.GetInvocationList(); - - TimeEvents.DeprecationManager.WarnForEvent(handlers, name, "1.6", DeprecationLevel.Info); - monitor.SafelyRaiseGenericEvent(name, handlers, null, new EventArgsNewDay(priorDay, newDay, isTransitioning)); + monitor.SafelyRaiseGenericEvent($"{nameof(TimeEvents)}.{nameof(TimeEvents.OnNewDay)}", TimeEvents._OnNewDay?.GetInvocationList(), null, new EventArgsNewDay(priorDay, newDay, isTransitioning)); } } } diff --git a/src/StardewModdingAPI/Framework/InternalExtensions.cs b/src/StardewModdingAPI/Framework/InternalExtensions.cs index cadf6598..b99d3798 100644 --- a/src/StardewModdingAPI/Framework/InternalExtensions.cs +++ b/src/StardewModdingAPI/Framework/InternalExtensions.cs @@ -10,23 +10,6 @@ namespace StardewModdingAPI.Framework /// <summary>Provides extension methods for SMAPI's internal use.</summary> internal static class InternalExtensions { - /********* - ** Properties - *********/ - /// <summary>Tracks the installed mods.</summary> - private static ModRegistry ModRegistry; - - - /********* - ** Public methods - *********/ - /// <summary>Injects types required for backwards compatibility.</summary> - /// <param name="modRegistry">Tracks the installed mods.</param> - internal static void Shim(ModRegistry modRegistry) - { - InternalExtensions.ModRegistry = modRegistry; - } - /**** ** IMonitor ****/ @@ -111,27 +94,6 @@ namespace StardewModdingAPI.Framework } /**** - ** Deprecation - ****/ - /// <summary>Log a deprecation warning for mods using an event.</summary> - /// <param name="deprecationManager">The deprecation manager to extend.</param> - /// <param name="handlers">The event handlers.</param> - /// <param name="nounPhrase">A noun phrase describing what is deprecated.</param> - /// <param name="version">The SMAPI version which deprecated it.</param> - /// <param name="severity">How deprecated the code is.</param> - public static void WarnForEvent(this DeprecationManager deprecationManager, Delegate[] handlers, string nounPhrase, string version, DeprecationLevel severity) - { - if (handlers == null || !handlers.Any()) - return; - - foreach (Delegate handler in handlers) - { - string modName = InternalExtensions.ModRegistry.GetModFrom(handler) ?? "an unknown mod"; // suppress stack trace for unknown mods, not helpful here - deprecationManager.Warn(modName, nounPhrase, version, severity); - } - } - - /**** ** Sprite batch ****/ /// <summary>Get whether the sprite batch is between a begin and end pair.</summary> diff --git a/src/StardewModdingAPI/Framework/ModRegistry.cs b/src/StardewModdingAPI/Framework/ModRegistry.cs index 62063fbd..f9d3cfbf 100644 --- a/src/StardewModdingAPI/Framework/ModRegistry.cs +++ b/src/StardewModdingAPI/Framework/ModRegistry.cs @@ -63,16 +63,6 @@ namespace StardewModdingAPI.Framework return (from mod in this.Mods select mod); } - /// <summary>Get the friendly mod name which handles a delegate.</summary> - /// <param name="delegate">The delegate to follow.</param> - /// <returns>Returns the mod name, or <c>null</c> if the delegate isn't implemented by a known mod.</returns> - public string GetModFrom(Delegate @delegate) - { - return @delegate?.Target != null - ? this.GetModFrom(@delegate.Target.GetType()) - : null; - } - /// <summary>Get the friendly mod name which defines a type.</summary> /// <param name="type">The type to check.</param> /// <returns>Returns the mod name, or <c>null</c> if the type isn't part of a known mod.</returns> diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 4a4b2ca7..b92108c3 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -322,7 +322,6 @@ namespace StardewModdingAPI #pragma warning disable 618 Command.Shim(this.CommandManager, this.DeprecationManager, this.ModRegistry); Config.Shim(this.DeprecationManager); - InternalExtensions.Shim(this.ModRegistry); Log.Shim(this.DeprecationManager, this.GetSecondaryMonitor("legacy mod"), this.ModRegistry); Mod.Shim(this.DeprecationManager); ContentEvents.Shim(this.ModRegistry, this.Monitor); |