Skip to content

Commit f8c836c

Browse files
committed
Added a setting to sort unity loc tables.
This fixes the issue where a line added into the middle of a yarn file would be at the bottom of the string table. The downside to this is we do this by sorting the string table so for larger projects this could take a little while to complete. As such we default this to off but can be changed in the Yarn Spinner settings inside of Unity
1 parent 8e45ca6 commit f8c836c

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

Editor/Editors/YarnSpinnerProjectSettings.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class YarnSpinnerProjectSettings
4040
minorVersion = value.minor;
4141
}
4242
}
43+
public bool sortLocalisationValuesInsideStringTable = false;
44+
4345
private int majorVersion = 0;
4446
private int minorVersion = 0;
4547

@@ -49,6 +51,7 @@ class YarnSpinnerProjectSettings
4951
private const string enableDirectLinkToVSCodeKey = "enableDirectLinkToVSCode";
5052
private const string majorVersionKey = "majorVersion";
5153
private const string minorVersionKey = "minorVersion";
54+
private const string sortLocalisationValuesInsideStringTableKey = "sortLocalisationValuesInsideStringTable";
5255

5356
internal static YarnSpinnerProjectSettings GetOrCreateSettings(string? path = null, Yarn.Unity.ILogger? iLogger = null)
5457
{
@@ -80,6 +83,7 @@ internal static YarnSpinnerProjectSettings GetOrCreateSettings(string? path = nu
8083
settings.generateYSLSFile = false;
8184
settings.majorVersion = 0;
8285
settings.minorVersion = 0;
86+
settings.sortLocalisationValuesInsideStringTable = false;
8387
settings.WriteSettings(path, logger);
8488

8589
return settings;
@@ -119,13 +123,15 @@ T GetValueOrDefault<T>(string key, T defaultValue)
119123
bool enableDirectLinkToVSCode = GetValueOrDefault(enableDirectLinkToVSCodeKey, false);
120124
int major = GetValueOrDefault(majorVersionKey, 0);
121125
int minor = GetValueOrDefault(minorVersionKey, 0);
126+
bool sortLocalisationValuesInsideStringTable = GetValueOrDefault(sortLocalisationValuesInsideStringTableKey, false);
122127

123128
settings.automaticallyLinkAttributedYarnCommandsAndFunctions = automaticallyLinkAttributedYarnCommandsAndFunctions;
124129
settings.autoRefreshLocalisedAssets = autoRefreshLocalisedAssets;
125130
settings.generateYSLSFile = generateYSLSFile;
126131
settings.enableDirectLinkToVSCode = enableDirectLinkToVSCode;
127132
settings.majorVersion = major;
128133
settings.minorVersion = minor;
134+
settings.sortLocalisationValuesInsideStringTable = sortLocalisationValuesInsideStringTable;
129135
}
130136
catch (System.Exception ex)
131137
{

Editor/Editors/YarnSpinnerProjectSettingsProvider.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public override void OnGUI(string searchContext)
5050
var linkingAttributedFuncs = unsavedSettings.automaticallyLinkAttributedYarnCommandsAndFunctions;
5151
var generateYSLS = unsavedSettings.generateYSLSFile;
5252
var enableDirectLinkToVSCode = unsavedSettings.enableDirectLinkToVSCode;
53+
var sortLocalisationValuesInsideStringTable = unsavedSettings.sortLocalisationValuesInsideStringTable;
5354

5455
using (new EditorGUI.IndentLevelScope())
5556
{
@@ -67,6 +68,13 @@ public override void OnGUI(string searchContext)
6768
EditorGUILayout.LabelField("Generate YSLS file for attributed methods", GUILayout.Width(settingWidth), GUILayout.ExpandWidth(false));
6869
generateYSLS = EditorGUILayout.Toggle(unsavedSettings.generateYSLSFile, GUILayout.ExpandWidth(false));
6970
EditorGUILayout.EndHorizontal();
71+
72+
#if USE_UNITY_LOCALIZATION
73+
EditorGUILayout.BeginHorizontal();
74+
EditorGUILayout.LabelField("Keep Unity Localization tables sorted", GUILayout.Width(settingWidth), GUILayout.ExpandWidth(false));
75+
sortLocalisationValuesInsideStringTable = EditorGUILayout.Toggle(unsavedSettings.sortLocalisationValuesInsideStringTable, GUILayout.ExpandWidth(false));
76+
EditorGUILayout.EndHorizontal();
77+
#endif
7078
}
7179

7280
EditorGUILayout.Space();
@@ -85,6 +93,7 @@ public override void OnGUI(string searchContext)
8593
unsavedSettings.automaticallyLinkAttributedYarnCommandsAndFunctions = linkingAttributedFuncs;
8694
unsavedSettings.generateYSLSFile = generateYSLS;
8795
unsavedSettings.enableDirectLinkToVSCode = enableDirectLinkToVSCode;
96+
unsavedSettings.sortLocalisationValuesInsideStringTable = sortLocalisationValuesInsideStringTable;
8897
}
8998

9099
bool disabledReimportButton = true;
@@ -93,7 +102,8 @@ public override void OnGUI(string searchContext)
93102
unsavedSettings.automaticallyLinkAttributedYarnCommandsAndFunctions != baseSettings.automaticallyLinkAttributedYarnCommandsAndFunctions ||
94103
unsavedSettings.autoRefreshLocalisedAssets != baseSettings.autoRefreshLocalisedAssets ||
95104
unsavedSettings.generateYSLSFile != baseSettings.generateYSLSFile ||
96-
unsavedSettings.enableDirectLinkToVSCode != baseSettings.enableDirectLinkToVSCode
105+
unsavedSettings.enableDirectLinkToVSCode != baseSettings.enableDirectLinkToVSCode ||
106+
unsavedSettings.sortLocalisationValuesInsideStringTable != baseSettings.sortLocalisationValuesInsideStringTable
97107
)
98108
{
99109
disabledReimportButton = false;
@@ -123,12 +133,17 @@ public override void OnGUI(string searchContext)
123133
{
124134
needsCSharpRecompilation = true;
125135
}
136+
if (baseSettings.sortLocalisationValuesInsideStringTable != unsavedSettings.sortLocalisationValuesInsideStringTable)
137+
{
138+
needsYarnProjectReimport = true;
139+
}
126140

127141
// saving the changed settings out to disk
128142
baseSettings.autoRefreshLocalisedAssets = unsavedSettings.autoRefreshLocalisedAssets;
129143
baseSettings.automaticallyLinkAttributedYarnCommandsAndFunctions = unsavedSettings.automaticallyLinkAttributedYarnCommandsAndFunctions;
130144
baseSettings.generateYSLSFile = unsavedSettings.generateYSLSFile;
131145
baseSettings.enableDirectLinkToVSCode = unsavedSettings.enableDirectLinkToVSCode;
146+
baseSettings.sortLocalisationValuesInsideStringTable = unsavedSettings.sortLocalisationValuesInsideStringTable;
132147
baseSettings.WriteSettings();
133148

134149
// now we can reimport

Editor/Importers/YarnProjectImporter.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,44 @@ private static void AddStringTableEntries(IDictionary<string, StringInfo> string
13111311
}
13121312
}
13131313

