From e8f3177266bc6ee0c434305e6e259d6a4acf34a8 Mon Sep 17 00:00:00 2001 From: Eugenuss Date: Sun, 30 Aug 2020 16:29:22 +0300 Subject: [PATCH] Added runtime localization change support - Label.update() now invokes requestReassembly() method --- .../progressia/client/graphics/gui/Label.java | 5 +- .../client/graphics/gui/LayerTestGUI.java | 29 ++++++- .../client/localization/Localizer.java | 1 + .../client/localization/MutableString.java | 83 +++++++++++++++++++ .../localization/MutableStringConcat.java | 25 ++++++ .../localization/MutableStringFormatter.java | 29 +++++++ .../localization/MutableStringFunc.java | 17 ++++ .../localization/MutableStringLocalized.java | 18 ++++ .../localization/MutableStringParented.java | 14 ++++ 9 files changed, 215 insertions(+), 6 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/client/localization/MutableString.java create mode 100644 src/main/java/ru/windcorp/progressia/client/localization/MutableStringConcat.java create mode 100644 src/main/java/ru/windcorp/progressia/client/localization/MutableStringFormatter.java create mode 100644 src/main/java/ru/windcorp/progressia/client/localization/MutableStringFunc.java create mode 100644 src/main/java/ru/windcorp/progressia/client/localization/MutableStringLocalized.java create mode 100644 src/main/java/ru/windcorp/progressia/client/localization/MutableStringParented.java diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java index 1da850f..7fb5247 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java @@ -1,12 +1,12 @@ package ru.windcorp.progressia.client.graphics.gui; -import java.util.function.Supplier; - import glm.mat._4.Mat4; import glm.vec._2.i.Vec2i; import ru.windcorp.progressia.client.graphics.flat.RenderTarget; import ru.windcorp.progressia.client.graphics.font.Font; +import java.util.function.Supplier; + public class Label extends Component { private Font font; @@ -28,6 +28,7 @@ public class Label extends Component { public void update() { currentText = contents.get(); currentSize = font.getSize(currentText, Integer.MAX_VALUE, null).mul(2); + requestReassembly(); } @Override diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/LayerTestGUI.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/LayerTestGUI.java index a9bb658..d8d364e 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/LayerTestGUI.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/LayerTestGUI.java @@ -18,8 +18,8 @@ package ru.windcorp.progressia.client.graphics.gui; import com.google.common.eventbus.Subscribe; - import glm.vec._2.i.Vec2i; +import org.lwjgl.glfw.GLFW; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.flat.RenderTarget; import ru.windcorp.progressia.client.graphics.font.Font; @@ -28,6 +28,8 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign; import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical; import ru.windcorp.progressia.client.graphics.input.KeyEvent; import ru.windcorp.progressia.client.localization.Localizer; +import ru.windcorp.progressia.client.localization.MutableString; +import ru.windcorp.progressia.client.localization.MutableStringLocalized; public class LayerTestGUI extends GUILayer { @@ -51,7 +53,9 @@ public class LayerTestGUI extends GUILayer { } private boolean onClicked(KeyEvent event) { - if (event.isPress() && event.isLeftMouseButton()) { + if (!event.isMouse()) { + return false; + } else if (event.isPress() && event.isLeftMouseButton()) { System.out.println("You pressed a Component!"); } return true; @@ -81,12 +85,14 @@ public class LayerTestGUI extends GUILayer { //Debug Localizer.getInstance().setLanguage("ru-RU"); + MutableString epsilon = new MutableStringLocalized("Epsilon") + .addListener(() -> ((Label)charlie.getChild(0)).update()).format(34, "thirty-four"); // These two are swapped in code due to a bug in layouts, fixing ATM charlie.addChild( new Label( "Epsilon", new Font().withColor(0x4444BB).deriveItalic(), - Localizer.getInstance().getValue("Epsilon")+"\u269b" + () -> epsilon.get().concat("\u269b") ) ); charlie.addChild( @@ -97,7 +103,22 @@ public class LayerTestGUI extends GUILayer { ) ); panel.addChild(charlie); - + + + charlie.addListener(KeyEvent.class, e -> { + if(e.isPress() && e.getKey() == GLFW.GLFW_KEY_L) { + Localizer localizer = Localizer.getInstance(); + if (localizer.getLanguage().equals("ru-RU")) { + localizer.setLanguage("en-US"); + } else { + localizer.setLanguage("ru-RU"); + } + return true; + } return false; + }); + charlie.setFocusable(true); + charlie.takeFocus(); + getRoot().addChild(panel); } diff --git a/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java b/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java index 47e02b1..413ddab 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java @@ -64,6 +64,7 @@ public class Localizer { } private void pokeListeners(String newLanguage) { + //TODO extract as weak bus listener class synchronized (listeners) { Iterator> iterator = listeners.iterator(); while (iterator.hasNext()) { diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableString.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableString.java new file mode 100644 index 0000000..1aff3b3 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableString.java @@ -0,0 +1,83 @@ +package ru.windcorp.progressia.client.localization; + +import java.lang.ref.WeakReference; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.function.Function; + +public abstract class MutableString { + public interface Listener { + void onUpdate(); + } + + protected String data; + + protected final Collection> listeners = + Collections.synchronizedCollection(new LinkedList<>()); + + protected void pokeListeners() { + //TODO extract as weak bus listener class + synchronized (listeners) { + Iterator> iterator = listeners.iterator(); + while (iterator.hasNext()) { + Listener listenerOrNull = iterator.next().get(); + if (listenerOrNull == null) { + iterator.remove(); + } else { + listenerOrNull.onUpdate(); + } + } + } + } + + public MutableString addListener(Listener listener) { + listeners.add(new WeakReference<>(listener)); + return this; + } + + public MutableString removeListener(Listener listener) { + listeners.removeIf(ref -> listener.equals(ref.get())); + return this; + } + + protected void listen(Object obj) { + if (obj instanceof MutableString) { + ((MutableString) obj).addListener(this::update); + } + } + + public String get() { + if (data == null) { + data = compute(); + } + return data; + } + + public String toString() { + return get(); + } + + public MutableString apply(Function f) { + return new MutableStringFunc(this, f); + } + + public void update() { + data = compute(); + pokeListeners(); + } + protected abstract String compute(); + + public static MutableString formatted(Object format, Object... args) { + return new MutableStringFormatter(format, args); + } + + public MutableString format(Object... args) { + return formatted(this, args); + } + + public MutableString append(Object... objects) { + return new MutableStringConcat(this, objects); + } +} diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringConcat.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringConcat.java new file mode 100644 index 0000000..3035f0d --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringConcat.java @@ -0,0 +1,25 @@ +package ru.windcorp.progressia.client.localization; + +public class MutableStringConcat extends MutableString { + private final Object part0; + private final Object[] parts; + + public MutableStringConcat(Object object, Object... partsToConcat) { + this.part0 = object; + this.parts = partsToConcat; + + listen(object); + for (Object part : partsToConcat) { + listen(part); + } + } + + @Override + protected String compute() { + StringBuilder sb = new StringBuilder(String.valueOf(part0)); + for (Object part : parts) { + sb.append(part); + } + return sb.toString(); + } +} diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFormatter.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFormatter.java new file mode 100644 index 0000000..628bf06 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFormatter.java @@ -0,0 +1,29 @@ +package ru.windcorp.progressia.client.localization; + +import java.util.IllegalFormatException; + +public class MutableStringFormatter extends MutableString { + private final Object format; + private final Object[] args; + + public MutableStringFormatter(Object format, Object[] args) { + this.format = format; + this.args = args; + listen(format); + + for (Object arg : args) { + listen(arg); + } + } + + @Override + protected String compute() { + String format = this.format.toString(); + try { + return String.format(format, this.args); + } catch (IllegalFormatException e) { + return format; + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFunc.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFunc.java new file mode 100644 index 0000000..971572d --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFunc.java @@ -0,0 +1,17 @@ +package ru.windcorp.progressia.client.localization; + +import java.util.function.Function; + +public class MutableStringFunc extends MutableStringParented { + private final Function function; + + public MutableStringFunc(MutableString parent, Function f) { + super(parent); + this.function = f; + } + + @Override + protected String compute() { + return function.apply(getParent().get()); + } +} diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringLocalized.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringLocalized.java new file mode 100644 index 0000000..7ed8777 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringLocalized.java @@ -0,0 +1,18 @@ +package ru.windcorp.progressia.client.localization; + +public class MutableStringLocalized extends MutableString { + private final String key; + + LocaleListener listener = l -> update(); + + public MutableStringLocalized(String key) { + this.key = key; + Localizer.getInstance().addListener(listener); + update(); + } + + @Override + protected String compute() { + return Localizer.getInstance().getValue(key); + } +} diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringParented.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringParented.java new file mode 100644 index 0000000..db9c499 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringParented.java @@ -0,0 +1,14 @@ +package ru.windcorp.progressia.client.localization; + +public abstract class MutableStringParented extends MutableString { + private final MutableString parent; + + public MutableStringParented(MutableString parent) { + this.parent = parent; + listen(parent); + } + + public MutableString getParent() { + return parent; + } +}