diff --git a/docs/release-notes.md b/docs/release-notes.md index a0d8826b..eb30ef7c 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,8 +3,9 @@ # Release notes ## Upcoming release * For players: + * Improved performance for many mods still using the older content API. * Disabled case-insensitive file paths (introduced in 3.14.0) by default. - _You can enable them by editing `smapi-internal/config.json` if needed. They'll be re-enabled in a later version after they're reworked to reduce performance impact._ + _You can enable them by editing `smapi-internal/config.json` if needed. They'll be re-enabled in an upcoming version after they're reworked a bit._ * Removed experimental 'aggressive memory optimizations' option. _This was disabled by default and is no longer needed in most cases. Memory usage will be better reduced by reworked asset propagation in the upcoming SMAPI 4.0.0._ * Fixed 'content file was not found' error when the game tries to load unlocalized text from a localizable mod data asset. diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index ef442fbe..8ce0dba1 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -81,6 +81,14 @@ namespace StardewModdingAPI.Framework /// The cached asset load/edit operations to apply, indexed by asset name. private readonly TickCacheDictionary AssetOperationsByKey = new(); + /// A cache of asset operation groups created for legacy implementations. + [Obsolete] + private readonly Dictionary LegacyLoaderCache = new(ReferenceEqualityComparer.Instance); + + /// A cache of asset operation groups created for legacy implementations. + [Obsolete] + private readonly Dictionary LegacyEditorCache = new(ReferenceEqualityComparer.Instance); + /********* ** Accessors @@ -598,21 +606,26 @@ namespace StardewModdingAPI.Framework } // add operation - yield return new AssetOperationGroup( - mod: loader.Mod, - loadOperations: new[] - { - new AssetLoadOperation( - mod: loader.Mod, - priority: AssetLoadPriority.Exclusive, - onBehalfOf: null, - getData: assetInfo => loader.Data.Load( - this.GetLegacyAssetInfo(assetInfo) + if (!this.LegacyLoaderCache.TryGetValue(loader.Data, out AssetOperationGroup? group)) + { + this.LegacyLoaderCache[loader.Data] = group = new AssetOperationGroup( + mod: loader.Mod, + loadOperations: new[] + { + new AssetLoadOperation( + mod: loader.Mod, + priority: AssetLoadPriority.Exclusive, + onBehalfOf: null, + getData: assetInfo => loader.Data.Load( + this.GetLegacyAssetInfo(assetInfo) + ) ) - ) - }, - editOperations: Array.Empty() - ); + }, + editOperations: Array.Empty() + ); + } + + yield return group; } // legacy edit operations @@ -652,21 +665,26 @@ namespace StardewModdingAPI.Framework }; // add operation - yield return new AssetOperationGroup( - mod: editor.Mod, - loadOperations: Array.Empty(), - editOperations: new[] - { - new AssetEditOperation( - mod: editor.Mod, - priority: priority, - onBehalfOf: null, - applyEdit: assetData => editor.Data.Edit( - this.GetLegacyAssetData(assetData) + if (!this.LegacyEditorCache.TryGetValue(editor.Data, out AssetOperationGroup? group)) + { + this.LegacyEditorCache[editor.Data] = group = new AssetOperationGroup( + mod: editor.Mod, + loadOperations: Array.Empty(), + editOperations: new[] + { + new AssetEditOperation( + mod: editor.Mod, + priority: priority, + onBehalfOf: null, + applyEdit: assetData => editor.Data.Edit( + this.GetLegacyAssetData(assetData) + ) ) - ) - } - ); + } + ); + } + + yield return group; } #pragma warning restore CS0612, CS0618 }