summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2019-04-15 00:40:45 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2019-09-14 17:13:53 -0400
commit6c220453e16c6cb5ad150b61cf02685a97557b3c (patch)
tree8122aaa95a9135a1d3d418fb9a932c909d261ec5 /src
parent09d1c5a601e77c051dfde8a31f422b2c898086c3 (diff)
downloadSMAPI-6c220453e16c6cb5ad150b61cf02685a97557b3c.tar.gz
SMAPI-6c220453e16c6cb5ad150b61cf02685a97557b3c.tar.bz2
SMAPI-6c220453e16c6cb5ad150b61cf02685a97557b3c.zip
fix translatable assets not updated when switching language (#586)
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs7
-rw-r--r--src/SMAPI/Framework/ContentManagers/BaseContentManager.cs3
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs23
-rw-r--r--src/SMAPI/Framework/ContentManagers/IContentManager.cs3
-rw-r--r--src/SMAPI/Framework/SCore.cs6
-rw-r--r--src/SMAPI/Framework/SGame.cs8
6 files changed, 42 insertions, 8 deletions
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index caeb7ee9..25eeb2ef 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -114,6 +114,13 @@ namespace StardewModdingAPI.Framework
return this.MainContentManager.GetLocale(LocalizedContentManager.CurrentLanguageCode);
}
+ /// <summary>Perform any cleanup needed when the locale changes.</summary>
+ public void OnLocaleChanged()
+ {
+ foreach (IContentManager contentManager in this.ContentManagers)
+ contentManager.OnLocaleChanged();
+ }
+
/// <summary>Get whether this asset is mapped to a mod folder.</summary>
/// <param name="key">The asset key.</param>
public bool IsManagedAssetKey(string key)
diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
index 7821e454..b2b3769b 100644
--- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
@@ -138,6 +138,9 @@ namespace StardewModdingAPI.Framework.ContentManagers
}
}
+ /// <summary>Perform any cleanup needed when the locale changes.</summary>
+ public virtual void OnLocaleChanged() { }
+
/// <summary>Normalise path separators in a file path. For asset keys, see <see cref="AssertAndNormaliseAssetName"/> instead.</summary>
/// <param name="path">The file path to normalise.</param>
[Pure]
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index f159f035..55cf15ec 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -112,6 +112,29 @@ namespace StardewModdingAPI.Framework.ContentManagers
return data;
}
+ /// <summary>Perform any cleanup needed when the locale changes.</summary>
+ public override void OnLocaleChanged()
+ {
+ base.OnLocaleChanged();
+
+ // find assets for which a translatable version was loaded
+ HashSet<string> removeAssetNames = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
+ foreach (string key in this.IsLocalisableLookup.Where(p => p.Value).Select(p => p.Key))
+ removeAssetNames.Add(this.TryParseExplicitLanguageAssetKey(key, out string assetName, out _) ? assetName : key);
+
+ // invalidate translatable assets
+ string[] invalidated = this
+ .InvalidateCache((key, type) =>
+ removeAssetNames.Contains(key)
+ || (this.TryParseExplicitLanguageAssetKey(key, out string assetName, out _) && removeAssetNames.Contains(assetName))
+ )
+ .Select(p => p.Item1)
+ .OrderBy(p => p, StringComparer.InvariantCultureIgnoreCase)
+ .ToArray();
+ if (invalidated.Any())
+ this.Monitor.Log($"Invalidated {invalidated.Length} asset names: {string.Join(", ", invalidated)} for locale change.", LogLevel.Trace);
+ }
+
/// <summary>Create a new content manager for temporary use.</summary>
public override LocalizedContentManager CreateTemporary()
{
diff --git a/src/SMAPI/Framework/ContentManagers/IContentManager.cs b/src/SMAPI/Framework/ContentManagers/IContentManager.cs
index 17618edd..66ef9181 100644
--- a/src/SMAPI/Framework/ContentManagers/IContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/IContentManager.cs
@@ -52,6 +52,9 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="asset">The asset to clone.</param>
T CloneIfPossible<T>(T asset);
+ /// <summary>Perform any cleanup needed when the locale changes.</summary>
+ void OnLocaleChanged();
+
/// <summary>Normalise path separators in a file path. For asset keys, see <see cref="AssertAndNormaliseAssetName"/> instead.</summary>
/// <param name="path">The file path to normalise.</param>
[Pure]
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index f64af82b..e8d5b672 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -208,6 +208,9 @@ namespace StardewModdingAPI.Framework
// add more leniant assembly resolvers
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => AssemblyLoader.ResolveAssembly(e.Name);
+ // hook locale event
+ LocalizedContentManager.OnLanguageChange += locale => this.OnLocaleChanged();
+
// override game
SGame.ConstructorHack = new SGameConstructorHack(this.Monitor, this.Reflection, this.Toolkit.JsonHelper, this.InitialiseBeforeFirstAssetLoaded);
this.GameInstance = new SGame(
@@ -218,7 +221,6 @@ namespace StardewModdingAPI.Framework
jsonHelper: this.Toolkit.JsonHelper,
modRegistry: this.ModRegistry,
deprecationManager: SCore.DeprecationManager,
- onLocaleChanged: this.OnLocaleChanged,
onGameInitialised: this.InitialiseAfterGameStart,
onGameExiting: this.Dispose
);
@@ -442,6 +444,8 @@ namespace StardewModdingAPI.Framework
/// <summary>Handle the game changing locale.</summary>
private void OnLocaleChanged()
{
+ this.ContentCore.OnLocaleChanged();
+
// get locale
string locale = this.ContentCore.GetLocale();
LocalizedContentManager.LanguageCode languageCode = this.ContentCore.Language;
diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs
index 002a5d1b..684ff3ba 100644
--- a/src/SMAPI/Framework/SGame.cs
+++ b/src/SMAPI/Framework/SGame.cs
@@ -72,9 +72,6 @@ namespace StardewModdingAPI.Framework
/// <summary>Whether the game is creating the save file and SMAPI has already raised <see cref="IGameLoopEvents.SaveCreating"/>.</summary>
private bool IsBetweenCreateEvents;
- /// <summary>A callback to invoke after the content language changes.</summary>
- private readonly Action OnLocaleChanged;
-
/// <summary>A callback to invoke the first time *any* game content manager loads an asset.</summary>
private readonly Action OnLoadingFirstAsset;
@@ -137,10 +134,9 @@ namespace StardewModdingAPI.Framework
/// <param name="jsonHelper">Encapsulates SMAPI's JSON file parsing.</param>
/// <param name="modRegistry">Tracks the installed mods.</param>
/// <param name="deprecationManager">Manages deprecation warnings.</param>
- /// <param name="onLocaleChanged">A callback to invoke after the content language changes.</param>
/// <param name="onGameInitialised">A callback to invoke after the game finishes initialising.</param>
/// <param name="onGameExiting">A callback to invoke when the game exits.</param>
- internal SGame(IMonitor monitor, IMonitor monitorForGame, Reflector reflection, EventManager eventManager, JsonHelper jsonHelper, ModRegistry modRegistry, DeprecationManager deprecationManager, Action onLocaleChanged, Action onGameInitialised, Action onGameExiting)
+ internal SGame(IMonitor monitor, IMonitor monitorForGame, Reflector reflection, EventManager eventManager, JsonHelper jsonHelper, ModRegistry modRegistry, DeprecationManager deprecationManager, Action onGameInitialised, Action onGameExiting)
{
this.OnLoadingFirstAsset = SGame.ConstructorHack.OnLoadingFirstAsset;
SGame.ConstructorHack = null;
@@ -159,7 +155,6 @@ namespace StardewModdingAPI.Framework
this.ModRegistry = modRegistry;
this.Reflection = reflection;
this.DeprecationManager = deprecationManager;
- this.OnLocaleChanged = onLocaleChanged;
this.OnGameInitialised = onGameInitialised;
this.OnGameExiting = onGameExiting;
Game1.input = new SInputState();
@@ -467,7 +462,6 @@ namespace StardewModdingAPI.Framework
if (this.Watchers.LocaleWatcher.IsChanged)
{
this.Monitor.Log($"Context: locale set to {this.Watchers.LocaleWatcher.CurrentValue}.", LogLevel.Trace);
- this.OnLocaleChanged();
this.Watchers.LocaleWatcher.Reset();
}