mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-11-26 06:18:00 +01:00
Rewrote configurations to get rid of reflection
This commit is contained in:
parent
2fd94f9434
commit
0d5656685c
9 changed files with 162 additions and 168 deletions
|
@ -19,7 +19,7 @@ import com.minelittlepony.client.gui.hdskins.MineLPHDSkins;
|
||||||
import com.minelittlepony.client.mixin.MixinBlockEntityRenderDispatcher;
|
import com.minelittlepony.client.mixin.MixinBlockEntityRenderDispatcher;
|
||||||
import com.minelittlepony.client.settings.ClientPonyConfig;
|
import com.minelittlepony.client.settings.ClientPonyConfig;
|
||||||
import com.minelittlepony.hdskins.mixin.MixinEntityRenderDispatcher;
|
import com.minelittlepony.hdskins.mixin.MixinEntityRenderDispatcher;
|
||||||
import com.minelittlepony.settings.SensibleJsonConfig;
|
import com.minelittlepony.settings.JsonConfig;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -36,7 +36,7 @@ public class FabMod implements ClientModInitializer, IModUtilities {
|
||||||
mlp = new MineLPClient(this);
|
mlp = new MineLPClient(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
mlp.init(SensibleJsonConfig.of(getConfigDirectory().resolve("minelp.json"), ClientPonyConfig::new));
|
mlp.init(JsonConfig.of(getConfigDirectory().resolve("minelp.json"), ClientPonyConfig::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,8 +3,8 @@ package com.minelittlepony.client.render.entities;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.minelittlepony.MineLittlePony;
|
import com.minelittlepony.MineLittlePony;
|
||||||
import com.minelittlepony.client.PonyRenderManager;
|
import com.minelittlepony.client.PonyRenderManager;
|
||||||
import com.minelittlepony.settings.SensibleConfig;
|
import com.minelittlepony.settings.Config;
|
||||||
import com.minelittlepony.settings.SensibleConfig.Setting;
|
import com.minelittlepony.settings.Config.Setting;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -13,10 +13,8 @@ import net.minecraft.entity.passive.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Central location where new entity renderers are registered and applied.
|
* Central location where new entity renderers are registered and applied.
|
||||||
*
|
|
||||||
* Due to the limitations in Mumfrey's framework, needs to be paired with a field in PonyConfig.
|
|
||||||
*/
|
*/
|
||||||
public enum MobRenderers implements Setting {
|
public enum MobRenderers implements Setting<Boolean> {
|
||||||
VILLAGERS {
|
VILLAGERS {
|
||||||
@Override
|
@Override
|
||||||
void register(boolean state, PonyRenderManager pony) {
|
void register(boolean state, PonyRenderManager pony) {
|
||||||
|
@ -73,13 +71,18 @@ public enum MobRenderers implements Setting {
|
||||||
public static final List<MobRenderers> registry = Lists.newArrayList(values());
|
public static final List<MobRenderers> registry = Lists.newArrayList(values());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(boolean value) {
|
public Boolean getDefault() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Boolean value) {
|
||||||
Setting.super.set(value);
|
Setting.super.set(value);
|
||||||
apply(PonyRenderManager.getInstance());
|
apply(PonyRenderManager.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SensibleConfig config() {
|
public Config config() {
|
||||||
return MineLittlePony.getInstance().getConfig();
|
return MineLittlePony.getInstance().getConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
package com.minelittlepony.client.settings;
|
package com.minelittlepony.client.settings;
|
||||||
|
|
||||||
|
import com.minelittlepony.client.render.entities.MobRenderers;
|
||||||
import com.minelittlepony.hdskins.HDSkins;
|
import com.minelittlepony.hdskins.HDSkins;
|
||||||
import com.minelittlepony.settings.PonyConfig;
|
import com.minelittlepony.settings.PonyConfig;
|
||||||
import com.minelittlepony.settings.PonyLevel;
|
import com.minelittlepony.settings.PonyLevel;
|
||||||
|
|
||||||
public class ClientPonyConfig extends PonyConfig {
|
public class ClientPonyConfig extends PonyConfig {
|
||||||
|
|
||||||
|
public ClientPonyConfig() {
|
||||||
|
initWith(MobRenderers.values());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPonyLevel(PonyLevel ponylevel) {
|
public void setPonyLevel(PonyLevel ponylevel) {
|
||||||
// only trigger reloads when the value actually changes
|
// only trigger reloads when the value actually changes
|
||||||
|
|
104
src/main/java/com/minelittlepony/settings/Config.java
Normal file
104
src/main/java/com/minelittlepony/settings/Config.java
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
package com.minelittlepony.settings;
|
||||||
|
|
||||||
|
import com.minelittlepony.common.client.gui.IField.IChangeCallback;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A configuration container that lets you programmatically index values by a key.
|
||||||
|
*/
|
||||||
|
public abstract class Config {
|
||||||
|
|
||||||
|
protected Map<String, Object> entries = new HashMap<>();
|
||||||
|
|
||||||
|
protected void initWith(Setting<?>... settings) {
|
||||||
|
for (Setting<?> s : settings) {
|
||||||
|
entries.putIfAbsent(s.name(), s.getDefault());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void save();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any value that can be stored in this config file.
|
||||||
|
*/
|
||||||
|
public class Value<T> implements Setting<T> {
|
||||||
|
private final T def;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public Value(String name, T def) {
|
||||||
|
this.name = name;
|
||||||
|
this.def = def;
|
||||||
|
|
||||||
|
entries.putIfAbsent(name(), def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public T getDefault() {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Config config() {
|
||||||
|
return Config.this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any settings.
|
||||||
|
*/
|
||||||
|
public interface Setting<T> extends IChangeCallback<T> {
|
||||||
|
String name();
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
T getDefault();
|
||||||
|
|
||||||
|
Config config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the config value associated with this entry.
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
default T get() {
|
||||||
|
T t = (T)config().entries.computeIfAbsent(name(), k -> getDefault());
|
||||||
|
|
||||||
|
if (t == null) {
|
||||||
|
t = getDefault();
|
||||||
|
|
||||||
|
set(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the config value associated with this entry.
|
||||||
|
*/
|
||||||
|
default void set(@Nullable T value) {
|
||||||
|
value = value == null ? getDefault() : value;
|
||||||
|
config().entries.put(name(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default T perform(T v) {
|
||||||
|
set(v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,15 +3,20 @@ package com.minelittlepony.settings;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import com.minelittlepony.client.settings.ClientPonyConfig;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class SensibleJsonConfig extends SensibleConfig {
|
public class JsonConfig extends Config {
|
||||||
|
|
||||||
|
public static <T extends JsonConfig> T of(Path file, Supplier<T> creator) {
|
||||||
|
return creator.get().load(file);
|
||||||
|
}
|
||||||
|
|
||||||
static final Gson gson = new GsonBuilder()
|
static final Gson gson = new GsonBuilder()
|
||||||
.setPrettyPrinting()
|
.setPrettyPrinting()
|
||||||
|
@ -22,42 +27,32 @@ public class SensibleJsonConfig extends SensibleConfig {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save() {
|
public void save() {
|
||||||
|
|
||||||
try (JsonWriter writer = new JsonWriter(Files.newBufferedWriter(configFile))) {
|
try (JsonWriter writer = new JsonWriter(Files.newBufferedWriter(configFile))) {
|
||||||
writer.setIndent(" ");
|
writer.setIndent(" ");
|
||||||
|
|
||||||
gson.toJson(this, ClientPonyConfig.class, writer);
|
gson.toJson(entries, HashMap.class, writer);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T extends SensibleJsonConfig> T load(Path file) {
|
protected <T extends JsonConfig> T load(Path file) {
|
||||||
SensibleJsonConfig result = this;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Files.exists(file)) {
|
if (Files.exists(file)) {
|
||||||
try (BufferedReader s = Files.newBufferedReader(file)) {
|
try (BufferedReader s = Files.newBufferedReader(file)) {
|
||||||
result = gson.fromJson(s, getClass());
|
Map<String, Object> parsed = gson.fromJson(s, HashMap.class);
|
||||||
} catch (IOException ignored) {
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == null) {
|
if (parsed != null) {
|
||||||
result = this;
|
entries = parsed;
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) { }
|
||||||
}
|
}
|
||||||
|
configFile = file;
|
||||||
result.configFile = file;
|
|
||||||
} finally {
|
} finally {
|
||||||
result.save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (T)result;
|
return (T)this;
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends SensibleJsonConfig> T of(Path file, Supplier<T> creator) {
|
|
||||||
return creator.get().load(file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
package com.minelittlepony.settings;
|
|
||||||
|
|
||||||
public enum MobSettings {
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,32 +2,17 @@ package com.minelittlepony.settings;
|
||||||
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage container for MineLP client settings.
|
* Storage container for MineLP client settings.
|
||||||
*/
|
*/
|
||||||
public abstract class PonyConfig extends SensibleJsonConfig {
|
public class PonyConfig extends JsonConfig {
|
||||||
|
|
||||||
@Expose private PonyLevel ponylevel = PonyLevel.PONIES;
|
private final Setting<PonyLevel> ponyLevel = new Value<>("ponylevel", PonyLevel.PONIES);
|
||||||
|
private final Setting<Float> scaleFactor = new Value<>("globalScaleFactor", 0.9F);
|
||||||
|
|
||||||
@Expose boolean sizes = true;
|
public PonyConfig() {
|
||||||
@Expose boolean snuzzles = true;
|
initWith(PonySettings.values());
|
||||||
@Expose boolean hd = true;
|
}
|
||||||
@Expose boolean showscale = true;
|
|
||||||
@Expose boolean fpsmagic = true;
|
|
||||||
@Expose boolean ponyskulls = true;
|
|
||||||
@Expose boolean frustrum = true;
|
|
||||||
|
|
||||||
@Expose boolean villagers = true;
|
|
||||||
@Expose boolean zombies = true;
|
|
||||||
@Expose boolean pigzombies = true;
|
|
||||||
@Expose boolean skeletons = true;
|
|
||||||
@Expose boolean illagers = true;
|
|
||||||
@Expose boolean guardians = true;
|
|
||||||
@Expose boolean endermen = true;
|
|
||||||
|
|
||||||
@Expose private float globalScaleFactor = 0.9F;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current PonyLevel. That is the level of ponies you would like to see.
|
* Gets the current PonyLevel. That is the level of ponies you would like to see.
|
||||||
|
@ -42,10 +27,7 @@ public abstract class PonyConfig extends SensibleJsonConfig {
|
||||||
* Actually gets the pony level value. No option to ignore reality here.
|
* Actually gets the pony level value. No option to ignore reality here.
|
||||||
*/
|
*/
|
||||||
public PonyLevel getPonyLevel() {
|
public PonyLevel getPonyLevel() {
|
||||||
if (ponylevel == null) {
|
return ponyLevel.get();
|
||||||
ponylevel = PonyLevel.PONIES;
|
|
||||||
}
|
|
||||||
return ponylevel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,18 +36,20 @@ public abstract class PonyConfig extends SensibleJsonConfig {
|
||||||
* @param ponylevel
|
* @param ponylevel
|
||||||
*/
|
*/
|
||||||
public void setPonyLevel(PonyLevel ponylevel) {
|
public void setPonyLevel(PonyLevel ponylevel) {
|
||||||
this.ponylevel = ponylevel;
|
ponyLevel.set(ponylevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGlobalScaleFactor(float f) {
|
public void setGlobalScaleFactor(float f) {
|
||||||
globalScaleFactor = Math.round(MathHelper.clamp(f, 0.1F, 3) * 100) / 100F;
|
f = Math.round(MathHelper.clamp(f, 0.1F, 3) * 100) / 100F;
|
||||||
showscale = globalScaleFactor != 1;
|
|
||||||
|
scaleFactor.set(f);
|
||||||
|
PonySettings.SHOWSCALE.set(f != 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the universal scale factor used to determine how tall ponies are.
|
* Gets the universal scale factor used to determine how tall ponies are.
|
||||||
*/
|
*/
|
||||||
public float getGlobalScaleFactor() {
|
public float getGlobalScaleFactor() {
|
||||||
return showscale ? globalScaleFactor : 1;
|
return PonySettings.SHOWSCALE.get() ? scaleFactor.get() : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package com.minelittlepony.settings;
|
package com.minelittlepony.settings;
|
||||||
|
|
||||||
import com.minelittlepony.MineLittlePony;
|
import com.minelittlepony.MineLittlePony;
|
||||||
import com.minelittlepony.settings.SensibleConfig.Setting;
|
import com.minelittlepony.settings.Config.Setting;
|
||||||
|
|
||||||
public enum PonySettings implements Setting {
|
/**
|
||||||
|
* Mod settings.
|
||||||
|
*/
|
||||||
|
public enum PonySettings implements Setting<Boolean> {
|
||||||
SIZES,
|
SIZES,
|
||||||
SNUZZLES,
|
SNUZZLES,
|
||||||
HD,
|
HD,
|
||||||
|
@ -13,7 +16,12 @@ public enum PonySettings implements Setting {
|
||||||
FRUSTRUM;
|
FRUSTRUM;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SensibleConfig config() {
|
public Boolean getDefault() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Config config() {
|
||||||
return MineLittlePony.getInstance().getConfig();
|
return MineLittlePony.getInstance().getConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
package com.minelittlepony.settings;
|
|
||||||
|
|
||||||
import com.minelittlepony.common.client.gui.IField.IChangeCallback;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A sensible config container that actually lets us programmatically index values by a key.
|
|
||||||
*
|
|
||||||
* Reflection because Mumfrey pls.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
// Mumfrey pls.
|
|
||||||
// TODO: Reflection
|
|
||||||
public abstract class SensibleConfig {
|
|
||||||
|
|
||||||
public abstract void save();
|
|
||||||
|
|
||||||
public interface Setting extends IChangeCallback<Boolean> {
|
|
||||||
String name();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the config value associated with this entry.
|
|
||||||
*/
|
|
||||||
default boolean get() {
|
|
||||||
return config().getValue(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the config value associated with this entry.
|
|
||||||
*/
|
|
||||||
default void set(boolean value) {
|
|
||||||
config().setValue(this, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
SensibleConfig config();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default Boolean perform(Boolean v) {
|
|
||||||
set(v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Setting, Boolean> entries = new HashMap<>();
|
|
||||||
private Map<Setting, Field> fieldEntries = new HashMap<>();
|
|
||||||
|
|
||||||
public boolean getValue(Setting key) {
|
|
||||||
return entries.computeIfAbsent(key, this::reflectGetValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setValue(Setting key, boolean value) {
|
|
||||||
entries.put(key, value);
|
|
||||||
try {
|
|
||||||
findField(getClass(), key).setBoolean(this, value);
|
|
||||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
protected Field findField(Class<?> type, Setting key) {
|
|
||||||
return fieldEntries.computeIfAbsent(key, k -> recurseFindField(type, key));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean reflectGetValue(Setting key) {
|
|
||||||
try {
|
|
||||||
return findField(getClass(), key).getBoolean(this);
|
|
||||||
} catch (IllegalArgumentException | IllegalAccessException | SecurityException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private Field recurseFindField(Class<?> type, Setting key) {
|
|
||||||
try {
|
|
||||||
Field f = type.getDeclaredField(key.name().toLowerCase());
|
|
||||||
f.setAccessible(true);
|
|
||||||
fieldEntries.put(key, f);
|
|
||||||
|
|
||||||
return f;
|
|
||||||
} catch (IllegalArgumentException | NoSuchFieldException | SecurityException e) {
|
|
||||||
Class<?> superType = type.getSuperclass();
|
|
||||||
|
|
||||||
if (superType != null && superType != Object.class) {
|
|
||||||
return recurseFindField(superType, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException(String.format("Config option %s was not defined", key), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue