summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2021-08-15 01:25:56 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2021-08-25 18:17:09 -0400
commit6cf7c49f34eac8edd18012d41d1f49a149fb1f5a (patch)
tree1e2b911c730acd643baae7493d5e7f938c014e87
parenta4c6c6168405bb0441a40e4f6f4e86dfa46a76b2 (diff)
downloadSMAPI-6cf7c49f34eac8edd18012d41d1f49a149fb1f5a.tar.gz
SMAPI-6cf7c49f34eac8edd18012d41d1f49a149fb1f5a.tar.bz2
SMAPI-6cf7c49f34eac8edd18012d41d1f49a149fb1f5a.zip
add GetInAllLocales to translation API
-rw-r--r--docs/release-notes.md1
-rw-r--r--src/SMAPI/Framework/ModHelpers/TranslationHelper.cs6
-rw-r--r--src/SMAPI/Framework/Translator.cs65
-rw-r--r--src/SMAPI/ITranslationHelper.cs7
4 files changed, 67 insertions, 12 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 9e42a847..409c4bd5 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -3,6 +3,7 @@
# Release notes
## Upcoming release
* For mod authors:
+ * Added `GetInAllLocales` method in translation API, to get a translation in every available locale.
* Fixed rare `NullReferenceException` in SMAPI's error-handling.
* Internal changes to prepare for upcoming releases.
diff --git a/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs b/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs
index a88ca9c9..869664fe 100644
--- a/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs
@@ -55,6 +55,12 @@ namespace StardewModdingAPI.Framework.ModHelpers
return this.Translator.Get(key, tokens);
}
+ /// <inheritdoc />
+ public IDictionary<string, Translation> GetInAllLocales(string key, bool withFallback = false)
+ {
+ return this.Translator.GetInAllLocales(key, withFallback);
+ }
+
/// <summary>Set the translations to use.</summary>
/// <param name="translations">The translations to use.</param>
internal TranslationHelper SetTranslations(IDictionary<string, IDictionary<string, string>> translations)
diff --git a/src/SMAPI/Framework/Translator.cs b/src/SMAPI/Framework/Translator.cs
index 11ec983b..4492b17f 100644
--- a/src/SMAPI/Framework/Translator.cs
+++ b/src/SMAPI/Framework/Translator.cs
@@ -46,18 +46,10 @@ namespace StardewModdingAPI.Framework
this.LocaleEnum = localeEnum;
this.ForLocale = new Dictionary<string, Translation>(StringComparer.OrdinalIgnoreCase);
- foreach (string next in this.GetRelevantLocales(this.Locale))
+ foreach (string key in this.GetAllKeysRaw())
{
- // skip if locale not defined
- if (!this.All.TryGetValue(next, out IDictionary<string, string> translations))
- continue;
-
- // add missing translations
- foreach (var pair in translations)
- {
- if (!this.ForLocale.ContainsKey(pair.Key))
- this.ForLocale.Add(pair.Key, new Translation(this.Locale, pair.Key, pair.Value));
- }
+ string text = this.GetRaw(key, locale, withFallback: true);
+ this.ForLocale.Add(key, new Translation(this.Locale, key, text));
}
}
@@ -83,6 +75,25 @@ namespace StardewModdingAPI.Framework
return this.Get(key).Tokens(tokens);
}
+ /// <summary>Get a translation in every locale for which it's defined.</summary>
+ /// <param name="key">The translation key.</param>
+ /// <param name="withFallback">Whether to add duplicate translations for locale fallback. For example, if a translation is defined in <c>default.json</c> but not <c>fr.json</c>, setting this to true will add a <c>fr</c> entry which duplicates the default text.</param>
+ public IDictionary<string, Translation> GetInAllLocales(string key, bool withFallback)
+ {
+ IDictionary<string, Translation> translations = new Dictionary<string, Translation>();
+
+ foreach (var localeSet in this.All)
+ {
+ string locale = localeSet.Key;
+ string text = this.GetRaw(key, locale, withFallback);
+
+ if (text != null)
+ translations[locale] = new Translation(locale, key, text);
+ }
+
+ return translations;
+ }
+
/// <summary>Set the translations to use.</summary>
/// <param name="translations">The translations to use.</param>
internal Translator SetTranslations(IDictionary<string, IDictionary<string, string>> translations)
@@ -102,6 +113,38 @@ namespace StardewModdingAPI.Framework
/*********
** Private methods
*********/
+ /// <summary>Get all translation keys in the underlying translation data, ignoring the <see cref="ForLocale"/> cache.</summary>
+ private IEnumerable<string> GetAllKeysRaw()
+ {
+ return new HashSet<string>(
+ this.All.SelectMany(p => p.Value.Keys),
+ StringComparer.OrdinalIgnoreCase
+ );
+ }
+
+ /// <summary>Get a translation from the underlying translation data, ignoring the <see cref="ForLocale"/> cache.</summary>
+ /// <param name="key">The translation key.</param>
+ /// <param name="locale">The locale to get.</param>
+ /// <param name="withFallback">Whether to add duplicate translations for locale fallback. For example, if a translation is defined in <c>default.json</c> but not <c>fr.json</c>, setting this to true will add a <c>fr</c> entry which duplicates the default text.</param>
+ private string GetRaw(string key, string locale, bool withFallback)
+ {
+ foreach (string next in this.GetRelevantLocales(locale))
+ {
+ string translation = null;
+ bool hasTranslation =
+ this.All.TryGetValue(next, out IDictionary<string, string> translations)
+ && translations.TryGetValue(key, out translation);
+
+ if (hasTranslation)
+ return translation;
+
+ if (!withFallback)
+ break;
+ }
+
+ return null;
+ }
+
/// <summary>Get the locales which can provide translations for the given locale, in precedence order.</summary>
/// <param name="locale">The locale for which to find valid locales.</param>
private IEnumerable<string> GetRelevantLocales(string locale)
diff --git a/src/SMAPI/ITranslationHelper.cs b/src/SMAPI/ITranslationHelper.cs
index c4b72444..b30d9b14 100644
--- a/src/SMAPI/ITranslationHelper.cs
+++ b/src/SMAPI/ITranslationHelper.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using StardewValley;
namespace StardewModdingAPI
@@ -30,5 +30,10 @@ namespace StardewModdingAPI
/// <param name="key">The translation key.</param>
/// <param name="tokens">An object containing token key/value pairs. This can be an anonymous object (like <c>new { value = 42, name = "Cranberries" }</c>), a dictionary, or a class instance.</param>
Translation Get(string key, object tokens);
+
+ /// <summary>Get a translation in every locale for which it's defined.</summary>
+ /// <param name="key">The translation key.</param>
+ /// <param name="withFallback">Whether to add duplicate translations for locale fallback. For example, if a translation is defined in <c>default.json</c> but not <c>fr.json</c>, setting this to true will add a <c>fr</c> entry which duplicates the default text.</param>
+ IDictionary<string, Translation> GetInAllLocales(string key, bool withFallback = false);
}
}