diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-03-24 22:55:55 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-03-24 22:55:55 -0400 |
commit | 2b0ce2bb4d6690b7d00da0a243855db9bffffbf0 (patch) | |
tree | 43c944e0af70ec8bcf628fd6f13f04f01826d869 /src/SMAPI/Framework | |
parent | 6a43e6dfad0f4d3a17ea20ef391fe760135f1c24 (diff) | |
download | SMAPI-2b0ce2bb4d6690b7d00da0a243855db9bffffbf0.tar.gz SMAPI-2b0ce2bb4d6690b7d00da0a243855db9bffffbf0.tar.bz2 SMAPI-2b0ce2bb4d6690b7d00da0a243855db9bffffbf0.zip |
add AssetInvalidated content event (#766)
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r-- | src/SMAPI/Framework/ContentCoordinator.cs | 30 | ||||
-rw-r--r-- | src/SMAPI/Framework/Events/EventManager.cs | 4 | ||||
-rw-r--r-- | src/SMAPI/Framework/Events/ModContentEvents.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Framework/SCore.cs | 9 |
4 files changed, 39 insertions, 11 deletions
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index 22ae0a18..4f696928 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -49,6 +49,12 @@ namespace StardewModdingAPI.Framework /// <summary>A callback to invoke the first time *any* game content manager loads an asset.</summary> private readonly Action OnLoadingFirstAsset; + /// <summary>A callback to invoke when any asset names have been invalidated from the cache.</summary> + private readonly Action<IEnumerable<IAssetName>> OnAssetsInvalidated; + + /// <summary>Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</summary> + private readonly Func<IAssetInfo, IList<AssetOperationGroup>> RequestAssetOperations; + /// <summary>The loaded content managers (including the <see cref="MainContentManager"/>).</summary> private readonly List<IContentManager> ContentManagers = new(); @@ -71,9 +77,6 @@ namespace StardewModdingAPI.Framework /// <summary>The language enum values indexed by locale code.</summary> private Lazy<Dictionary<string, LocalizedContentManager.LanguageCode>> LocaleCodes; - /// <summary>Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</summary> - private readonly Func<IAssetInfo, IList<AssetOperationGroup>> RequestAssetOperations; - /// <summary>The cached asset load/edit operations to apply, indexed by asset name.</summary> private readonly TickCacheDictionary<IAssetName, AssetOperationGroup[]> AssetOperationsByKey = new(); @@ -109,14 +112,16 @@ namespace StardewModdingAPI.Framework /// <param name="jsonHelper">Encapsulates SMAPI's JSON file parsing.</param> /// <param name="onLoadingFirstAsset">A callback to invoke the first time *any* game content manager loads an asset.</param> /// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param> + /// <param name="onAssetsInvalidated">A callback to invoke when any asset names have been invalidated from the cache.</param> /// <param name="requestAssetOperations">Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</param> - public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, bool aggressiveMemoryOptimizations, Func<IAssetInfo, IList<AssetOperationGroup>> requestAssetOperations) + public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, bool aggressiveMemoryOptimizations, Action<IEnumerable<IAssetName>> onAssetsInvalidated, Func<IAssetInfo, IList<AssetOperationGroup>> requestAssetOperations) { this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations; this.Monitor = monitor ?? throw new ArgumentNullException(nameof(monitor)); this.Reflection = reflection; this.JsonHelper = jsonHelper; this.OnLoadingFirstAsset = onLoadingFirstAsset; + this.OnAssetsInvalidated = onAssetsInvalidated; this.RequestAssetOperations = requestAssetOperations; this.FullRootDirectory = Path.Combine(Constants.GamePath, rootDirectory); this.ContentManagers.Add( @@ -257,7 +262,7 @@ namespace StardewModdingAPI.Framework // Note that we *must* propagate changes here, otherwise when mods invalidate the cache later to reapply // their changes, the assets won't be found in the cache so no changes will be propagated. if (LocalizedContentManager.CurrentLanguageCode != LocalizedContentManager.LanguageCode.en) - this.InvalidateCache((contentManager, key, type) => contentManager is GameContentManager); + this.InvalidateCache((contentManager, _, _) => contentManager is GameContentManager); } /// <summary>Parse a raw asset name.</summary> @@ -347,7 +352,7 @@ namespace StardewModdingAPI.Framework public IEnumerable<IAssetName> InvalidateCache(Func<IAssetInfo, bool> predicate, bool dispose = false) { string locale = this.GetLocale(); - return this.InvalidateCache((contentManager, rawName, type) => + return this.InvalidateCache((_, rawName, type) => { IAssetName assetName = this.ParseAssetName(rawName); IAssetInfo info = new AssetInfo(locale, assetName, type, this.MainContentManager.AssertAndNormalizeAssetName); @@ -393,13 +398,16 @@ namespace StardewModdingAPI.Framework } }); - // clear cached editor checks - foreach (IAssetName name in invalidatedAssets.Keys) - this.AssetOperationsByKey.Remove(name); - - // reload core game assets + // handle invalidation if (invalidatedAssets.Any()) { + // clear cached editor checks + foreach (IAssetName name in invalidatedAssets.Keys) + this.AssetOperationsByKey.Remove(name); + + // raise event + this.OnAssetsInvalidated(invalidatedAssets.Keys); + // propagate changes to the game this.CoreAssets.Propagate( assets: invalidatedAssets.ToDictionary(p => p.Key, p => p.Value), diff --git a/src/SMAPI/Framework/Events/EventManager.cs b/src/SMAPI/Framework/Events/EventManager.cs index 8142f00e..96582380 100644 --- a/src/SMAPI/Framework/Events/EventManager.cs +++ b/src/SMAPI/Framework/Events/EventManager.cs @@ -16,6 +16,9 @@ namespace StardewModdingAPI.Framework.Events /// <inheritdoc cref="IContentEvents.AssetRequested" /> public readonly ManagedEvent<AssetRequestedEventArgs> AssetRequested; + /// <inheritdoc cref="IContentEvents.AssetsInvalidated" /> + public readonly ManagedEvent<AssetsInvalidatedEventArgs> AssetsInvalidated; + /**** ** Display @@ -198,6 +201,7 @@ namespace StardewModdingAPI.Framework.Events // init events this.AssetRequested = ManageEventOf<AssetRequestedEventArgs>(nameof(IModEvents.Content), nameof(IContentEvents.AssetRequested)); + this.AssetsInvalidated = ManageEventOf<AssetsInvalidatedEventArgs>(nameof(IModEvents.Content), nameof(IContentEvents.AssetsInvalidated)); this.MenuChanged = ManageEventOf<MenuChangedEventArgs>(nameof(IModEvents.Display), nameof(IDisplayEvents.MenuChanged)); this.Rendering = ManageEventOf<RenderingEventArgs>(nameof(IModEvents.Display), nameof(IDisplayEvents.Rendering), isPerformanceCritical: true); diff --git a/src/SMAPI/Framework/Events/ModContentEvents.cs b/src/SMAPI/Framework/Events/ModContentEvents.cs index b4d4279c..4d0cfb97 100644 --- a/src/SMAPI/Framework/Events/ModContentEvents.cs +++ b/src/SMAPI/Framework/Events/ModContentEvents.cs @@ -16,6 +16,13 @@ namespace StardewModdingAPI.Framework.Events remove => this.EventManager.AssetRequested.Remove(value); } + /// <inheritdoc /> + public event EventHandler<AssetsInvalidatedEventArgs> AssetsInvalidated + { + add => this.EventManager.AssetsInvalidated.Add(value, this.Mod); + remove => this.EventManager.AssetsInvalidated.Remove(value); + } + /********* ** Public methods diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index f9f84206..e9bc9a2b 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -1106,6 +1106,14 @@ namespace StardewModdingAPI.Framework this.EventManager.DayEnding.RaiseEmpty(); } + /// <summary>A callback invoked after assets have been invalidated from the content cache.</summary> + /// <param name="assetNames">The invalidated asset names.</param> + private void OnAssetsInvalidated(IEnumerable<IAssetName> assetNames) + { + if (this.EventManager.AssetsInvalidated.HasListeners()) + this.EventManager.AssetsInvalidated.Raise(new AssetsInvalidatedEventArgs(assetNames)); + } + /// <summary>Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</summary> /// <param name="asset">The asset info being requested.</param> private IList<AssetOperationGroup> RequestAssetOperations(IAssetInfo asset) @@ -1175,6 +1183,7 @@ namespace StardewModdingAPI.Framework reflection: this.Reflection, jsonHelper: this.Toolkit.JsonHelper, onLoadingFirstAsset: this.InitializeBeforeFirstAssetLoaded, + onAssetsInvalidated: this.OnAssetsInvalidated, aggressiveMemoryOptimizations: this.Settings.AggressiveMemoryOptimizations, requestAssetOperations: this.RequestAssetOperations ); |