summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-03-24 22:55:55 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-03-24 22:55:55 -0400
commit2b0ce2bb4d6690b7d00da0a243855db9bffffbf0 (patch)
tree43c944e0af70ec8bcf628fd6f13f04f01826d869 /src/SMAPI/Framework
parent6a43e6dfad0f4d3a17ea20ef391fe760135f1c24 (diff)
downloadSMAPI-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.cs30
-rw-r--r--src/SMAPI/Framework/Events/EventManager.cs4
-rw-r--r--src/SMAPI/Framework/Events/ModContentEvents.cs7
-rw-r--r--src/SMAPI/Framework/SCore.cs9
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
);