Created
July 11, 2019 23:19
-
-
Save killjoy1221/09f1070aba5e11eb747116340c800536 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ConfigManager { | |
private static Set<String> configPaths = new HashSet<>(); | |
private static Map<Object, ConfigInstance> configs = new HashMap<>(); | |
public static <T extends JsonConfig> void register(String path, T config) { | |
Preconditions.checkState(!configPaths.contains(path), "Duplicate configuration file!"); | |
Preconditions.checkState(!configs.containsKey(config), "Duplicate config instance!"); | |
Path configPath = FabricLoader.getInstance().getConfigDirectory().toPath().resolve(path); | |
configPaths.add(path); | |
configs.put(path, new ConfigInstance<>(configPath, config)); | |
try { | |
try { | |
load(config); | |
} catch (NoSuchFileException e) { | |
save(config); | |
} | |
} catch (IOException e) { | |
LogManager.getLogger().warn("Unable to load config {}", config, e); | |
} | |
} | |
/** | |
* Used by {@link ConfigScreen} to get the {@link ConfigInstance#valueCache cached values}. | |
*/ | |
@SuppressWarnings("unchecked") | |
static <T extends JsonConfig> ConfigInstance<T> getInstance(T config) { | |
return (ConfigInstance<T>) configs.get(config); | |
} | |
public static void load(JsonConfig config) throws IOException { | |
getInstance(config).load(); | |
} | |
public static void save(JsonConfig config) throws IOException { | |
getInstance(config).save(); | |
} | |
static class ConfigInstance<T extends JsonConfig> { | |
private final Gson gson; | |
private final Path configPath; | |
private final T config; | |
final Map<String, Value<Object>> valueCache; | |
private ConfigInstance(Path configPath, T config) { | |
this.configPath = configPath; | |
this.config = config; | |
valueCache = cacheValueObjects(); | |
GsonBuilder builder = new GsonBuilder(); | |
builder.registerTypeAdapter(config.getClass(), new TypeAdapter<T>() { | |
@Override | |
public void write(JsonWriter out, T value) throws IOException { | |
out.beginObject(); | |
for (Map.Entry<String, Value<Object>> entry : valueCache.entrySet()) { | |
out.name(entry.getKey()); | |
Value<?> val = entry.getValue(); | |
gson.toJson(val.get(), val.getDefault().getClass(), out); | |
} | |
out.endObject(); | |
} | |
@Override | |
public T read(JsonReader in) throws IOException { | |
in.beginObject(); | |
while (in.hasNext()) { | |
Value<Object> value = valueCache.get(in.nextName()); | |
if (value == null) { | |
in.skipValue(); | |
} else { | |
Object o = gson.fromJson(in, value.getDefault().getClass()); | |
value.set(o); | |
} | |
} | |
in.endObject(); | |
return config; | |
} | |
}); | |
config.setupGson(builder); | |
this.gson = builder.create(); | |
} | |
/** | |
* Cache all the values from the config | |
*/ | |
@SuppressWarnings("unchecked") | |
private Map<String, Value<Object>> cacheValueObjects() { | |
try { | |
Map<String, Value<Object>> map = new TreeMap<>(); | |
for (Field f : config.getClass().getFields()) { | |
if (f.getType() == Value.class) { | |
String name = f.getName(); | |
Value<Object> value = (Value<Object>) f.get(config); | |
map.put(name, value); | |
} | |
} | |
return ImmutableMap.copyOf(map); | |
} catch (IllegalAccessException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
private void load() throws IOException { | |
try (Reader r = Files.newBufferedReader(configPath)) { | |
gson.fromJson(r, config.getClass()); | |
} | |
} | |
private void save() throws IOException { | |
Files.createDirectories(configPath.getParent()); | |
try (Writer w = Files.newBufferedWriter(configPath)) { | |
gson.toJson(config, w); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface JsonConfig { | |
default void setupGson(GsonBuilder builder) { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Value<T> { | |
private final T def; | |
private T value; | |
public Value(T def) { | |
this.def = def; | |
} | |
public void set(T value) { | |
this.value = value; | |
} | |
public T get() { | |
return this.value; | |
} | |
public T getDefault() { | |
return def; | |
} | |
public void reset() { | |
set(def); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment