From a1eeece49b937c942e2cc002bd1863295d943fde Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 25 Oct 2017 17:14:58 -0400 Subject: centralise most content-loading logic to fix map tilesheet edge case (#373) --- src/SMAPI/IContentHelper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/IContentHelper.cs') diff --git a/src/SMAPI/IContentHelper.cs b/src/SMAPI/IContentHelper.cs index b78b165b..7900809f 100644 --- a/src/SMAPI/IContentHelper.cs +++ b/src/SMAPI/IContentHelper.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using StardewValley; +using xTile; namespace StardewModdingAPI { @@ -29,7 +30,7 @@ namespace StardewModdingAPI ** Public methods *********/ /// Load content from the game folder or mod folder (if not already cached), and return it. When loading a .png file, this must be called outside the game's draw loop. - /// The expected data type. The main supported types are and dictionaries; other types may be supported by the game's content pipeline. + /// The expected data type. The main supported types are , , and dictionaries; other types may be supported by the game's content pipeline. /// The asset key to fetch (if the is ), or the local path to a content file relative to the mod folder. /// Where to search for a matching content asset. /// The is empty or contains invalid characters. -- cgit From 08c30eeffd8cc62d00db33d91e3a9a6ab1d376a3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 30 Oct 2017 00:02:20 -0400 Subject: let mods invalidate assets matching a predicate (#363) --- docs/release-notes.md | 11 ++++++----- src/SMAPI/Framework/ModHelpers/ContentHelper.cs | 13 +++++++++++-- src/SMAPI/Framework/SContentManager.cs | 26 ++++++++++++++++++------- src/SMAPI/IContentHelper.cs | 5 +++++ 4 files changed, 41 insertions(+), 14 deletions(-) (limited to 'src/SMAPI/IContentHelper.cs') diff --git a/docs/release-notes.md b/docs/release-notes.md index 99b9b965..c192d4ee 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,15 +1,16 @@ # Release notes ## 2.1 (upcoming) * For players: - * Fixed compatibility check crashing for players with Stardew Valley 1.08. - * Fixed the game's test messages being shown in the console and log. - * Fixed TrainerMod's `player_setlevel` command not also setting XP. - * Renamed the default _TrainerMod_ mod to _Console Commands_ to clarify its purpose. * Added a log parser service at [log.smapi.io](https://log.smapi.io). * Added better Steam instructions to the SMAPI installer. + * Renamed the default _TrainerMod_ mod to _Console Commands_ to clarify its purpose. + * Hid the game's test messages from the console log. + * Fixed compatibility check crashing for players with Stardew Valley 1.08. + * Fixed TrainerMod's `player_setlevel` command not also setting XP. * For modders: - * Added support for public code in reflection API, to simplify mod integrations. + * The reflection API now works with public code to simplify mod integrations. + * The content API now lets you invalidated multiple assets at once. * Improved input events: * Added `e.IsActionButton` and `e.IsUseToolButton`. * Added `ToSButton()` extension for the game's `Game1.options` button type. diff --git a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs index ae812e71..711897eb 100644 --- a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs @@ -163,9 +163,9 @@ namespace StardewModdingAPI.Framework.ModHelpers /// Returns whether the given asset key was cached. public bool InvalidateCache(string key) { - this.Monitor.Log($"Requested cache invalidation for '{key}'.", LogLevel.Trace); string actualKey = this.GetActualAssetKey(key, ContentSource.GameContent); - return this.ContentManager.InvalidateCache((otherKey, type) => otherKey.Equals(actualKey, StringComparison.InvariantCultureIgnoreCase)); + this.Monitor.Log($"Requested cache invalidation for '{actualKey}'.", LogLevel.Trace); + return this.ContentManager.InvalidateCache(asset => asset.AssetNameEquals(actualKey)); } /// Remove all assets of the given type from the cache so they're reloaded on the next request. This can be a very expensive operation and should only be used in very specific cases. This will reload core game assets if needed, but references to the former assets will still show the previous content. @@ -177,6 +177,15 @@ namespace StardewModdingAPI.Framework.ModHelpers return this.ContentManager.InvalidateCache((key, type) => typeof(T).IsAssignableFrom(type)); } + /// Remove matching assets from the content cache so they're reloaded on the next request. This will reload core game assets if needed, but references to the former asset will still show the previous content. + /// A predicate matching the assets to invalidate. + /// Returns whether any cache entries were invalidated. + public bool InvalidateCache(Func predicate) + { + this.Monitor.Log("Requested cache invalidation for all assets matching a predicate.", LogLevel.Trace); + return this.ContentManager.InvalidateCache(predicate); + } + /********* ** Private methods *********/ diff --git a/src/SMAPI/Framework/SContentManager.cs b/src/SMAPI/Framework/SContentManager.cs index 54ebba83..a755a6df 100644 --- a/src/SMAPI/Framework/SContentManager.cs +++ b/src/SMAPI/Framework/SContentManager.cs @@ -287,18 +287,30 @@ namespace StardewModdingAPI.Framework throw new InvalidOperationException("SMAPI could not access the interceptor methods."); // should never happen // invalidate matching keys - return this.InvalidateCache((assetName, assetType) => + return this.InvalidateCache(asset => { - IAssetInfo info = new AssetInfo(this.GetLocale(), assetName, assetType, this.NormaliseAssetName); - // check loaders - MethodInfo canLoadGeneric = canLoad.MakeGenericMethod(assetType); - if (loaders.Any(loader => (bool)canLoadGeneric.Invoke(loader, new object[] { info }))) + MethodInfo canLoadGeneric = canLoad.MakeGenericMethod(asset.DataType); + if (loaders.Any(loader => (bool)canLoadGeneric.Invoke(loader, new object[] { asset }))) return true; // check editors - MethodInfo canEditGeneric = canEdit.MakeGenericMethod(assetType); - return editors.Any(editor => (bool)canEditGeneric.Invoke(editor, new object[] { info })); + MethodInfo canEditGeneric = canEdit.MakeGenericMethod(asset.DataType); + return editors.Any(editor => (bool)canEditGeneric.Invoke(editor, new object[] { asset })); + }); + } + + /// Purge matched assets from the cache. + /// Matches the asset keys to invalidate. + /// Whether to dispose invalidated assets. This should only be true when they're being invalidated as part of a dispose, to avoid crashing the game. + /// Returns whether any cache entries were invalidated. + public bool InvalidateCache(Func predicate, bool dispose = false) + { + string locale = this.GetLocale(); + return this.InvalidateCache((assetName, type) => + { + IAssetInfo info = new AssetInfo(locale, assetName, type, this.NormaliseAssetName); + return predicate(info); }); } diff --git a/src/SMAPI/IContentHelper.cs b/src/SMAPI/IContentHelper.cs index 7900809f..e3362502 100644 --- a/src/SMAPI/IContentHelper.cs +++ b/src/SMAPI/IContentHelper.cs @@ -53,5 +53,10 @@ namespace StardewModdingAPI /// The asset type to remove from the cache. /// Returns whether any assets were invalidated. bool InvalidateCache(); + + /// Remove matching assets from the content cache so they're reloaded on the next request. This will reload core game assets if needed, but references to the former asset will still show the previous content. + /// A predicate matching the assets to invalidate. + /// Returns whether any cache entries were invalidated. + bool InvalidateCache(Func predicate); } } -- cgit