v0.8.0: updated string grabbing functionality to use LibGDX I18NBundle

This commit is contained in:
Evan Debenham 2020-02-03 21:42:25 -05:00
parent 2576b170c2
commit e24ee139ad

View File

@ -21,21 +21,19 @@
package com.shatteredpixel.shatteredpixeldungeon.messages; package com.shatteredpixel.shatteredpixeldungeon.messages;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.I18NBundle;
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings; import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.IllegalFormatException; import java.util.IllegalFormatException;
import java.util.Locale; import java.util.Locale;
import java.util.ResourceBundle;
/* /*
Simple wrapper class for java resource bundles. Simple wrapper class for libGDX I18NBundles.
The core idea here is that each string resource's key is a combination of the class definition and a local value. The core idea here is that each string resource's key is a combination of the class definition and a local value.
An object or static method would usually call this with an object/class reference (usually its own) and a local key. An object or static method would usually call this with an object/class reference (usually its own) and a local key.
@ -43,14 +41,7 @@ import java.util.ResourceBundle;
*/ */
public class Messages { public class Messages {
/* private static ArrayList<I18NBundle> bundles;
use hashmap for two reasons. Firstly because android 2.2 doesn't support resourcebundle.containskey(),
secondly so I can read in and combine multiple properties files,
resulting in a more clean structure for organizing all the strings, instead of one big file.
..Yes R.string would do this for me, but that's not multiplatform
*/
private static HashMap<String, String> strings;
private static Languages lang; private static Languages lang;
public static Languages lang(){ public static Languages lang(){
@ -63,16 +54,17 @@ public class Messages {
* Setup Methods * Setup Methods
*/ */
//TODO probably want to move these to assets now
private static String[] prop_files = new String[]{ private static String[] prop_files = new String[]{
"com.shatteredpixel.shatteredpixeldungeon.messages.actors.actors", "com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors",
"com.shatteredpixel.shatteredpixeldungeon.messages.items.items", "com/shatteredpixel/shatteredpixeldungeon/messages/items/items",
"com.shatteredpixel.shatteredpixeldungeon.messages.journal.journal", "com/shatteredpixel/shatteredpixeldungeon/messages/journal/journal",
"com.shatteredpixel.shatteredpixeldungeon.messages.levels.levels", "com/shatteredpixel/shatteredpixeldungeon/messages/levels/levels",
"com.shatteredpixel.shatteredpixeldungeon.messages.plants.plants", "com/shatteredpixel/shatteredpixeldungeon/messages/plants/plants",
"com.shatteredpixel.shatteredpixeldungeon.messages.scenes.scenes", "com/shatteredpixel/shatteredpixeldungeon/messages/scenes/scenes",
"com.shatteredpixel.shatteredpixeldungeon.messages.ui.ui", "com/shatteredpixel/shatteredpixeldungeon/messages/ui/ui",
"com.shatteredpixel.shatteredpixeldungeon.messages.windows.windows", "com/shatteredpixel/shatteredpixeldungeon/messages/windows/windows",
"com.shatteredpixel.shatteredpixeldungeon.messages.misc.misc" "com/shatteredpixel/shatteredpixeldungeon/messages/misc/misc"
}; };
static{ static{
@ -80,29 +72,15 @@ public class Messages {
} }
public static void setup( Languages lang ){ public static void setup( Languages lang ){
strings = new HashMap<>(); //seeing as missing keys are part of our process, this is faster than throwing an exception
I18NBundle.setExceptionOnMissingKey(false);
bundles = new ArrayList<>();
Messages.lang = lang; Messages.lang = lang;
Locale locale = new Locale(lang.code()); Locale locale = new Locale(lang.code());
for (String file : prop_files) { for (String file : prop_files) {
ResourceBundle bundle = ResourceBundle.getBundle( file, locale); bundles.add(I18NBundle.createBundle(Gdx.files.classpath(file), locale));
Enumeration<String> keys = bundle.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
String value = bundle.getString(key);
//TODO do all desktop platforms read as ISO, or only windows?
// should also move this to platform support, probably.
if (Gdx.app.getType() == Application.ApplicationType.Desktop) {
try {
value = new String(value.getBytes("ISO-8859-1"), "UTF-8");
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
}
}
strings.put(key, value);
}
} }
} }
@ -128,9 +106,10 @@ public class Messages {
} else } else
key = k; key = k;
if (strings.containsKey(key.toLowerCase(Locale.ENGLISH))){ String value = getFromBundle(key.toLowerCase(Locale.ENGLISH));
if (args.length > 0) return format(strings.get(key.toLowerCase(Locale.ENGLISH)), args); if (value != null){
else return strings.get(key.toLowerCase(Locale.ENGLISH)); if (args.length > 0) return format(value, args);
else return value;
} else { } else {
//this is so child classes can inherit properties from their parents. //this is so child classes can inherit properties from their parents.
//in cases where text is commonly grabbed as a utility from classes that aren't mean to be instantiated //in cases where text is commonly grabbed as a utility from classes that aren't mean to be instantiated
@ -143,6 +122,18 @@ public class Messages {
} }
} }
private static String getFromBundle(String key){
String result;
for (I18NBundle b : bundles){
result = b.get(key);
//if it isn't the return string for no key found, return it
if (result.length() != key.length()+6 || !result.contains(key)){
return result;
}
}
return null;
}
/** /**