mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-07 22:55:40 +12:00
GlobalConfig and create node data storage
This commit is contained in:
parent
eb23d7eab3
commit
f553e80080
9 changed files with 461 additions and 0 deletions
|
@ -11,6 +11,7 @@
|
||||||
android:glEsVersion="0x0030001"/>
|
android:glEsVersion="0x0030001"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".app.PandaApplication"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.panda3ds.pandroid.app;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.panda3ds.pandroid.data.config.GlobalConfig;
|
||||||
|
|
||||||
|
public class PandaApplication extends Application {
|
||||||
|
private static Context appContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
appContext = this;
|
||||||
|
GlobalConfig.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Context getAppContext() {
|
||||||
|
return appContext;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.panda3ds.pandroid.data.config;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import com.panda3ds.pandroid.app.PandaApplication;
|
||||||
|
import com.panda3ds.pandroid.utils.Constants;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class GlobalConfig {
|
||||||
|
private static SharedPreferences data;
|
||||||
|
|
||||||
|
public static void initialize() {
|
||||||
|
data = PandaApplication.getAppContext()
|
||||||
|
.getSharedPreferences(Constants.PREF_GLOBAL_CONFIG, Context.MODE_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Serializable> T get(Key<T> 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 <T extends Serializable> void set(Key<T> 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<T extends Serializable> {
|
||||||
|
private final String name;
|
||||||
|
private final T defValue;
|
||||||
|
|
||||||
|
private Key(String name, T defValue) {
|
||||||
|
this.name = name;
|
||||||
|
this.defValue = defValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<Object> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<NodeBase> changeListener;
|
||||||
|
|
||||||
|
protected void setParent(NodeBase parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void changed() {
|
||||||
|
if (parent != null)
|
||||||
|
parent.changed();
|
||||||
|
if (changeListener != null)
|
||||||
|
changeListener.run(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends NodeBase> void setChangeListener(Function<T> listener) {
|
||||||
|
changeListener = val -> listener.run((T) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NodeBase getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Object buildValue();
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public abstract String toString();
|
||||||
|
}
|
|
@ -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<String, Object> 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<String> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.panda3ds.pandroid.lang;
|
||||||
|
|
||||||
|
public interface Function<T> {
|
||||||
|
void run(T val);
|
||||||
|
}
|
|
@ -20,4 +20,6 @@ public class Constants {
|
||||||
|
|
||||||
public static final String ACTIVITY_PARAMETER_PATH = "path";
|
public static final String ACTIVITY_PARAMETER_PATH = "path";
|
||||||
public static final String LOG_TAG = "pandroid";
|
public static final String LOG_TAG = "pandroid";
|
||||||
|
|
||||||
|
public static final String PREF_GLOBAL_CONFIG = "app.GlobalConfig";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue