summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SMAPI/Framework/InternalExtensions.cs3
-rw-r--r--src/SMAPI/Framework/SCore.cs175
-rw-r--r--src/SMAPI/Framework/SMultiplayer.cs12
3 files changed, 115 insertions, 75 deletions
diff --git a/src/SMAPI/Framework/InternalExtensions.cs b/src/SMAPI/Framework/InternalExtensions.cs
index 580651f3..ba9bbcec 100644
--- a/src/SMAPI/Framework/InternalExtensions.cs
+++ b/src/SMAPI/Framework/InternalExtensions.cs
@@ -64,7 +64,8 @@ namespace StardewModdingAPI.Framework
/// <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);
+ if (@event.HasListeners)
+ @event.Raise(Singleton<TEventArgs>.Instance);
}
/****
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index c1e03634..ec21e38a 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -47,6 +47,7 @@ using StardewModdingAPI.Toolkit.Utilities.PathLookups;
using StardewModdingAPI.Utilities;
using StardewValley;
using StardewValley.Menus;
+using StardewValley.Objects;
using xTile.Display;
using LanguageCode = StardewValley.LocalizedContentManager.LanguageCode;
using MiniMonoModHotfix = MonoMod.Utils.MiniMonoModHotfix;
@@ -808,7 +809,8 @@ namespace StardewModdingAPI.Framework
if (verbose)
this.Monitor.Log($"Events: window size changed to {state.WindowSize.New}.");
- events.WindowResized.Raise(new WindowResizedEventArgs(state.WindowSize.Old, state.WindowSize.New));
+ if (events.WindowResized.HasListeners)
+ events.WindowResized.Raise(new WindowResizedEventArgs(state.WindowSize.Old, state.WindowSize.New));
}
/*********
@@ -823,7 +825,7 @@ namespace StardewModdingAPI.Framework
ICursorPosition cursor = instance.Input.CursorPosition;
// raise cursor moved event
- if (state.Cursor.IsChanged)
+ if (state.Cursor.IsChanged && events.CursorMoved.HasListeners)
events.CursorMoved.Raise(new CursorMovedEventArgs(state.Cursor.Old!, state.Cursor.New!));
// raise mouse wheel scrolled
@@ -831,32 +833,42 @@ namespace StardewModdingAPI.Framework
{
if (verbose)
this.Monitor.Log($"Events: mouse wheel scrolled to {state.MouseWheelScroll.New}.");
- events.MouseWheelScrolled.Raise(new MouseWheelScrolledEventArgs(cursor, state.MouseWheelScroll.Old, state.MouseWheelScroll.New));
+
+ if (events.MouseWheelScrolled.HasListeners)
+ events.MouseWheelScrolled.Raise(new MouseWheelScrolledEventArgs(cursor, state.MouseWheelScroll.Old, state.MouseWheelScroll.New));
}
// raise input button events
if (inputState.ButtonStates.Count > 0)
{
- events.ButtonsChanged.Raise(new ButtonsChangedEventArgs(cursor, inputState));
-
- foreach (var pair in inputState.ButtonStates)
- {
- SButton button = pair.Key;
- SButtonState status = pair.Value;
+ if (events.ButtonsChanged.HasListeners)
+ events.ButtonsChanged.Raise(new ButtonsChangedEventArgs(cursor, inputState));
- if (status == SButtonState.Pressed)
- {
- if (verbose)
- this.Monitor.Log($"Events: button {button} pressed.");
+ bool raisePressed = events.ButtonPressed.HasListeners;
+ bool raiseReleased = events.ButtonReleased.HasListeners;
- events.ButtonPressed.Raise(new ButtonPressedEventArgs(button, cursor, inputState));
- }
- else if (status == SButtonState.Released)
+ if (verbose || raisePressed || raiseReleased)
+ {
+ foreach ((SButton button, SButtonState status) in inputState.ButtonStates)
{
- if (verbose)
- this.Monitor.Log($"Events: button {button} released.");
-
- events.ButtonReleased.Raise(new ButtonReleasedEventArgs(button, cursor, inputState));
+ switch (status)
+ {
+ case SButtonState.Pressed:
+ if (verbose)
+ this.Monitor.Log($"Events: button {button} pressed.");
+
+ if (raisePressed)
+ events.ButtonPressed.Raise(new ButtonPressedEventArgs(button, cursor, inputState));
+ break;
+
+ case SButtonState.Released:
+ if (verbose)
+ this.Monitor.Log($"Events: button {button} released.");
+
+ if (raiseReleased)
+ events.ButtonReleased.Raise(new ButtonReleasedEventArgs(button, cursor, inputState));
+ break;
+ }
}
}
}
@@ -868,14 +880,15 @@ namespace StardewModdingAPI.Framework
*********/
if (state.ActiveMenu.IsChanged)
{
- var was = state.ActiveMenu.Old;
- var now = state.ActiveMenu.New;
+ IClickableMenu? was = state.ActiveMenu.Old;
+ IClickableMenu? now = state.ActiveMenu.New;
if (verbose)
this.Monitor.Log($"Context: menu changed from {was?.GetType().FullName ?? "none"} to {now?.GetType().FullName ?? "none"}.");
// raise menu events
- events.MenuChanged.Raise(new MenuChangedEventArgs(was, now));
+ if (events.MenuChanged.HasListeners)
+ events.MenuChanged.Raise(new MenuChangedEventArgs(was, now));
}
/*********
@@ -898,7 +911,8 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log($"Context: location list changed (added {addedText}; removed {removedText}).");
}
- events.LocationListChanged.Raise(new LocationListChangedEventArgs(added, removed));
+ if (events.LocationListChanged.HasListeners)
+ events.LocationListChanged.Raise(new LocationListChangedEventArgs(added, removed));
}
// raise location contents changed
@@ -906,50 +920,47 @@ namespace StardewModdingAPI.Framework
{
foreach (LocationSnapshot locState in state.Locations.Locations)
{
- var location = locState.Location;
+ GameLocation location = locState.Location;
// buildings changed
- if (locState.Buildings.IsChanged)
+ if (locState.Buildings.IsChanged && events.BuildingListChanged.HasListeners)
events.BuildingListChanged.Raise(new BuildingListChangedEventArgs(location, locState.Buildings.Added, locState.Buildings.Removed));
// debris changed
- if (locState.Debris.IsChanged)
+ if (locState.Debris.IsChanged && events.DebrisListChanged.HasListeners)
events.DebrisListChanged.Raise(new DebrisListChangedEventArgs(location, locState.Debris.Added, locState.Debris.Removed));
// large terrain features changed
- if (locState.LargeTerrainFeatures.IsChanged)
+ if (locState.LargeTerrainFeatures.IsChanged && events.LargeTerrainFeatureListChanged.HasListeners)
events.LargeTerrainFeatureListChanged.Raise(new LargeTerrainFeatureListChangedEventArgs(location, locState.LargeTerrainFeatures.Added, locState.LargeTerrainFeatures.Removed));
// NPCs changed
- if (locState.Npcs.IsChanged)
+ if (locState.Npcs.IsChanged && events.NpcListChanged.HasListeners)
events.NpcListChanged.Raise(new NpcListChangedEventArgs(location, locState.Npcs.Added, locState.Npcs.Removed));
// objects changed
- if (locState.Objects.IsChanged)
+ if (locState.Objects.IsChanged && events.ObjectListChanged.HasListeners)
events.ObjectListChanged.Raise(new ObjectListChangedEventArgs(location, locState.Objects.Added, locState.Objects.Removed));
// chest items changed
if (events.ChestInventoryChanged.HasListeners)
{
- foreach (var pair in locState.ChestItems)
- {
- SnapshotItemListDiff diff = pair.Value;
- events.ChestInventoryChanged.Raise(new ChestInventoryChangedEventArgs(pair.Key, location, added: diff.Added, removed: diff.Removed, quantityChanged: diff.QuantityChanged));
- }
+ foreach ((Chest chest, SnapshotItemListDiff diff) in locState.ChestItems)
+ events.ChestInventoryChanged.Raise(new ChestInventoryChangedEventArgs(chest, location, added: diff.Added, removed: diff.Removed, quantityChanged: diff.QuantityChanged));
}
// terrain features changed
- if (locState.TerrainFeatures.IsChanged)
+ if (locState.TerrainFeatures.IsChanged && events.TerrainFeatureListChanged.HasListeners)
events.TerrainFeatureListChanged.Raise(new TerrainFeatureListChangedEventArgs(location, locState.TerrainFeatures.Added, locState.TerrainFeatures.Removed));
// furniture changed
- if (locState.Furniture.IsChanged)
+ if (locState.Furniture.IsChanged && events.FurnitureListChanged.HasListeners)
events.FurnitureListChanged.Raise(new FurnitureListChangedEventArgs(location, locState.Furniture.Added, locState.Furniture.Removed));
}
}
// raise time changed
- if (raiseWorldEvents && state.Time.IsChanged)
+ if (raiseWorldEvents && state.Time.IsChanged && events.TimeChanged.HasListeners)
events.TimeChanged.Raise(new TimeChangedEventArgs(state.Time.Old, state.Time.New));
// raise player events
@@ -964,29 +975,38 @@ namespace StardewModdingAPI.Framework
if (verbose)
this.Monitor.Log($"Context: set location to {playerState.Location.New}.");
- events.Warped.Raise(new WarpedEventArgs(player, playerState.Location.Old!, playerState.Location.New!));
+ if (events.Warped.HasListeners)
+ events.Warped.Raise(new WarpedEventArgs(player, playerState.Location.Old!, playerState.Location.New!));
}
// raise player leveled up a skill
- foreach ((SkillType skill, var value) in playerState.Skills)
+ bool raiseLevelChanged = events.LevelChanged.HasListeners;
+ if (verbose || raiseLevelChanged)
{
- if (!value.IsChanged)
- continue;
+ foreach ((SkillType skill, var value) in playerState.Skills)
+ {
+ if (!value.IsChanged)
+ continue;
- if (verbose)
- this.Monitor.Log($"Events: player skill '{skill}' changed from {value.Old} to {value.New}.");
+ if (verbose)
+ this.Monitor.Log($"Events: player skill '{skill}' changed from {value.Old} to {value.New}.");
- events.LevelChanged.Raise(new LevelChangedEventArgs(player, skill, value.Old, value.New));
+ if (raiseLevelChanged)
+ events.LevelChanged.Raise(new LevelChangedEventArgs(player, skill, value.Old, value.New));
+ }
}
// raise player inventory changed
if (playerState.Inventory.IsChanged)
{
- SnapshotItemListDiff inventory = playerState.Inventory;
-
if (verbose)
this.Monitor.Log("Events: player inventory changed.");
- events.InventoryChanged.Raise(new InventoryChangedEventArgs(player, added: inventory.Added, removed: inventory.Removed, quantityChanged: inventory.QuantityChanged));
+
+ if (events.InventoryChanged.HasListeners)
+ {
+ SnapshotItemListDiff inventory = playerState.Inventory;
+ events.InventoryChanged.Raise(new InventoryChangedEventArgs(player, added: inventory.Added, removed: inventory.Removed, quantityChanged: inventory.QuantityChanged));
+ }
}
}
}
@@ -998,7 +1018,9 @@ namespace StardewModdingAPI.Framework
if (instance.IsFirstTick && !Context.IsGameLaunched)
{
Context.IsGameLaunched = true;
- events.GameLaunched.Raise(new GameLaunchedEventArgs());
+
+ if (events.GameLaunched.HasListeners)
+ events.GameLaunched.Raise(new GameLaunchedEventArgs());
}
// preloaded
@@ -1124,9 +1146,11 @@ namespace StardewModdingAPI.Framework
}
// raise events
- this.EventManager.LoadStageChanged.Raise(new LoadStageChangedEventArgs(oldStage, newStage));
+ EventManager events = this.EventManager;
+ if (events.LoadStageChanged.HasListeners)
+ events.LoadStageChanged.Raise(new LoadStageChangedEventArgs(oldStage, newStage));
if (newStage == LoadStage.None)
- this.EventManager.ReturnedToTitle.RaiseEmpty();
+ events.ReturnedToTitle.RaiseEmpty();
}
/// <summary>A callback invoked before <see cref="Game1.newDayAfterFade"/> runs.</summary>
@@ -1156,9 +1180,14 @@ namespace StardewModdingAPI.Framework
/// <param name="asset">The asset info being requested.</param>
private IList<AssetOperationGroup> RequestAssetOperations(IAssetInfo asset)
{
- List<AssetOperationGroup> operations = new();
-
- this.EventManager.AssetRequested.Raise(
+ // get event
+ var @event = this.EventManager.AssetRequested;
+ if (!@event.HasListeners)
+ return Array.Empty<AssetOperationGroup>();
+
+ // get operations
+ List<AssetOperationGroup>? operations = null;
+ @event.Raise(
invoke: (mod, invoke) =>
{
AssetRequestedEventArgs args = new(mod, asset, this.GetOnBehalfOfContentPack);
@@ -1167,6 +1196,7 @@ namespace StardewModdingAPI.Framework
if (args.LoadOperations.Any() || args.EditOperations.Any())
{
+ operations ??= new();
operations.Add(
new AssetOperationGroup(mod, args.LoadOperations.ToArray(), args.EditOperations.ToArray())
);
@@ -1174,7 +1204,9 @@ namespace StardewModdingAPI.Framework
}
);
- return operations;
+ return operations != null
+ ? operations
+ : Array.Empty<AssetOperationGroup>();
}
/// <summary>Get the mod metadata for a content pack whose ID matches <paramref name="id"/>, if it's a valid content pack for the given <paramref name="mod"/>.</summary>
@@ -1226,23 +1258,26 @@ namespace StardewModdingAPI.Framework
/// <param name="message">The message to deliver to applicable mods.</param>
private void OnModMessageReceived(ModMessageModel message)
{
- // get mod IDs to notify
- HashSet<string> modIDs = new HashSet<string>(message.ToModIDs ?? this.ModRegistry.GetAll().Select(p => p.Manifest.UniqueID), StringComparer.OrdinalIgnoreCase);
- if (message.FromPlayerID == Game1.player?.UniqueMultiplayerID)
- modIDs.Remove(message.FromModID); // don't send a broadcast back to the sender
-
- // raise events
- ModMessageReceivedEventArgs? args = null;
- this.EventManager.ModMessageReceived.Raise(
- invoke: (mod, invoke) =>
- {
- if (modIDs.Contains(mod.Manifest.UniqueID))
+ if (this.EventManager.ModMessageReceived.HasListeners)
+ {
+ // get mod IDs to notify
+ HashSet<string> modIDs = new(message.ToModIDs ?? this.ModRegistry.GetAll().Select(p => p.Manifest.UniqueID), StringComparer.OrdinalIgnoreCase);
+ if (message.FromPlayerID == Game1.player?.UniqueMultiplayerID)
+ modIDs.Remove(message.FromModID); // don't send a broadcast back to the sender
+
+ // raise events
+ ModMessageReceivedEventArgs? args = null;
+ this.EventManager.ModMessageReceived.Raise(
+ invoke: (mod, invoke) =>
{
- args ??= new(message, this.Toolkit.JsonHelper);
- invoke(args);
+ if (modIDs.Contains(mod.Manifest.UniqueID))
+ {
+ args ??= new(message, this.Toolkit.JsonHelper);
+ invoke(args);
+ }
}
- }
- );
+ );
+ }
}
/// <summary>Constructor a content manager to read game content files.</summary>
diff --git a/src/SMAPI/Framework/SMultiplayer.cs b/src/SMAPI/Framework/SMultiplayer.cs
index 2badcbbf..441a50ef 100644
--- a/src/SMAPI/Framework/SMultiplayer.cs
+++ b/src/SMAPI/Framework/SMultiplayer.cs
@@ -235,7 +235,8 @@ namespace StardewModdingAPI.Framework
}
// raise event
- this.EventManager.PeerContextReceived.Raise(new PeerContextReceivedEventArgs(newPeer));
+ if (this.EventManager.PeerContextReceived.HasListeners)
+ this.EventManager.PeerContextReceived.Raise(new PeerContextReceivedEventArgs(newPeer));
}
break;
@@ -259,7 +260,8 @@ namespace StardewModdingAPI.Framework
resume();
// raise event
- this.EventManager.PeerConnected.Raise(new PeerConnectedEventArgs(this.Peers[message.FarmerID]));
+ if (this.EventManager.PeerConnected.HasListeners)
+ this.EventManager.PeerConnected.Raise(new PeerConnectedEventArgs(this.Peers[message.FarmerID]));
break;
// handle mod message
@@ -370,7 +372,9 @@ namespace StardewModdingAPI.Framework
{
this.Monitor.Log($"Player quit: {playerID}");
this.Peers.Remove(playerID);
- this.EventManager.PeerDisconnected.Raise(new PeerDisconnectedEventArgs(peer));
+
+ if (this.EventManager.PeerDisconnected.HasListeners)
+ this.EventManager.PeerDisconnected.Raise(new PeerDisconnectedEventArgs(peer));
}
}
@@ -481,7 +485,7 @@ namespace StardewModdingAPI.Framework
this.HostPeer = peer;
// raise event
- if (raiseEvent)
+ if (raiseEvent && this.EventManager.PeerContextReceived.HasListeners)
this.EventManager.PeerContextReceived.Raise(new PeerContextReceivedEventArgs(peer));
}