Merge pull request #2 from frqnny/modularize

Port to java 16 and MC 1.17
This commit is contained in:
Draylar
2021-05-27 10:43:32 -05:00
committed by GitHub
21 changed files with 157 additions and 156 deletions
+12 -6
View File
@@ -4,13 +4,15 @@
*The last config library you will ever use.*
ΩConfig is a hyper-minimal config library based on [Auto Config](https://github.com/shedaniel/AutoConfig). It aims to achieve
the following goals:
ΩConfig is a hyper-minimal config library based on [Auto Config](https://github.com/shedaniel/AutoConfig). It aims to
achieve the following goals:
- Be lightweight (<10 KB) for JIJ usage
- Exceedingly simple design & API for developers
- Intuition and usability for players
The following is an example of a simple ΩConfig setup:
```java
public class TestConfig implements Config {
@@ -24,6 +26,7 @@ public class TestConfig implements Config {
}
```
```java
public class MyModInitializer {
@@ -35,7 +38,9 @@ public class MyModInitializer {
}
}
```
---
### Extra API Utilities
ΩConfig provides several utility methods for developers.
@@ -43,11 +48,12 @@ public class MyModInitializer {
**save()** - *saves a modified configuration instance to disk*
```java
MyModInitializer.CONFIG.value = false;
MyModInitializer.CONFIG.save(); // writes the new value to disk
MyModInitializer.CONFIG.value=false;
MyModInitializer.CONFIG.save(); // writes the new value to disk
```
---
### License
ΩConfig is available under Public Domain.
You are encouraged to utilize the code in this repository in any way you wish.
ΩConfig is available under Public Domain. You are encouraged to utilize the code in this repository in any way you wish.
+16 -13
View File
@@ -10,7 +10,7 @@ buildscript {
}
dependencies {
classpath 'com.guardsquare:proguard-gradle:7.0.1'
classpath 'com.guardsquare:proguard-gradle:7.1.0-beta4'
}
}
@@ -105,10 +105,10 @@ subprojects {
tasks.publish.dependsOn build //stupid fix for maven/loom not publishing the main artifact
task ('proguard', type: proguard.gradle.ProGuardTask) {
task('proguard', type: proguard.gradle.ProGuardTask) {
configuration './proguard.conf'
verbose
injars project.buildDir.toString() + '/libs/' + archivesBaseName + "-" + project.mod_version + ".jar"
injars project.buildDir.toString() + '/libs/' + archivesBaseName + "-" + project.mod_version + ".jar"
outjars project.buildDir.toString() + '/libs/' + archivesBaseName + "-" + project.mod_version + "-min.jar"
printmapping 'out.map'
keepparameternames
@@ -137,7 +137,7 @@ subprojects {
allprojects {
apply plugin: "fabric-loom"
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_16
version = System.getenv("TRAVIS_TAG") ?: project.mod_version
repositories {
@@ -146,7 +146,7 @@ allprojects {
url = "https://maven.fabricmc.net"
}
maven { url = "https://maven.terraformersmc.com/releases/"}
maven { url = "https://maven.terraformersmc.com/releases/" }
}
dependencies {
@@ -155,10 +155,19 @@ allprojects {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modRuntime "com.terraformersmc:modmenu:1.16.8"
modCompileOnly "com.terraformersmc:modmenu:1.16.8"
modRuntime "com.terraformersmc:modmenu:2.0.0-beta.4"
modCompileOnly "com.terraformersmc:modmenu:2.0.0-beta.4"
}
}
jar {
from(rootProject.file("LICENSE.md")) {
rename { "LICENSE_${project.archivesBaseName.replace('-', '_')}" }
}
}
afterEvaluate {
processResources {
// this will ensure that this task is redone when there"s a change
inputs.property "version", mod_version
@@ -176,12 +185,6 @@ allprojects {
exclude "fabric.mod.json"
}
}
jar {
from(rootProject.file("LICENSE.md")) {
rename { "LICENSE_${project.archivesBaseName.replace('-', '_')}"}
}
}
}
sourceSets {
+4 -7
View File
@@ -1,17 +1,14 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.16.5
yarn_mappings=1.16.5+build.5
loader_version=0.11.2
minecraft_version=21w20a
yarn_mappings=21w20a+build.19
loader_version=0.11.3
# Mod Properties
mod_version=1.0.5
maven_group=draylar
archives_base_name=omega-config
# Dependencies
# check this on https://modmuss50.me/fabric.html
fabric_version=0.32.0+1.16
fabric_version=0.34.6+1.17
@@ -10,8 +10,8 @@ import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
@@ -28,36 +28,33 @@ import java.util.*;
public class OmegaConfig {
private static final Logger LOGGER = LogManager.getLogger();
private static final List<Config> REGISTERED_CONFIGURATIONS = new ArrayList<>();
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static final Identifier CONFIG_SYNC_PACKET = new Identifier("omegaconfig", "sync");
public static final Gson SYNC_ONLY_GSON = new GsonBuilder().addSerializationExclusionStrategy(new SyncableExclusionStrategy()).setPrettyPrinting().create();
private static final Logger LOGGER = LogManager.getLogger();
private static final List<Config> REGISTERED_CONFIGURATIONS = new ArrayList<>();
static {
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
server.execute(() -> {
PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer());
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> server.execute(() -> {
PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer());
// list of configurations that are synced
CompoundTag root = new CompoundTag();
ListTag configurations = new ListTag();
// list of configurations that are synced
NbtCompound root = new NbtCompound();
NbtList configurations = new NbtList();
// Iterate over each configuration.
// Find values that should be synced and send the value over.
OmegaConfig.getRegisteredConfigurations().forEach(config -> {
if(config.hasAnySyncable()) {
configurations.add(config.writeSyncingTag());
}
});
// save to packet and send to user
root.put("Configurations", configurations);
packet.writeCompoundTag(root);
handler.sendPacket(ServerPlayNetworking.createS2CPacket(CONFIG_SYNC_PACKET, packet));
// Iterate over each configuration.
// Find values that should be synced and send the value over.
OmegaConfig.getRegisteredConfigurations().forEach(config -> {
if (config.hasAnySyncable()) {
configurations.add(config.writeSyncingTag());
}
});
});
// save to packet and send to user
root.put("Configurations", configurations);
packet.writeNbt(root);
handler.sendPacket(ServerPlayNetworking.createS2CPacket(CONFIG_SYNC_PACKET, packet));
}));
}
public static <T extends Config> T register(Class<T> configClass) {
@@ -69,7 +66,7 @@ public class OmegaConfig {
// We want to provide access to the config as soon as it is created, so we:
// 1. serialize to disk if the config does not already exist
// 2. read from disk if it does exist
if(!configExists(config)) {
if (!configExists(config)) {
writeConfig(configClass, config);
REGISTERED_CONFIGURATIONS.add(config);
} else {
@@ -99,7 +96,7 @@ public class OmegaConfig {
}
}
public static <T extends Config> void writeConfig(Class<T> configClass, T instance) {
public static <T extends Config> void writeConfig(Class<T> configClass, T instance) {
// Write the config to disk with the default values.
String json = GSON.toJson(instance);
@@ -109,14 +106,14 @@ public class OmegaConfig {
Map<String, String> keyToComments = new HashMap<>();
// populate key -> comments map
for(Field field : configClass.getDeclaredFields()) {
for (Field field : configClass.getDeclaredFields()) {
addFieldComments(field, keyToComments);
}
// get inner-class fields
// TODO: recursively get inner classes?
for(Class<?> innerClass : configClass.getDeclaredClasses()) {
for(Field field : innerClass.getDeclaredFields()) {
for (Class<?> innerClass : configClass.getDeclaredClasses()) {
for (Field field : innerClass.getDeclaredFields()) {
addFieldComments(field, keyToComments);
}
}
@@ -154,7 +151,7 @@ public class OmegaConfig {
Files.write(configPath, res.toString().getBytes());
} catch (IOException ioException) {
LOGGER.error(ioException);
LOGGER.info(String.format("Write error, using default values for config %s.", configClass.toString()));
LOGGER.info(String.format("Write error, using default values for config %s.", configClass));
}
}
@@ -164,7 +161,7 @@ public class OmegaConfig {
// Find comment
for (Annotation annotation : annotations) {
if(annotation instanceof Comment) {
if (annotation instanceof Comment) {
keyToComments.put(fieldName, ((Comment) annotation).value());
break;
}
@@ -179,23 +176,23 @@ public class OmegaConfig {
* "p" -> ""
* " p" -> " "
*
* @param input input to retrieve whitespaces from
* @return starting whitespaces from the given input
* @param input input to retrieve whitespaces from
* @return starting whitespaces from the given input
*/
private static String getStartingWhitespace(String input) {
int index = -1;
char[] chars = input.toCharArray();
for(int i = 0; i < chars.length; i++) {
for (int i = 0; i < chars.length; i++) {
char at = chars[i];
if(at != ' ') {
if (at != ' ') {
index = i;
break;
}
}
if(index != -1) {
if (index != -1) {
return input.substring(0, index);
} else {
return "";
@@ -10,7 +10,7 @@ import java.lang.annotation.Target;
*
* <p>
* When a configuration is serialized, any field elements with the {@link Comment} annotation
* will be prefixed with a // comment on the previous line, with the value specified by this annotation.
* will be prefixed with a // comment on the previous line, with the value specified by this annotation.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@@ -1,7 +1,7 @@
package draylar.omegaconfig.api;
import draylar.omegaconfig.OmegaConfig;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtCompound;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
@@ -16,12 +16,12 @@ public interface Config {
OmegaConfig.writeConfig((Class<Config>) getClass(), this);
}
default CompoundTag writeSyncingTag() {
CompoundTag tag = new CompoundTag();
default NbtCompound writeSyncingTag() {
NbtCompound tag = new NbtCompound();
tag.putString("ConfigName", getName());
// all config vs. individual fields
if(Arrays.stream(getClass().getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
if (Arrays.stream(getClass().getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
// write ALL fields to tag
String json = OmegaConfig.GSON.toJson(this);
tag.putString("Serialized", json);
@@ -37,7 +37,7 @@ public interface Config {
}
/**
* @return true if this {@link Config} has any values that should be synced to the client
* @return true if this {@link Config} has any values that should be synced to the client
*/
default boolean hasAnySyncable() {
boolean hasSyncingField = Arrays.stream(getClass().getDeclaredFields()).anyMatch(field -> Arrays.stream(field.getDeclaredAnnotations()).anyMatch(annotation -> annotation instanceof Syncing));
@@ -55,7 +55,7 @@ public interface Config {
* <li>No special characters ($, %, ^, etc.)
* <li>No spaces
*
* @return the name of this config, which is used for the name of the config file saved to disk.
* @return the name of this config, which is used for the name of the config file saved to disk.
*/
String getName();
@@ -64,14 +64,14 @@ public interface Config {
*
* <p>
* This functionality is used for libraries like ModMenu, which depend on
* modids for configuration screen instances in their menu.
* modids for configuration screen instances in their menu.
* If you are intending for this config to have a ModMenu config
* screen, this method should return the modid specified in your fabric.mod.json.
*
* screen, this method should return the modid specified in your fabric.mod.json.
* <p>
* If this method is not overridden, null will be returned, which
* means this config is not explicitly associated with any particular mod.
* means this config is not explicitly associated with any particular mod.
*
* @return the modid of the mod associated with this config, or null if none was specified
* @return the modid of the mod associated with this config, or null if none was specified
*/
@Nullable
default String getModid() {
@@ -84,9 +84,9 @@ public interface Config {
* <p>
* The file extension is used while serializing this config to a local file.
* The primary use-case of switching this would be supporting existing config files
* when porting from other json5 config libraries.
* when porting from other json5 config libraries.
*
* @return the file extension of this config
* @return the file extension of this config
*/
default String getExtension() {
return "json";
@@ -98,11 +98,11 @@ public interface Config {
* <p>
* By default, a config such as 'my_config' will appear at /config/my_config.json.
* If this method specifies a directory, such as 'configurations',
* the config file will appear at /config/configurations/my_config.json.
*
* the config file will appear at /config/configurations/my_config.json.
* <p>
* Nested directories can be specified by using a string such as 'configurations/client'.
*
* @return the directory of this config
* @return the directory of this config
*/
default String getDirectory() {
return "";
@@ -3,13 +3,12 @@ package draylar.omegaconfig.mixin;
import draylar.omegaconfig.OmegaConfig;
import draylar.omegaconfig.api.Config;
import draylar.omegaconfig.api.Syncing;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.util.NbtType;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.RunArgs;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@@ -29,17 +28,17 @@ public class ClientMixin {
@Inject(
method = "<init>",
at = @At("RETURN"))
at = @At("RETURN"))
private void onReturn(RunArgs args, CallbackInfo ci) {
ClientSidePacketRegistry.INSTANCE.register(OmegaConfig.CONFIG_SYNC_PACKET, (context, buffer) -> {
CompoundTag tag = buffer.readCompoundTag();
ClientPlayNetworking.registerGlobalReceiver(OmegaConfig.CONFIG_SYNC_PACKET, (client, handler, buf, responseSender) -> {
NbtCompound tag = buf.readNbt();
savedClientConfig.clear();
context.getTaskQueue().execute(() -> {
if(tag != null && tag.contains("Configurations")) {
ListTag list = tag.getList("Configurations", NbtType.COMPOUND);
client.execute(() -> {
if (tag != null && tag.contains("Configurations")) {
NbtList list = tag.getList("Configurations", NbtType.COMPOUND);
list.forEach(compound -> {
CompoundTag syncedConfiguration = (CompoundTag) compound;
NbtCompound syncedConfiguration = (NbtCompound) compound;
String name = syncedConfiguration.getString("ConfigName");
String json = syncedConfiguration.getString("Serialized");
boolean allSync = syncedConfiguration.getBoolean("AllSync");
@@ -56,7 +55,7 @@ public class ClientMixin {
// locate all fields that differ between the client and server, assign values from server to client (this will mutate the stored object)
for (Field field : server.getClass().getDeclaredFields()) {
if(allSync || Arrays.stream(field.getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
if (allSync || Arrays.stream(field.getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
try {
field.setAccessible(true);
Object serverValue = field.get(server);
@@ -79,15 +78,15 @@ public class ClientMixin {
@Inject(
method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V",
at = @At("RETURN"))
private void restoreConfigurations(Screen screen, CallbackInfo ci) {
for(Config config : savedClientConfig) {
for(Config potentiallySynced : OmegaConfig.getRegisteredConfigurations()) {
if(config.getName().equals(potentiallySynced.getName())) {
private void restoreConfigurations(CallbackInfo ci) {
for (Config config : savedClientConfig) {
for (Config potentiallySynced : OmegaConfig.getRegisteredConfigurations()) {
if (config.getName().equals(potentiallySynced.getName())) {
boolean allConfigSyncs = Arrays.stream(config.getClass().getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing);
// mutate object in registered configurations
for (Field field : config.getClass().getDeclaredFields()) {
if(allConfigSyncs || Arrays.stream(field.getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
if (allConfigSyncs || Arrays.stream(field.getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
try {
field.setAccessible(true);
Object preSyncValue = field.get(config);
@@ -4,7 +4,6 @@
"package": "draylar.omegaconfig.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
],
"client": [
"ClientMixin"
@@ -12,11 +12,12 @@ public class OmegaConfigGui {
/**
* Registers a ModMenu configuration screen for the given {@link Config} instance.
* @param config registered config to create a ModMenu screen for
* @param <T> config type
*
* @param config registered config to create a ModMenu screen for
* @param <T> config type
*/
public static <T extends Config> void registerConfigScreen(T config) {
if(FabricLoader.getInstance().isModLoaded("modmenu")) {
if (FabricLoader.getInstance().isModLoaded("modmenu")) {
ModMenuHelper.injectScreen(config, parent -> new OmegaConfigScreen<>(config, parent));
}
}
@@ -5,19 +5,16 @@ import draylar.omegaconfig.api.Config;
import draylar.omegaconfiggui.api.screen.widget.LabelWidget;
import draylar.omegaconfiggui.api.screen.widget.TypeWidgets;
import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Drawable;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
import java.lang.reflect.Field;
@@ -32,7 +29,7 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
private static final List<Class<?>> validClasses = Arrays.asList(Double.class, String.class, Boolean.class);
private final T config;
private final Screen parent;
private final Map<Field, Pair<WidgetSupplier<Object, AbstractButtonWidget>, AbstractButtonWidget>> fieldWidgets = new HashMap<>();
private final Map<Field, Pair<WidgetSupplier<Object, ClickableWidget>, ClickableWidget>> fieldWidgets = new HashMap<>();
public OmegaConfigScreen(T config, Screen parent) {
super(new LiteralText(""));
@@ -54,24 +51,24 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
Class<?> unbox = TypeWidgets.unbox(field.getType());
// label
addChild(new LabelWidget(150, 15 + height / 6 + 20 * over, new LiteralText(field.getName())));
addDrawable(new LabelWidget(150, 15 + height / 6 + 20 * over, new LiteralText(field.getName())));
// get value
field.setAccessible(true);
Object value = field.get(config);
// button / interact
AbstractButtonWidget button;
WidgetSupplier<Object, AbstractButtonWidget> widgetSupplier = (WidgetSupplier<Object, AbstractButtonWidget>) TypeWidgets.get(unbox);
if(widgetSupplier != null) {
button = widgetSupplier.create(this,250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName()), value);
ClickableWidget button;
WidgetSupplier<Object, ClickableWidget> widgetSupplier = (WidgetSupplier<Object, ClickableWidget>) TypeWidgets.get(unbox);
if (widgetSupplier != null) {
button = widgetSupplier.create(this, 250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName()), value);
} else {
button = new TextFieldWidget(client.textRenderer, 250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName()));
}
fieldWidgets.put(field, new Pair<>(widgetSupplier, button));
addButton(button);
addSelectableChild(button);
over++;
}
@@ -92,15 +89,17 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
config.save();
});
addButton(save);
addButton(exit);
addSelectableChild(save);
addSelectableChild(exit);
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
renderBackground(matrices);
for (AbstractButtonWidget button : this.buttons) {
//TODO make this work. for Drawables (children) it works in parent method
/*
for (ClickableWidget button : this.) {
button.render(matrices, mouseX, mouseY, delta);
}
@@ -109,6 +108,8 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
((Drawable) element).render(matrices, mouseX, mouseY, delta);
}
}
*/
}
@Override
@@ -129,13 +130,13 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
this.client.getTextureManager().bindTexture(OPTIONS_BACKGROUND_TEXTURE);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
bufferBuilder.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
bufferBuilder.vertex(x, height + y, 0.0D).texture(0.0F, (float)height / 32.0F + (float)vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(width + x, height + y, 0.0D).texture((float)width / 32.0F, (float)height / 32.0F + (float)vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(width + x, y, 0.0D).texture((float)width / 32.0F, (float)vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(x, y, 0.0D).texture(0.0F, (float)vOffset).color(r, g, b, 255).next();
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
bufferBuilder.vertex(x, height + y, 0.0D).texture(0.0F, (float) height / 32.0F + (float) vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(width + x, height + y, 0.0D).texture((float) width / 32.0F, (float) height / 32.0F + (float) vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(width + x, y, 0.0D).texture((float) width / 32.0F, (float) vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(x, y, 0.0D).texture(0.0F, (float) vOffset).color(r, g, b, 255).next();
tessellator.draw();
}
}
@@ -1,9 +1,9 @@
package draylar.omegaconfiggui.api.screen.widget;
import draylar.omegaconfiggui.mixin.AbstractButtonWidgetAccessor;
import draylar.omegaconfiggui.mixin.ClickableWidgetInvoker;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text;
@@ -20,8 +20,8 @@ public class BaseTextFieldWidget extends TextFieldWidget {
public void setTextFieldFocused(boolean focused) {
// unfocus all others
parent.children().forEach(element -> {
if(element instanceof AbstractButtonWidget) {
((AbstractButtonWidgetAccessor) element).callSetFocused(false);
if (element instanceof ClickableWidget) {
((ClickableWidgetInvoker) element).callSetFocused(false);
}
});
@@ -13,14 +13,12 @@ public class DoubleFieldWidget extends BaseTextFieldWidget {
@Override
public void write(String string) {
try {
if(string.equals(".") && !getText().contains(".")) {
super.write(string);
} else {
if (!string.equals(".") || getText().contains(".")) {
Double.parseDouble(string);
super.write(string);
}
super.write(string);
} catch(NumberFormatException ignored) {
} catch (NumberFormatException ignored) {
}
}
@@ -30,6 +30,10 @@ public class TypeWidgets {
PRIMITIVE_TO_BOXED.put(void.class, Void.class);
}
private TypeWidgets() {
// NO-OP
}
@Nullable
public static <T> WidgetSupplier<T, ?> get(Class<T> typeClass) {
return (WidgetSupplier<T, ?>) CLASS_WIDGETS.get(unbox(typeClass));
@@ -38,8 +42,4 @@ public class TypeWidgets {
public static Class<?> unbox(Class<?> c) {
return PRIMITIVE_TO_BOXED.getOrDefault(c, c);
}
private TypeWidgets() {
// NO-OP
}
}
@@ -1,10 +1,11 @@
package draylar.omegaconfiggui.api.screen.widget;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.text.LiteralText;
public interface WidgetSupplier<T, A extends AbstractButtonWidget> {
AbstractButtonWidget create(Screen parent, int x, int y, int width, int height, LiteralText prompt, T value);
public interface WidgetSupplier<T, A extends ClickableWidget> {
ClickableWidget create(Screen parent, int x, int y, int width, int height, LiteralText prompt, T value);
T get(A widget);
}
@@ -21,12 +21,12 @@ public class DoubleWidgetSupplier implements WidgetSupplier<Double, DoubleFieldW
String message = widget.getText();
// if it is just a . or empty, return 0
if(message.equals(".") || message.isEmpty()) {
if (message.equals(".") || message.isEmpty()) {
return 0.0;
}
// trim potential trailing .
if(message.indexOf(".") == message.length()) {
if (message.indexOf(".") == message.length()) {
message = message.substring(0, message.length() - 1);
}
@@ -4,7 +4,6 @@ import draylar.omegaconfiggui.api.screen.widget.BaseTextFieldWidget;
import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.LiteralText;
@@ -1,11 +1,11 @@
package draylar.omegaconfiggui.mixin;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(AbstractButtonWidget.class)
public interface AbstractButtonWidgetAccessor {
@Mixin(ClickableWidget.class)
public interface ClickableWidgetInvoker {
@Invoker
void callSetFocused(boolean focused);
}
@@ -4,7 +4,7 @@
"package": "draylar.omegaconfiggui.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
"AbstractButtonWidgetAccessor",
"ClickableWidgetInvoker",
"ModMenuAccessor"
],
"client": [
@@ -3,8 +3,8 @@ package draylar.omegatest;
import draylar.omegaconfig.OmegaConfig;
import draylar.omegatest.config.ClassConfigTest;
import draylar.omegatest.config.NestedConfigTest;
import draylar.omegatest.config.StructuresConfigTest;
import draylar.omegatest.config.SimpleConfigTest;
import draylar.omegatest.config.StructuresConfigTest;
import net.fabricmc.api.ModInitializer;
public class OmegaTestMain implements ModInitializer {
@@ -19,12 +19,6 @@ public class SimpleConfigTest implements Config {
@Comment(value = "This is an inner static class.")
public Test test = new Test();
public static class Test {
@Comment(value = "This is the value inside the class!")
public boolean innerTest = false;
}
@Override
public String getName() {
return "test-config";
@@ -34,4 +28,10 @@ public class SimpleConfigTest implements Config {
public @Nullable String getModid() {
return "omega-config-test";
}
public static class Test {
@Comment(value = "This is the value inside the class!")
public boolean innerTest = false;
}
}
@@ -21,6 +21,11 @@ public class StructuresConfigTest implements Config {
return "mostructures-config-v2";
}
@Override
public String getExtension() {
return "json5";
}
public static class Features {
@Comment("Airplanes & Air Balloons")
public boolean air_features = true;
@@ -123,9 +128,4 @@ public class StructuresConfigTest implements Config {
public int killer_bunny_castle_seperation = 25;
public int killer_bunny_castle_spacing = 50;
}
@Override
public String getExtension() {
return "json5";
}
}