summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SMAPI/Events/DayStartedEventArgs.cs7
-rw-r--r--src/SMAPI/Events/IGameLoopEvents.cs18
-rw-r--r--src/SMAPI/Events/SaveCreatedEventArgs.cs7
-rw-r--r--src/SMAPI/Events/SaveCreatingEventArgs.cs7
-rw-r--r--src/SMAPI/Events/SaveLoadedEventArgs.cs7
-rw-r--r--src/SMAPI/Events/SavedEventArgs.cs7
-rw-r--r--src/SMAPI/Events/SavingEventArgs.cs7
-rw-r--r--src/SMAPI/Framework/Events/EventManager.cs24
-rw-r--r--src/SMAPI/Framework/Events/ModGameLoopEvents.cs42
-rw-r--r--src/SMAPI/Framework/InternalExtensions.cs12
-rw-r--r--src/SMAPI/Framework/SGame.cs9
-rw-r--r--src/SMAPI/Framework/Singleton.cs10
-rw-r--r--src/SMAPI/StardewModdingAPI.csproj7
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" />