summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs10
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs12
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs4
-rw-r--r--src/SMAPI/Framework/Events/EventManager.cs6
-rw-r--r--src/SMAPI/Framework/Events/ModContentEvents.cs7
-rw-r--r--src/SMAPI/Framework/SCore.cs11
6 files changed, 43 insertions, 7 deletions
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index 4f696928..4dbbae15 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -49,6 +49,9 @@ 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 an asset is fully loaded.</summary>
+ private readonly Action<BaseContentManager, IAssetName> OnAssetLoaded;
+
/// <summary>A callback to invoke when any asset names have been invalidated from the cache.</summary>
private readonly Action<IEnumerable<IAssetName>> OnAssetsInvalidated;
@@ -111,16 +114,18 @@ namespace StardewModdingAPI.Framework
/// <param name="reflection">Simplifies access to private code.</param>
/// <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="onAssetLoaded">A callback to invoke when an asset is fully loaded.</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, Action<IEnumerable<IAssetName>> onAssetsInvalidated, Func<IAssetInfo, IList<AssetOperationGroup>> requestAssetOperations)
+ public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, 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.OnAssetLoaded = onAssetLoaded;
this.OnAssetsInvalidated = onAssetsInvalidated;
this.RequestAssetOperations = requestAssetOperations;
this.FullRootDirectory = Path.Combine(Constants.GamePath, rootDirectory);
@@ -135,6 +140,7 @@ namespace StardewModdingAPI.Framework
reflection: reflection,
onDisposing: this.OnDisposing,
onLoadingFirstAsset: onLoadingFirstAsset,
+ onAssetLoaded: onAssetLoaded,
aggressiveMemoryOptimizations: aggressiveMemoryOptimizations
)
);
@@ -148,6 +154,7 @@ namespace StardewModdingAPI.Framework
reflection: reflection,
onDisposing: this.OnDisposing,
onLoadingFirstAsset: onLoadingFirstAsset,
+ onAssetLoaded: onAssetLoaded,
aggressiveMemoryOptimizations: aggressiveMemoryOptimizations
);
this.ContentManagers.Add(contentManagerForAssetPropagation);
@@ -172,6 +179,7 @@ namespace StardewModdingAPI.Framework
reflection: this.Reflection,
onDisposing: this.OnDisposing,
onLoadingFirstAsset: this.OnLoadingFirstAsset,
+ onAssetLoaded: this.OnAssetLoaded,
aggressiveMemoryOptimizations: this.AggressiveMemoryOptimizations
);
this.ContentManagers.Add(manager);
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index 642e526c..12ed5506 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -35,6 +35,9 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <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 an asset is fully loaded.</summary>
+ private readonly Action<BaseContentManager, IAssetName> OnAssetLoaded;
+
/*********
** Public methods
@@ -49,11 +52,13 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="reflection">Simplifies access to private code.</param>
/// <param name="onDisposing">A callback to invoke when the content manager is being disposed.</param>
/// <param name="onLoadingFirstAsset">A callback to invoke the first time *any* game content manager loads an asset.</param>
+ /// <param name="onAssetLoaded">A callback to invoke when an asset is fully loaded.</param>
/// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param>
- public GameContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset, bool aggressiveMemoryOptimizations)
+ public GameContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, bool aggressiveMemoryOptimizations)
: base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: false, aggressiveMemoryOptimizations: aggressiveMemoryOptimizations)
{
this.OnLoadingFirstAsset = onLoadingFirstAsset;
+ this.OnAssetLoaded = onAssetLoaded;
}
/// <inheritdoc />
@@ -129,8 +134,11 @@ namespace StardewModdingAPI.Framework.ContentManagers
});
}
- // update cache & return data
+ // update cache
this.TrackAsset(assetName, data, language, useCache);
+
+ // raise event & return data
+ this.OnAssetLoaded(this, assetName);
return data;
}
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs b/src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs
index 206ece30..847e2ce1 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs
@@ -21,8 +21,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
** Public methods
*********/
/// <inheritdoc />
- public GameContentManagerForAssetPropagation(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset, bool aggressiveMemoryOptimizations)
- : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, onLoadingFirstAsset, aggressiveMemoryOptimizations) { }
+ public GameContentManagerForAssetPropagation(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, bool aggressiveMemoryOptimizations)
+ : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, onLoadingFirstAsset, onAssetLoaded, aggressiveMemoryOptimizations) { }
/// <inheritdoc />
public override T Load<T>(IAssetName assetName, LanguageCode language, bool useCache)
diff --git a/src/SMAPI/Framework/Events/EventManager.cs b/src/SMAPI/Framework/Events/EventManager.cs
index 96582380..bcfd7dd7 100644
--- a/src/SMAPI/Framework/Events/EventManager.cs
+++ b/src/SMAPI/Framework/Events/EventManager.cs
@@ -1,10 +1,8 @@
-using System.Diagnostics.CodeAnalysis;
using StardewModdingAPI.Events;
namespace StardewModdingAPI.Framework.Events
{
/// <summary>Manages SMAPI events.</summary>
- [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Private fields are deliberately named to simplify organisation.")]
internal class EventManager
{
/*********
@@ -19,6 +17,9 @@ namespace StardewModdingAPI.Framework.Events
/// <inheritdoc cref="IContentEvents.AssetsInvalidated" />
public readonly ManagedEvent<AssetsInvalidatedEventArgs> AssetsInvalidated;
+ /// <inheritdoc cref="IContentEvents.AssetReady" />
+ public readonly ManagedEvent<AssetReadyEventArgs> AssetReady;
+
/****
** Display
@@ -202,6 +203,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.AssetReady = ManageEventOf<AssetReadyEventArgs>(nameof(IModEvents.Content), nameof(IContentEvents.AssetReady));
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 4d0cfb97..cb242e99 100644
--- a/src/SMAPI/Framework/Events/ModContentEvents.cs
+++ b/src/SMAPI/Framework/Events/ModContentEvents.cs
@@ -23,6 +23,13 @@ namespace StardewModdingAPI.Framework.Events
remove => this.EventManager.AssetsInvalidated.Remove(value);
}
+ /// <inheritdoc />
+ public event EventHandler<AssetReadyEventArgs> AssetReady
+ {
+ add => this.EventManager.AssetReady.Add(value, this.Mod);
+ remove => this.EventManager.AssetReady.Remove(value);
+ }
+
/*********
** Public methods
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index e9bc9a2b..9d97ec7d 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -19,6 +19,7 @@ using Newtonsoft.Json;
using StardewModdingAPI.Enums;
using StardewModdingAPI.Events;
using StardewModdingAPI.Framework.Content;
+using StardewModdingAPI.Framework.ContentManagers;
using StardewModdingAPI.Framework.Events;
using StardewModdingAPI.Framework.Exceptions;
using StardewModdingAPI.Framework.Input;
@@ -1106,6 +1107,15 @@ namespace StardewModdingAPI.Framework
this.EventManager.DayEnding.RaiseEmpty();
}
+ /// <summary>A callback invoked after an asset is fully loaded through a content manager.</summary>
+ /// <param name="contentManager">The content manager through which the asset was loaded.</param>
+ /// <param name="assetName">The asset name that was loaded.</param>
+ private void OnAssetLoaded(IContentManager contentManager, IAssetName assetName)
+ {
+ if (this.EventManager.AssetReady.HasListeners())
+ this.EventManager.AssetReady.Raise(new AssetReadyEventArgs(assetName));
+ }
+
/// <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)
@@ -1183,6 +1193,7 @@ namespace StardewModdingAPI.Framework
reflection: this.Reflection,
jsonHelper: this.Toolkit.JsonHelper,
onLoadingFirstAsset: this.InitializeBeforeFirstAssetLoaded,
+ onAssetLoaded: this.OnAssetLoaded,
onAssetsInvalidated: this.OnAssetsInvalidated,
aggressiveMemoryOptimizations: this.Settings.AggressiveMemoryOptimizations,
requestAssetOperations: this.RequestAssetOperations