summaryrefslogtreecommitdiff
path: root/src/SMAPI/Events
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-05-11 21:36:45 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-05-11 21:36:45 -0400
commitbbe5983acdd082d2185a69e2ad37d659a298223d (patch)
treead6fe68ebd0da25a832e9fad3832741dee50954f /src/SMAPI/Events
parent42a797a01240893e9a8e645253a269087b2d178d (diff)
downloadSMAPI-bbe5983acdd082d2185a69e2ad37d659a298223d.tar.gz
SMAPI-bbe5983acdd082d2185a69e2ad37d659a298223d.tar.bz2
SMAPI-bbe5983acdd082d2185a69e2ad37d659a298223d.zip
rewrite asset operations to reduce allocations
• When raising AssetRequested, SMAPI now creates a single event args model and reuses it for each handler. • There's now a single AssetOperationGroup per asset, which tracks the loaders/editors registered by every mod for that asset. • The operation group's loader/editor lists are now used directly instead of querying them.
Diffstat (limited to 'src/SMAPI/Events')
-rw-r--r--src/SMAPI/Events/AssetRequestedEventArgs.cs43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs
index d0aef1db..d6561028 100644
--- a/src/SMAPI/Events/AssetRequestedEventArgs.cs
+++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs
@@ -14,7 +14,7 @@ namespace StardewModdingAPI.Events
** Fields
*********/
/// <summary>The mod handling the event.</summary>
- private readonly IModMetadata Mod;
+ private IModMetadata? Mod;
/// <summary>Get the mod metadata for a content pack, if it's a valid content pack for the mod.</summary>
private readonly Func<IModMetadata, string?, string, IModMetadata?> GetOnBehalfOf;
@@ -37,26 +37,31 @@ namespace StardewModdingAPI.Events
public Type DataType => this.AssetInfo.DataType;
/// <summary>The load operations requested by the event handler.</summary>
- internal IList<AssetLoadOperation> LoadOperations { get; } = new List<AssetLoadOperation>();
+ internal List<AssetLoadOperation> LoadOperations { get; } = new();
/// <summary>The edit operations requested by the event handler.</summary>
- internal IList<AssetEditOperation> EditOperations { get; } = new List<AssetEditOperation>();
+ internal List<AssetEditOperation> EditOperations { get; } = new();
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
- /// <param name="mod">The mod handling the event.</param>
/// <param name="assetInfo">The asset info being requested.</param>
/// <param name="getOnBehalfOf">Get the mod metadata for a content pack, if it's a valid content pack for the mod.</param>
- internal AssetRequestedEventArgs(IModMetadata mod, IAssetInfo assetInfo, Func<IModMetadata, string?, string, IModMetadata?> getOnBehalfOf)
+ internal AssetRequestedEventArgs(IAssetInfo assetInfo, Func<IModMetadata, string?, string, IModMetadata?> getOnBehalfOf)
{
- this.Mod = mod;
this.AssetInfo = assetInfo;
this.GetOnBehalfOf = getOnBehalfOf;
}
+ /// <summary>Set the mod handling the event.</summary>
+ /// <param name="mod">The mod handling the event.</param>
+ internal void SetMod(IModMetadata mod)
+ {
+ this.Mod = mod;
+ }
+
/// <summary>Provide the initial instance for the asset, instead of trying to load it from the game's <c>Content</c> folder.</summary>
/// <param name="load">Get the initial instance of an asset.</param>
/// <param name="priority">If there are multiple loads that apply to the same asset, the priority with which this one should be applied.</param>
@@ -70,10 +75,11 @@ namespace StardewModdingAPI.Events
/// </remarks>
public void LoadFrom(Func<object> load, AssetLoadPriority priority, string? onBehalfOf = null)
{
+ IModMetadata mod = this.GetMod();
this.LoadOperations.Add(
new AssetLoadOperation(
- Mod: this.Mod,
- OnBehalfOf: this.GetOnBehalfOf(this.Mod, onBehalfOf, "load assets"),
+ Mod: mod,
+ OnBehalfOf: this.GetOnBehalfOf(mod, onBehalfOf, "load assets"),
Priority: priority,
GetData: _ => load()
)
@@ -94,12 +100,13 @@ namespace StardewModdingAPI.Events
public void LoadFromModFile<TAsset>(string relativePath, AssetLoadPriority priority)
where TAsset : notnull
{
+ IModMetadata mod = this.GetMod();
this.LoadOperations.Add(
new AssetLoadOperation(
- Mod: this.Mod,
+ Mod: mod,
OnBehalfOf: null,
Priority: priority,
- GetData: _ => this.Mod.Mod!.Helper.ModContent.Load<TAsset>(relativePath)
+ GetData: _ => mod.Mod!.Helper.ModContent.Load<TAsset>(relativePath)
)
);
}
@@ -117,14 +124,26 @@ namespace StardewModdingAPI.Events
/// </remarks>
public void Edit(Action<IAssetData> apply, AssetEditPriority priority = AssetEditPriority.Default, string? onBehalfOf = null)
{
+ IModMetadata mod = this.GetMod();
this.EditOperations.Add(
new AssetEditOperation(
- Mod: this.Mod,
+ Mod: mod,
Priority: priority,
- OnBehalfOf: this.GetOnBehalfOf(this.Mod, onBehalfOf, "edit assets"),
+ OnBehalfOf: this.GetOnBehalfOf(mod, onBehalfOf, "edit assets"),
ApplyEdit: apply
)
);
}
+
+
+ /*********
+ ** Private methods
+ *********/
+ /// <summary>Get the mod handling the event.</summary>
+ /// <exception cref="InvalidOperationException">This instance hasn't been initialized with the mod metadata yet.</exception>
+ private IModMetadata GetMod()
+ {
+ return this.Mod ?? throw new InvalidOperationException($"This {nameof(AssetRequestedEventArgs)} instance hasn't been initialized yet.");
+ }
}
}