1314+
if (YarnSpinnerProjectSettings.GetOrCreateSettings().sortLocalisationValuesInsideStringTable)
1315+
{
1316+
// sorting the table based on file and line number
1317+
Dictionary<string, string> sortKeys = new();
1318+
foreach (var pair in stringTable)
1319+
{
1320+
sortKeys[pair.Key] = $"{pair.Value.fileName.ToLower()}-{string.Format("{0:D6}", pair.Value.lineNumber)}";
1321+
}
1322+
1323+
HashSet<string> invalidKeys = new();
1324+
unityStringTable.SharedData.Entries.Sort((a,b) =>
1325+
{
1326+
// if we encounter a key that doesn't match a value we got from the string table we want to log this and push it to one end
1327+
if (sortKeys.TryGetValue(unityStringTable.GetEntry(a.Id).Key, out var aKey))
1328+
{
1329+
if (sortKeys.TryGetValue(unityStringTable.GetEntry(b.Id).Key, out var bKey))
1330+
{
1331+
return aKey.CompareTo(bKey);
1332+
}
1333+
else
1334+
{
1335+
invalidKeys.Add(unityStringTable.GetEntry(b.Id).Key);
1336+
return 1;
1337+
}
1338+
}
1339+
else
1340+
{
1341+
invalidKeys.Add(unityStringTable.GetEntry(a.Id).Key);
1342+
return -1;
1343+
}
1344+
});
1345+
// now that the table is sorted we want to log any invalid entries we might have found
1346+
foreach (var key in invalidKeys)
1347+
{
1348+
Debug.LogWarning($"Encountered an ID in the Yarn string table \"{key}\" during import that didn't come from the Yarn Project.");
1349+
}
1350+
}
1351+
13141352
// We've made changes to the table, so flag it and its shared data
13151353
// as dirty.
13161354
EditorUtility.SetDirty(unityStringTable);

0 commit comments

Comments
 (0)