diff options
Diffstat (limited to 'src/SMAPI/Framework')
-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 |
5 files changed, 97 insertions, 0 deletions
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(); + } +} |