From f553e800801bcb93d28c3155a3ad4cf54776a9af Mon Sep 17 00:00:00 2001 From: GabrielBRDeveloper Date: Thu, 14 Dec 2023 12:55:28 -0400 Subject: [PATCH] GlobalConfig and create node data storage --- src/pandroid/app/src/main/AndroidManifest.xml | 1 + .../pandroid/app/PandaApplication.java | 21 +++ .../pandroid/data/config/GlobalConfig.java | 61 +++++++ .../panda3ds/pandroid/data/node/Caster.java | 40 +++++ .../pandroid/data/node/NodeArray.java | 133 ++++++++++++++ .../panda3ds/pandroid/data/node/NodeBase.java | 34 ++++ .../pandroid/data/node/NodeObject.java | 164 ++++++++++++++++++ .../com/panda3ds/pandroid/lang/Function.java | 5 + .../panda3ds/pandroid/utils/Constants.java | 2 + 9 files changed, 461 insertions(+) create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/PandaApplication.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/config/GlobalConfig.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/Caster.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeArray.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeBase.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeObject.java create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Function.java diff --git a/src/pandroid/app/src/main/AndroidManifest.xml b/src/pandroid/app/src/main/AndroidManifest.xml index 291496f4..a4379fb2 100644 --- a/src/pandroid/app/src/main/AndroidManifest.xml +++ b/src/pandroid/app/src/main/AndroidManifest.xml @@ -11,6 +11,7 @@ android:glEsVersion="0x0030001"/> T get(Key key) { + Serializable value; + if (key.defValue instanceof String) { + value = data.getString(key.name, (String) key.defValue); + } else if (key.defValue instanceof Integer) { + value = data.getInt(key.name, (int) key.defValue); + } else if (key.defValue instanceof Boolean) { + value = data.getBoolean(key.name, (Boolean) key.defValue); + } else if (key.defValue instanceof Long) { + value = data.getLong(key.name, (Long) key.defValue); + } else { + value = data.getFloat(key.name, ((Number) key.defValue).floatValue()); + } + return (T) value; + } + + //Need synchronized why SharedPreferences don't support aysnc write + private static synchronized void set(Key key, T value) { + if (value instanceof String) { + data.edit().putString(key.name, (String) value).apply(); + } else if (value instanceof Integer) { + data.edit().putInt(key.name, (Integer) value).apply(); + } else if (value instanceof Boolean) { + data.edit().putBoolean(key.name, (Boolean) value).apply(); + } else if (value instanceof Long) { + data.edit().putLong(key.name, (Long) value).apply(); + } else if (value instanceof Float) { + data.edit().putFloat(key.name, (Float) value).apply(); + } else { + throw new IllegalArgumentException("Invalid global config value instance"); + } + } + + private static class Key { + private final String name; + private final T defValue; + + private Key(String name, T defValue) { + this.name = name; + this.defValue = defValue; + } + } +} \ No newline at end of file diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/Caster.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/Caster.java new file mode 100644 index 00000000..68f45302 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/Caster.java @@ -0,0 +1,40 @@ +package com.panda3ds.pandroid.data.node; + +/** + * JAVA THINGS: + * Java allow cast primary (int, double, float and long) + * but crash on cast object number why!! + **/ +class Caster { + public static int intValue(Object value){ + if (value instanceof Number){ + return ((Number)value).intValue(); + } else { + return Integer.parseInt((String) value); + } + } + + public static float floatValue(Object value){ + if (value instanceof Number){ + return ((Number)value).floatValue(); + } else { + return Float.parseFloat((String) value); + } + } + + public static long longValue(Object value){ + if (value instanceof Number){ + return ((Number)value).longValue(); + } else { + return Long.parseLong((String) value); + } + } + + public static double doubleValue(Object value){ + if (value instanceof Number){ + return ((Number)value).doubleValue(); + } else { + return Double.parseDouble((String) value); + } + } +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeArray.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeArray.java new file mode 100644 index 00000000..7f8a318b --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeArray.java @@ -0,0 +1,133 @@ +package com.panda3ds.pandroid.data.node; + +import androidx.annotation.NonNull; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +public class NodeArray extends NodeBase { + public static final String EMPTY_SOURCE = "[]"; + + private final ArrayList list = new ArrayList<>(); + + NodeArray(JSONArray array) { + init(array); + } + + public NodeArray() { + this(EMPTY_SOURCE); + } + + public NodeArray(String source) { + try { + init(new JSONArray(source)); + } catch (JSONException e) { + throw new IllegalArgumentException(e); + } + } + + private void init(JSONArray array) { + try { + for (int i = 0; i < array.length(); i++) { + Object item = array.get(i); + if (item instanceof JSONArray) { + item = new NodeArray((JSONArray) item); + ((NodeArray) item).setParent(this); + } else if (item instanceof JSONObject) { + item = new NodeObject((JSONObject) item); + ((NodeObject) item).setParent(this); + } + list.add(item); + } + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + private void add(Object obj) { + list.add(obj); + changed(); + } + + public String getString(int index) { + return (String) list.get(index); + } + + public int getInteger(int index) { + return Caster.intValue(list.get(index)); + } + + public long getLong(int index) { + return Caster.longValue(list.get(index)); + } + + public boolean getBoolean(int index) { + return (boolean) list.get(index); + } + + public double getDouble(int index) { + return Caster.doubleValue(list.get(index)); + } + + public NodeArray getArray(int index) { + return (NodeArray) list.get(index); + } + + public NodeObject getObject(int index) { + return (NodeObject) list.get(index); + } + + public void add(String val) { + list.add(val); + } + + public void add(int val) { + add((Object) val); + } + + public void add(long val) { + add((Object) val); + } + + public void add(double val) { + add((Object) val); + } + + public void add(boolean val) { + add((Object) val); + } + + public void add(NodeBase val) { + add((Object) val); + } + + public int getSize() { + return list.size(); + } + + @NonNull + @Override + public String toString() { + try { + return ((JSONArray) buildValue()).toString(4); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + @Override + protected Object buildValue() { + JSONArray array = new JSONArray(); + for (Object obj : list) { + if (obj instanceof NodeBase) { + array.put(((NodeBase) obj).buildValue()); + } else { + array.put(obj); + } + } + return array; + } +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeBase.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeBase.java new file mode 100644 index 00000000..12961a4f --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeBase.java @@ -0,0 +1,34 @@ +package com.panda3ds.pandroid.data.node; + +import androidx.annotation.NonNull; + +import com.panda3ds.pandroid.lang.Function; + +abstract class NodeBase { + private NodeBase parent = null; + private Function changeListener; + + protected void setParent(NodeBase parent) { + this.parent = parent; + } + + protected void changed() { + if (parent != null) + parent.changed(); + if (changeListener != null) + changeListener.run(this); + } + + public void setChangeListener(Function listener) { + changeListener = val -> listener.run((T) val); + } + + protected NodeBase getParent() { + return parent; + } + + protected abstract Object buildValue(); + + @NonNull + public abstract String toString(); +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeObject.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeObject.java new file mode 100644 index 00000000..40cb1682 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/node/NodeObject.java @@ -0,0 +1,164 @@ +package com.panda3ds.pandroid.data.node; + +import androidx.annotation.NonNull; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Iterator; + +public class NodeObject extends NodeBase { + + public static final String EMPTY_SOURCE = "{}"; + private final HashMap map = new HashMap<>(); + + NodeObject(JSONObject obj) { + init(obj); + } + + public NodeObject() { + this(EMPTY_SOURCE); + } + + public NodeObject(String source) { + try { + init(new JSONObject(source)); + } catch (JSONException e) { + throw new IllegalArgumentException(e); + } + } + + private void init(JSONObject base) { + try { + Iterator keys = base.keys(); + while (keys.hasNext()) { + String key = keys.next(); + Object item = base.get(key); + if (item instanceof JSONObject) { + item = new NodeObject((JSONObject) item); + ((NodeObject) item).setParent(this); + } else if (item instanceof JSONArray) { + item = new NodeArray((JSONArray) item); + ((NodeArray) item).setParent(this); + } + map.put(key, item); + } + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + private Object get(String key, Object def) { + if (!has(key)) + return def; + + return map.get(key); + } + + private void put(String key, Object value) { + map.put(key, value); + changed(); + } + + public String getString(String key, String def) { + return (String) get(key, def); + } + + public int getInteger(String key, int def) { + return Caster.intValue(get(key, def)); + } + + public long getLong(String key, long def) { + return Caster.longValue(get(key, def)); + } + + public boolean getBoolean(String key, boolean def) { + return (boolean) get(key, def); + } + + public double getDouble(String key, double def) { + return Caster.doubleValue(get(key, def)); + } + + public NodeArray getArray(String key, NodeArray def) { + return (NodeArray) get(key, def); + } + + public NodeObject getObject(String key, NodeObject def) { + return (NodeObject) get(key, def); + } + + public void put(String key, String val) { + put(key, (Object) val); + } + + public void put(String key, int val) { + put(key, (Object) val); + } + + public void put(String key, double val) { + put(key, (Object) val); + } + + public void put(String key, boolean val) { + put(key, (Object) val); + } + + public void put(String key, NodeBase val) { + put(key, (Object) val); + } + + public boolean has(String key) { + return map.containsKey(key); + } + + public void remove(String key) { + map.remove(key); + changed(); + } + + + public void clear() { + map.clear(); + changed(); + } + + public String[] getKeys() { + return map.keySet().toArray(new String[0]); + } + + + public int getSize() { + return map.size(); + } + + @NonNull + @Override + public String toString() { + try { + return ((JSONObject) buildValue()).toString(4); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + @Override + protected Object buildValue() { + try { + JSONObject dest = new JSONObject(); + for (String key : getKeys()) { + Object obj = map.get(key); + if (obj instanceof NodeBase) { + obj = ((NodeBase) obj).buildValue(); + } + dest.put(key, obj); + } + + return dest; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Function.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Function.java new file mode 100644 index 00000000..c5e6a4f4 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Function.java @@ -0,0 +1,5 @@ +package com.panda3ds.pandroid.lang; + +public interface Function { + void run(T val); +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/Constants.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/Constants.java index d94164c7..1aac0a4d 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/Constants.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/utils/Constants.java @@ -20,4 +20,6 @@ public class Constants { public static final String ACTIVITY_PARAMETER_PATH = "path"; public static final String LOG_TAG = "pandroid"; + + public static final String PREF_GLOBAL_CONFIG = "app.GlobalConfig"; }