diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-07-01 19:39:04 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-07-01 19:39:04 -0400 |
commit | 3b6adf3c2676fa8f73997f9c1f8ec5f727f73690 (patch) | |
tree | e4314a49d68e8f040ade273c58c2cf730eb7dec7 | |
parent | 4568f2259ba6a0808658229122daa6ff6335a4fe (diff) | |
download | SMAPI-3b6adf3c2676fa8f73997f9c1f8ec5f727f73690.tar.gz SMAPI-3b6adf3c2676fa8f73997f9c1f8ec5f727f73690.tar.bz2 SMAPI-3b6adf3c2676fa8f73997f9c1f8ec5f727f73690.zip |
reset asset cache when a new interceptor is added (#255)
This lets new interceptors edit assets loaded before they were added, particularly assets loaded before mods are initialised.
-rw-r--r-- | src/StardewModdingAPI/Framework/ContentHelper.cs | 6 | ||||
-rw-r--r-- | src/StardewModdingAPI/Framework/SContentManager.cs | 59 | ||||
-rw-r--r-- | src/StardewModdingAPI/Program.cs | 16 |
3 files changed, 79 insertions, 2 deletions
diff --git a/src/StardewModdingAPI/Framework/ContentHelper.cs b/src/StardewModdingAPI/Framework/ContentHelper.cs index f4b541e9..b7773d6a 100644 --- a/src/StardewModdingAPI/Framework/ContentHelper.cs +++ b/src/StardewModdingAPI/Framework/ContentHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; @@ -36,8 +37,11 @@ namespace StardewModdingAPI.Framework /********* ** Accessors *********/ + /// <summary>The observable implementation of <see cref="AssetEditors"/>.</summary> + internal ObservableCollection<IAssetEditor> ObservableAssetEditors { get; } = new ObservableCollection<IAssetEditor>(); + /// <summary>Editors which change content assets after they're loaded.</summary> - internal IList<IAssetEditor> AssetEditors { get; } = new List<IAssetEditor>(); + internal IList<IAssetEditor> AssetEditors => this.ObservableAssetEditors; /********* diff --git a/src/StardewModdingAPI/Framework/SContentManager.cs b/src/StardewModdingAPI/Framework/SContentManager.cs index d269cafa..24585963 100644 --- a/src/StardewModdingAPI/Framework/SContentManager.cs +++ b/src/StardewModdingAPI/Framework/SContentManager.cs @@ -5,10 +5,14 @@ using System.IO; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.AssemblyRewriters; using StardewModdingAPI.Framework.Content; using StardewModdingAPI.Framework.Reflection; using StardewValley; +using StardewValley.BellsAndWhistles; +using StardewValley.Objects; +using StardewValley.Projectiles; namespace StardewModdingAPI.Framework { @@ -59,6 +63,10 @@ namespace StardewModdingAPI.Framework public SContentManager(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, string languageCodeOverride, IMonitor monitor) : base(serviceProvider, rootDirectory, currentCulture, languageCodeOverride) { + // validate + if (monitor == null) + throw new ArgumentNullException(nameof(monitor)); + // initialise IReflectionHelper reflection = new ReflectionHelper(); this.Monitor = monitor; @@ -130,6 +138,7 @@ namespace StardewModdingAPI.Framework public void Inject<T>(string assetName, T value) { assetName = this.NormaliseAssetName(assetName); + this.Cache[assetName] = value; } @@ -139,6 +148,56 @@ namespace StardewModdingAPI.Framework return this.GetKeyLocale.Invoke<string>(); } + /// <summary>Reset the asset cache and reload the game's static assets.</summary> + /// <remarks>This implementation is derived from <see cref="Game1.LoadContent"/>.</remarks> + public void Reset() + { + this.Monitor.Log("Resetting asset cache...", LogLevel.Trace); + this.Cache.Clear(); + + // from Game1.LoadContent + Game1.daybg = this.Load<Texture2D>("LooseSprites\\daybg"); + Game1.nightbg = this.Load<Texture2D>("LooseSprites\\nightbg"); + Game1.menuTexture = this.Load<Texture2D>("Maps\\MenuTiles"); + Game1.lantern = this.Load<Texture2D>("LooseSprites\\Lighting\\lantern"); + Game1.windowLight = this.Load<Texture2D>("LooseSprites\\Lighting\\windowLight"); + Game1.sconceLight = this.Load<Texture2D>("LooseSprites\\Lighting\\sconceLight"); + Game1.cauldronLight = this.Load<Texture2D>("LooseSprites\\Lighting\\greenLight"); + Game1.indoorWindowLight = this.Load<Texture2D>("LooseSprites\\Lighting\\indoorWindowLight"); + Game1.shadowTexture = this.Load<Texture2D>("LooseSprites\\shadow"); + Game1.mouseCursors = this.Load<Texture2D>("LooseSprites\\Cursors"); + Game1.controllerMaps = this.Load<Texture2D>("LooseSprites\\ControllerMaps"); + Game1.animations = this.Load<Texture2D>("TileSheets\\animations"); + Game1.achievements = this.Load<Dictionary<int, string>>("Data\\Achievements"); + Game1.NPCGiftTastes = this.Load<Dictionary<string, string>>("Data\\NPCGiftTastes"); + Game1.dialogueFont = this.Load<SpriteFont>("Fonts\\SpriteFont1"); + Game1.smallFont = this.Load<SpriteFont>("Fonts\\SmallFont"); + Game1.tinyFont = this.Load<SpriteFont>("Fonts\\tinyFont"); + Game1.tinyFontBorder = this.Load<SpriteFont>("Fonts\\tinyFontBorder"); + Game1.objectSpriteSheet = this.Load<Texture2D>("Maps\\springobjects"); + Game1.cropSpriteSheet = this.Load<Texture2D>("TileSheets\\crops"); + Game1.emoteSpriteSheet = this.Load<Texture2D>("TileSheets\\emotes"); + Game1.debrisSpriteSheet = this.Load<Texture2D>("TileSheets\\debris"); + Game1.bigCraftableSpriteSheet = this.Load<Texture2D>("TileSheets\\Craftables"); + Game1.rainTexture = this.Load<Texture2D>("TileSheets\\rain"); + Game1.buffsIcons = this.Load<Texture2D>("TileSheets\\BuffsIcons"); + Game1.objectInformation = this.Load<Dictionary<int, string>>("Data\\ObjectInformation"); + Game1.bigCraftablesInformation = this.Load<Dictionary<int, string>>("Data\\BigCraftablesInformation"); + FarmerRenderer.hairStylesTexture = this.Load<Texture2D>("Characters\\Farmer\\hairstyles"); + FarmerRenderer.shirtsTexture = this.Load<Texture2D>("Characters\\Farmer\\shirts"); + FarmerRenderer.hatsTexture = this.Load<Texture2D>("Characters\\Farmer\\hats"); + FarmerRenderer.accessoriesTexture = this.Load<Texture2D>("Characters\\Farmer\\accessories"); + Furniture.furnitureTexture = this.Load<Texture2D>("TileSheets\\furniture"); + SpriteText.spriteTexture = this.Load<Texture2D>("LooseSprites\\font_bold"); + SpriteText.coloredTexture = this.Load<Texture2D>("LooseSprites\\font_colored"); + Tool.weaponsTexture = this.Load<Texture2D>("TileSheets\\weapons"); + Projectile.projectileSheet = this.Load<Texture2D>("TileSheets\\Projectiles"); + + // from Farmer constructor + if (Game1.player != null) + Game1.player.FarmerRenderer = new FarmerRenderer(this.Load<Texture2D>($"Characters\\Farmer\\farmer_" + (Game1.player.isMale ? "" : "girl_") + "base")); + } + /********* ** Private methods *********/ diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 98de4608..53efe1e3 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -708,7 +708,7 @@ namespace StardewModdingAPI { // add interceptors if (metadata.Mod.Helper.Content is ContentHelper helper) - this.ContentManager.Editors[metadata] = helper.AssetEditors; + this.ContentManager.Editors[metadata] = helper.ObservableAssetEditors; // call entry method try @@ -727,6 +727,20 @@ namespace StardewModdingAPI } } + // reset cache when needed + // only register listeners after Entry to avoid repeatedly reloading assets during load + foreach (IModMetadata metadata in loadedMods) + { + if (metadata.Mod.Helper.Content is ContentHelper helper) + { + helper.ObservableAssetEditors.CollectionChanged += (sender, e) => + { + if (e.NewItems.Count > 0) + this.ContentManager.Reset(); + }; + } + } + this.ContentManager.Reset(); } /// <summary>Reload translations for all mods.</summary> |