summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2018-11-25 00:07:26 -0500
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2018-11-25 00:07:26 -0500
commitfb253941dfdd370d3081c6e46707424d993b300a (patch)
tree9819c0ac1ceaa8b5c6add64da01f0b366b458a75 /src
parent43f11cfe51fdbb6c8fdee657ddf82d740ff6d738 (diff)
downloadSMAPI-fb253941dfdd370d3081c6e46707424d993b300a.tar.gz
SMAPI-fb253941dfdd370d3081c6e46707424d993b300a.tar.bz2
SMAPI-fb253941dfdd370d3081c6e46707424d993b300a.zip
add support for propagating map asset changes
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs16
-rw-r--r--src/SMAPI/Framework/ContentManagers/BaseContentManager.cs14
-rw-r--r--src/SMAPI/Framework/ContentManagers/IContentManager.cs4
-rw-r--r--src/SMAPI/Metadata/CoreAssetPropagator.cs30
4 files changed, 45 insertions, 19 deletions
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index 9eb7b5f9..08a32a9b 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -238,28 +238,30 @@ namespace StardewModdingAPI.Framework
public IEnumerable<string> InvalidateCache(Func<string, Type, bool> predicate, bool dispose = false)
{
// invalidate cache
- HashSet<string> removedAssetNames = new HashSet<string>();
+ IDictionary<string, Type> removedAssetNames = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);
foreach (IContentManager contentManager in this.ContentManagers)
{
- foreach (string name in contentManager.InvalidateCache(predicate, dispose))
- removedAssetNames.Add(name);
+ foreach (Tuple<string, Type> asset in contentManager.InvalidateCache(predicate, dispose))
+ removedAssetNames[asset.Item1] = asset.Item2;
}
// reload core game assets
int reloaded = 0;
- foreach (string key in removedAssetNames)
+ foreach (var pair in removedAssetNames)
{
- if (this.CoreAssets.Propagate(this.MainContentManager, key)) // use an intercepted content manager
+ string key = pair.Key;
+ Type type = pair.Value;
+ if (this.CoreAssets.Propagate(this.MainContentManager, key, type)) // use an intercepted content manager
reloaded++;
}
// report result
if (removedAssetNames.Any())
- this.Monitor.Log($"Invalidated {removedAssetNames.Count} asset names: {string.Join(", ", removedAssetNames.OrderBy(p => p, StringComparer.InvariantCultureIgnoreCase))}. Reloaded {reloaded} core assets.", LogLevel.Trace);
+ this.Monitor.Log($"Invalidated {removedAssetNames.Count} asset names: {string.Join(", ", removedAssetNames.Keys.OrderBy(p => p, StringComparer.InvariantCultureIgnoreCase))}. Reloaded {reloaded} core assets.", LogLevel.Trace);
else
this.Monitor.Log("Invalidated 0 cache entries.", LogLevel.Trace);
- return removedAssetNames;
+ return removedAssetNames.Keys;
}
/// <summary>Dispose held resources.</summary>
diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
index 18aae05b..ed08f11c 100644
--- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
@@ -200,23 +200,25 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <summary>Purge matched assets from the cache.</summary>
/// <param name="predicate">Matches the asset keys to invalidate.</param>
/// <param name="dispose">Whether to dispose invalidated assets. This should only be <c>true</c> when they're being invalidated as part of a dispose, to avoid crashing the game.</param>
- /// <returns>Returns the number of invalidated assets.</returns>
- public IEnumerable<string> InvalidateCache(Func<string, Type, bool> predicate, bool dispose = false)
+ /// <returns>Returns the invalidated asset names and types.</returns>
+ public IEnumerable<Tuple<string, Type>> InvalidateCache(Func<string, Type, bool> predicate, bool dispose = false)
{
- HashSet<string> removeAssetNames = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
+ Dictionary<string, Type> removeAssetNames = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);
this.Cache.Remove((key, type) =>
{
this.ParseCacheKey(key, out string assetName, out _);
- if (removeAssetNames.Contains(assetName) || predicate(assetName, type))
+ if (removeAssetNames.ContainsKey(assetName))
+ return true;
+ if (predicate(assetName, type))
{
- removeAssetNames.Add(assetName);
+ removeAssetNames[assetName] = type;
return true;
}
return false;
});
- return removeAssetNames;
+ return removeAssetNames.Select(p => Tuple.Create(p.Key, p.Value));
}
/// <summary>Dispose held resources.</summary>
diff --git a/src/SMAPI/Framework/ContentManagers/IContentManager.cs b/src/SMAPI/Framework/ContentManagers/IContentManager.cs
index 1eb8b0ac..17618edd 100644
--- a/src/SMAPI/Framework/ContentManagers/IContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/IContentManager.cs
@@ -80,7 +80,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <summary>Purge matched assets from the cache.</summary>
/// <param name="predicate">Matches the asset keys to invalidate.</param>
/// <param name="dispose">Whether to dispose invalidated assets. This should only be <c>true</c> when they're being invalidated as part of a dispose, to avoid crashing the game.</param>
- /// <returns>Returns the number of invalidated assets.</returns>
- IEnumerable<string> InvalidateCache(Func<string, Type, bool> predicate, bool dispose = false);
+ /// <returns>Returns the invalidated asset names and types.</returns>
+ IEnumerable<Tuple<string, Type>> InvalidateCache(Func<string, Type, bool> predicate, bool dispose = false);
}
}
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 8487b6be..841e6d64 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -13,6 +13,7 @@ using StardewValley.Menus;
using StardewValley.Objects;
using StardewValley.Projectiles;
using StardewValley.TerrainFeatures;
+using xTile;
using xTile.Tiles;
namespace StardewModdingAPI.Metadata
@@ -45,10 +46,11 @@ namespace StardewModdingAPI.Metadata
/// <summary>Reload one of the game's core assets (if applicable).</summary>
/// <param name="content">The content manager through which to reload the asset.</param>
/// <param name="key">The asset key to reload.</param>
+ /// <param name="type">The asset type to reload.</param>
/// <returns>Returns whether an asset was reloaded.</returns>
- public bool Propagate(LocalizedContentManager content, string key)
+ public bool Propagate(LocalizedContentManager content, string key, Type type)
{
- object result = this.PropagateImpl(content, key);
+ object result = this.PropagateImpl(content, key, type);
if (result is bool b)
return b;
return result != null;
@@ -61,9 +63,12 @@ namespace StardewModdingAPI.Metadata
/// <summary>Reload one of the game's core assets (if applicable).</summary>
/// <param name="content">The content manager through which to reload the asset.</param>
/// <param name="key">The asset key to reload.</param>
- /// <returns>Returns any non-null value to indicate an asset was loaded.</returns>
- private object PropagateImpl(LocalizedContentManager content, string key)
+ /// <param name="type">The asset type to reload.</param>
+ /// <returns>Returns whether an asset was loaded. The return value may be true or false, or a non-null value for true.</returns>
+ private object PropagateImpl(LocalizedContentManager content, string key, Type type)
{
+ key = this.GetNormalisedPath(key);
+
/****
** Special case: current map tilesheet
** We only need to do this for the current location, since tilesheets are reloaded when you enter a location.
@@ -79,6 +84,23 @@ namespace StardewModdingAPI.Metadata
}
/****
+ ** Propagate map changes
+ ****/
+ if (type == typeof(Map))
+ {
+ bool anyChanged = false;
+ foreach (GameLocation location in this.GetLocations())
+ {
+ if (this.GetNormalisedPath(location.mapPath.Value) == key)
+ {
+ this.Reflection.GetMethod(location, "reloadMap").Invoke();
+ anyChanged = true;
+ }
+ }
+ return anyChanged;
+ }
+
+ /****
** Propagate by key
****/
Reflector reflection = this.Reflection;