diff --git a/src/SMAPI/Framework/Content/AssetEditOperation.cs b/src/SMAPI/Framework/Content/AssetEditOperation.cs
new file mode 100644
index 00000000..fa189d44
--- /dev/null
+++ b/src/SMAPI/Framework/Content/AssetEditOperation.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace StardewModdingAPI.Framework.Content
+{
+ /// An edit to apply to an asset when it's requested from the content pipeline.
+ internal class AssetEditOperation
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// The mod applying the edit.
+ public IModMetadata Mod { get; }
+
+ /// Apply the edit to an asset.
+ public Action ApplyEdit { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// Construct an instance.
+ /// The mod applying the edit.
+ /// Apply the edit to an asset.
+ public AssetEditOperation(IModMetadata mod, Action applyEdit)
+ {
+ this.Mod = mod;
+ this.ApplyEdit = applyEdit;
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/Content/AssetLoadOperation.cs b/src/SMAPI/Framework/Content/AssetLoadOperation.cs
new file mode 100644
index 00000000..d773cadd
--- /dev/null
+++ b/src/SMAPI/Framework/Content/AssetLoadOperation.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace StardewModdingAPI.Framework.Content
+{
+ /// An operation which provides the initial instance of an asset when it's requested from the content pipeline.
+ internal class AssetLoadOperation
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// The mod applying the edit.
+ public IModMetadata Mod { get; }
+
+ /// Load the initial value for an asset.
+ public Func GetData { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// Construct an instance.
+ /// The mod applying the edit.
+ /// Load the initial value for an asset.
+ public AssetLoadOperation(IModMetadata mod, Func getData)
+ {
+ this.Mod = mod;
+ this.GetData = getData;
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index 9b8125ad..7ed1fcda 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -24,7 +24,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
** Fields
*********/
/// The assets currently being intercepted by instances. This is used to prevent infinite loops when a loader loads a new asset.
- private readonly ContextHash AssetsBeingLoaded = new ContextHash();
+ private readonly ContextHash AssetsBeingLoaded = new();
/// Interceptors which provide the initial versions of matching assets.
private IList> Loaders => this.Coordinator.Loaders;
@@ -79,12 +79,10 @@ namespace StardewModdingAPI.Framework.ContentManagers
// custom asset from a loader
string locale = this.GetLocale();
IAssetInfo info = new AssetInfo(locale, assetName, typeof(object), this.AssertAndNormalizeAssetName);
- ModLinked[] loaders = this.GetLoaders