diff options
-rw-r--r-- | src/SMAPI/Events/DayStartedEventArgs.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Events/IGameLoopEvents.cs | 18 | ||||
-rw-r--r-- | src/SMAPI/Events/SaveCreatedEventArgs.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Events/SaveCreatingEventArgs.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Events/SaveLoadedEventArgs.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Events/SavedEventArgs.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Events/SavingEventArgs.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Framework/Events/EventManager.cs | 24 | ||||
-rw-r--r-- | src/SMAPI/Framework/Events/ModGameLoopEvents.cs | 42 | ||||
-rw-r--r-- | src/SMAPI/Framework/InternalExtensions.cs | 12 | ||||
-rw-r--r-- | src/SMAPI/Framework/SGame.cs | 9 | ||||
-rw-r--r-- | src/SMAPI/Framework/Singleton.cs | 10 | ||||
-rw-r--r-- | src/SMAPI/StardewModdingAPI.csproj | 7 |
13 files changed, 164 insertions, 0 deletions
diff --git a/src/SMAPI/Events/DayStartedEventArgs.cs b/src/SMAPI/Events/DayStartedEventArgs.cs new file mode 100644 index 00000000..45823628 --- /dev/null +++ b/src/SMAPI/Events/DayStartedEventArgs.cs @@ -0,0 +1,7 @@ +using System; + +namespace StardewModdingAPI.Events +{ + /// <summary>Event arguments for an <see cref="IGameLoopEvents.DayStarted"/> event.</summary> + public class DayStartedEventArgs : EventArgs { } +} diff --git a/src/SMAPI/Events/IGameLoopEvents.cs b/src/SMAPI/Events/IGameLoopEvents.cs index 8ab86c9e..165aa0ce 100644 --- a/src/SMAPI/Events/IGameLoopEvents.cs +++ b/src/SMAPI/Events/IGameLoopEvents.cs @@ -13,5 +13,23 @@ namespace StardewModdingAPI.Events /// <summary>Raised after the game state is updated (≈60 times per second).</summary> event EventHandler<UpdateTickedEventArgs> UpdateTicked; + + /// <summary>Raised before the game creates a new save file.</summary> + event EventHandler<SaveCreatingEventArgs> SaveCreating; + + /// <summary>Raised after the game finishes creating the save file.</summary> + event EventHandler<SaveCreatedEventArgs> SaveCreated; + + /// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary> + event EventHandler<SavingEventArgs> Saving; + + /// <summary>Raised after the game finishes writing data to the save file (except the initial save creation).</summary> + event EventHandler<SavedEventArgs> Saved; + + /// <summary>Raised after the player loads a save slot.</summary> + event EventHandler<SaveLoadedEventArgs> SaveLoaded; + + /// <summary>Raised after the game begins a new day (including when the player loads a save).</summary> + event EventHandler<DayStartedEventArgs> DayStarted; } } diff --git a/src/SMAPI/Events/SaveCreatedEventArgs.cs b/src/SMAPI/Events/SaveCreatedEventArgs.cs new file mode 100644 index 00000000..5ae22531 --- /dev/null +++ b/src/SMAPI/Events/SaveCreatedEventArgs.cs @@ -0,0 +1,7 @@ +using System; + +namespace StardewModdingAPI.Events +{ + /// <summary>Event arguments for an <see cref="IGameLoopEvents.SaveCreated"/> event.</summary> + public class SaveCreatedEventArgs : EventArgs { } +} diff --git a/src/SMAPI/Events/SaveCreatingEventArgs.cs b/src/SMAPI/Events/SaveCreatingEventArgs.cs new file mode 100644 index 00000000..3c83f421 --- /dev/null +++ b/src/SMAPI/Events/SaveCreatingEventArgs.cs @@ -0,0 +1,7 @@ +using System; + +namespace StardewModdingAPI.Events +{ + /// <summary>Event arguments for an <see cref="IGameLoopEvents.SaveCreating"/> event.</summary> + public class SaveCreatingEventArgs : EventArgs { } +} diff --git a/src/SMAPI/Events/SaveLoadedEventArgs.cs b/src/SMAPI/Events/SaveLoadedEventArgs.cs new file mode 100644 index 00000000..f8aaa7f7 --- /dev/null +++ b/src/SMAPI/Events/SaveLoadedEventArgs.cs @@ -0,0 +1,7 @@ +using System; + +namespace StardewModdingAPI.Events +{ + /// <summary>Event arguments for an <see cref="IGameLoopEvents.SaveLoaded"/> event.</summary> + public class SaveLoadedEventArgs : EventArgs { } +} diff --git a/src/SMAPI/Events/SavedEventArgs.cs b/src/SMAPI/Events/SavedEventArgs.cs new file mode 100644 index 00000000..a4e90729 --- /dev/null +++ b/src/SMAPI/Events/SavedEventArgs.cs @@ -0,0 +1,7 @@ +using System; + +namespace StardewModdingAPI.Events +{ + /// <summary>Event arguments for an <see cref="IGameLoopEvents.Saved"/> event.</summary> + public class SavedEventArgs : EventArgs { } +} diff --git a/src/SMAPI/Events/SavingEventArgs.cs b/src/SMAPI/Events/SavingEventArgs.cs new file mode 100644 index 00000000..f323ca9e --- /dev/null +++ b/src/SMAPI/Events/SavingEventArgs.cs @@ -0,0 +1,7 @@ +using System; + +namespace StardewModdingAPI.Events +{ + /// <summary>Event arguments for an <see cref="IGameLoopEvents.Saving"/> event.</summary> + public class SavingEventArgs : EventArgs { } +} diff --git a/src/SMAPI/Framework/Events/EventManager.cs b/src/SMAPI/Framework/Events/EventManager.cs index 1435976a..023c45de 100644 --- a/src/SMAPI/Framework/Events/EventManager.cs +++ b/src/SMAPI/Framework/Events/EventManager.cs @@ -23,6 +23,24 @@ namespace StardewModdingAPI.Framework.Events /// <summary>Raised after the game performs its overall update tick (≈60 times per second).</summary> public readonly ManagedEvent<UpdateTickedEventArgs> UpdateTicked; + /// <summary>Raised before the game creates the save file.</summary> + public readonly ManagedEvent<SaveCreatingEventArgs> SaveCreating; + + /// <summary>Raised after the game finishes creating the save file.</summary> + public readonly ManagedEvent<SaveCreatedEventArgs> SaveCreated; + + /// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary> + public readonly ManagedEvent<SavingEventArgs> Saving; + + /// <summary>Raised after the game finishes writing data to the save file (except the initial save creation).</summary> + public readonly ManagedEvent<SavedEventArgs> Saved; + + /// <summary>Raised after the player loads a save slot.</summary> + public readonly ManagedEvent<SaveLoadedEventArgs> SaveLoaded; + + /// <summary>Raised after the game begins a new day, including when loading a save.</summary> + public readonly ManagedEvent<DayStartedEventArgs> DayStarted; + /**** ** Input ****/ @@ -267,6 +285,12 @@ namespace StardewModdingAPI.Framework.Events this.GameLaunched = ManageEventOf<GameLaunchedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.GameLaunched)); this.UpdateTicking = ManageEventOf<UpdateTickingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.UpdateTicking)); this.UpdateTicked = ManageEventOf<UpdateTickedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.UpdateTicked)); + this.SaveCreating = ManageEventOf<SaveCreatingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.SaveCreating)); + this.SaveCreated = ManageEventOf<SaveCreatedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.SaveCreated)); + this.Saving = ManageEventOf<SavingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.Saving)); + this.Saved = ManageEventOf<SavedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.Saved)); + this.SaveLoaded = ManageEventOf<SaveLoadedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.SaveLoaded)); + this.DayStarted = ManageEventOf<DayStartedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.DayStarted)); this.ButtonPressed = ManageEventOf<ButtonPressedEventArgs>(nameof(IModEvents.Input), nameof(IInputEvents.ButtonPressed)); this.ButtonReleased = ManageEventOf<ButtonReleasedEventArgs>(nameof(IModEvents.Input), nameof(IInputEvents.ButtonReleased)); diff --git a/src/SMAPI/Framework/Events/ModGameLoopEvents.cs b/src/SMAPI/Framework/Events/ModGameLoopEvents.cs index 781597ef..cf7e54aa 100644 --- a/src/SMAPI/Framework/Events/ModGameLoopEvents.cs +++ b/src/SMAPI/Framework/Events/ModGameLoopEvents.cs @@ -30,6 +30,48 @@ namespace StardewModdingAPI.Framework.Events remove => this.EventManager.UpdateTicked.Remove(value); } + /// <summary>Raised before the game creates a new save file.</summary> + public event EventHandler<SaveCreatingEventArgs> SaveCreating + { + add => this.EventManager.SaveCreating.Add(value); + remove => this.EventManager.SaveCreating.Remove(value); + } + + /// <summary>Raised after the game finishes creating the save file.</summary> + public event EventHandler<SaveCreatedEventArgs> SaveCreated + { + add => this.EventManager.SaveCreated.Add(value); + remove => this.EventManager.SaveCreated.Remove(value); + } + + /// <summary>Raised before the game begins writes data to the save file.</summary> + public event EventHandler<SavingEventArgs> Saving + { + add => this.EventManager.Saving.Add(value); + remove => this.EventManager.Saving.Remove(value); + } + + /// <summary>Raised after the game finishes writing data to the save file.</summary> + public event EventHandler<SavedEventArgs> Saved + { + add => this.EventManager.Saved.Add(value); + remove => this.EventManager.Saved.Remove(value); + } + + /// <summary>Raised after the player loads a save slot.</summary> + public event EventHandler<SaveLoadedEventArgs> SaveLoaded + { + add => this.EventManager.SaveLoaded.Add(value); + remove => this.EventManager.SaveLoaded.Remove(value); + } + + /// <summary>Raised after the game begins a new day (including when the player loads a save).</summary> + public event EventHandler<DayStartedEventArgs> DayStarted + { + add => this.EventManager.DayStarted.Add(value); + remove => this.EventManager.DayStarted.Remove(value); + } + /********* ** Public methods diff --git a/src/SMAPI/Framework/InternalExtensions.cs b/src/SMAPI/Framework/InternalExtensions.cs index ff3925fb..b51ff6a8 100644 --- a/src/SMAPI/Framework/InternalExtensions.cs +++ b/src/SMAPI/Framework/InternalExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Reflection; using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI.Framework.Events; using StardewModdingAPI.Framework.Reflection; using StardewValley; @@ -40,6 +41,17 @@ namespace StardewModdingAPI.Framework } /**** + ** ManagedEvent + ****/ + /// <summary>Raise the event and notify all handlers.</summary> + /// <typeparam name="TEventArgs">The empty event arguments type to construct.</typeparam> + /// <param name="event">The event to raise.</param> + public static void RaiseEmpty<TEventArgs>(this ManagedEvent<TEventArgs> @event) where TEventArgs : new() + { + @event.Raise(Singleton<TEventArgs>.Instance); + } + + /**** ** Exceptions ****/ /// <summary>Get a string representation of an exception suitable for writing to the error log.</summary> diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index a432e844..ef851afc 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -323,6 +323,7 @@ namespace StardewModdingAPI.Framework { this.IsBetweenCreateEvents = true; this.Monitor.Log("Context: before save creation.", LogLevel.Trace); + this.Events.SaveCreating.RaiseEmpty(); this.Events.Legacy_BeforeCreateSave.Raise(); } @@ -331,6 +332,7 @@ namespace StardewModdingAPI.Framework { this.IsBetweenSaveEvents = true; this.Monitor.Log("Context: before save.", LogLevel.Trace); + this.Events.Saving.RaiseEmpty(); this.Events.Legacy_BeforeSave.Raise(); } @@ -344,6 +346,7 @@ namespace StardewModdingAPI.Framework // raise after-create this.IsBetweenCreateEvents = false; this.Monitor.Log($"Context: after save creation, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); + this.Events.SaveCreated.RaiseEmpty(); this.Events.Legacy_AfterCreateSave.Raise(); } if (this.IsBetweenSaveEvents) @@ -351,6 +354,9 @@ namespace StardewModdingAPI.Framework // raise after-save this.IsBetweenSaveEvents = false; this.Monitor.Log($"Context: after save, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); + this.Events.Saved.RaiseEmpty(); + this.Events.DayStarted.RaiseEmpty(); + this.Events.Legacy_AfterSave.Raise(); this.Events.Legacy_AfterDayStarted.Raise(); } @@ -410,6 +416,9 @@ namespace StardewModdingAPI.Framework // raise events this.RaisedAfterLoadEvent = true; + this.Events.SaveLoaded.RaiseEmpty(); + this.Events.DayStarted.RaiseEmpty(); + this.Events.Legacy_AfterLoad.Raise(); this.Events.Legacy_AfterDayStarted.Raise(); } diff --git a/src/SMAPI/Framework/Singleton.cs b/src/SMAPI/Framework/Singleton.cs new file mode 100644 index 00000000..399a8bf0 --- /dev/null +++ b/src/SMAPI/Framework/Singleton.cs @@ -0,0 +1,10 @@ +namespace StardewModdingAPI.Framework +{ + /// <summary>Provides singleton instances of a given type.</summary> + /// <typeparam name="T">The instance type.</typeparam> + internal static class Singleton<T> where T : new() + { + /// <summary>The singleton instance.</summary> + public static T Instance { get; } = new T(); + } +} diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index 5ddee30c..4c8f2ffa 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -79,6 +79,12 @@ <Compile Include="..\..\build\GlobalAssemblyInfo.cs"> <Link>Properties\GlobalAssemblyInfo.cs</Link> </Compile> + <Compile Include="Events\DayStartedEventArgs.cs" /> + <Compile Include="Events\SaveCreatingEventArgs.cs" /> + <Compile Include="Events\SavedEventArgs.cs" /> + <Compile Include="Events\SavingEventArgs.cs" /> + <Compile Include="Events\SaveLoadedEventArgs.cs" /> + <Compile Include="Events\SaveCreatedEventArgs.cs" /> <Compile Include="Events\UpdateTickedEventArgs.cs" /> <Compile Include="Events\GameLaunchedEventArgs.cs" /> <Compile Include="Events\MouseWheelScrolledEventArgs.cs" /> @@ -125,6 +131,7 @@ <Compile Include="Framework\Events\ModInputEvents.cs" /> <Compile Include="Framework\Input\GamePadStateBuilder.cs" /> <Compile Include="Framework\ModHelpers\InputHelper.cs" /> + <Compile Include="Framework\Singleton.cs" /> <Compile Include="Framework\StateTracking\Comparers\GenericEqualsComparer.cs" /> <Compile Include="Framework\WatcherCore.cs" /> <Compile Include="IDataHelper.cs" /> |