feat: add support for whole numbers
This commit is contained in:
parent
e34c0752b9
commit
b3e8cc22cf
|
@ -80,7 +80,12 @@ Corresponds to version 4.4.0
|
|||
- Stricter enforcement of legal entry names: instead of sanitization, unsupported names are logged and ignored
|
||||
|
||||
## v11
|
||||
Corresponds to version 4.5.0
|
||||
Corresponds to version 4.5.0-4.5.1
|
||||
|
||||
- Directory RPOs in subdirectories are respected. Previously, only the innermost directory RPO would be used
|
||||
- Multiple replacements when resolving fallbacks for directory RPOs are prevented
|
||||
- Multiple replacements when resolving fallbacks for directory RPOs are prevented
|
||||
|
||||
## v12
|
||||
Corresponds to version 4.6.0
|
||||
|
||||
- Support for whole numbers (not integers!)
|
|
@ -13,20 +13,26 @@ Every entry can contain the following properties, regardless of its type:
|
|||
## Numbers
|
||||
There are two ways to display numbers: input boxes and sliders.
|
||||
Any number input that provides a minimum and maximum value will be displayed as a slider instead of a box.
|
||||
Their type is `number` for fractions and `integer` for whole numbers.
|
||||
|
||||
### Example:
|
||||
|
||||
```json
|
||||
{
|
||||
id: "examplePack",
|
||||
version: 9,
|
||||
capabilities: ["FileFilter", "DirFilter"],
|
||||
conf: {
|
||||
someOption: {
|
||||
default: 5,
|
||||
min: 0,
|
||||
max: 10
|
||||
}
|
||||
id: "examplePack",
|
||||
version: 9,
|
||||
capabilities: [
|
||||
"FileFilter",
|
||||
"DirFilter"
|
||||
],
|
||||
conf: {
|
||||
someOption: {
|
||||
type: "number",
|
||||
default: 5,
|
||||
min: 0,
|
||||
max: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
### Result:
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.util.concurrent.CompletableFuture;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
public class Respackopts implements ModInitializer, SaveHook {
|
||||
public static final Integer META_VERSION = 11;
|
||||
public static final Integer META_VERSION = 12;
|
||||
public static final String FILE_EXTENSION = ".rpo";
|
||||
public static final Gson GSON = new GsonBuilder()
|
||||
.registerTypeAdapter(ConfigEnumEntry.class, new EnumEntrySerializer())
|
||||
|
|
|
@ -56,6 +56,7 @@ public class ConfigBranchSerializer implements JsonSerializer<ConfigBranch>, Jso
|
|||
}
|
||||
ConfigEntry<?> entry = switch (type.toLowerCase()) {
|
||||
case "slider", "number", "numeric" -> context.deserialize(j, ConfigNumericEntry.class);
|
||||
case "integer", "int", "long", "whole" -> context.<ConfigNumericEntry>deserialize(j, ConfigNumericEntry.class).asInteger();
|
||||
case "boolean", "toggle" -> context.deserialize(j, ConfigBooleanEntry.class);
|
||||
case "enum", "select" -> context.deserialize(j, ConfigEnumEntry.class);
|
||||
default -> throw new JsonSyntaxException("Unknown entry type: " + type);
|
||||
|
|
|
@ -25,13 +25,13 @@ public class NumericEntrySerializer implements JsonSerializer<ConfigNumericEntry
|
|||
JsonElement max = o.get("max");
|
||||
if (min != null) {
|
||||
if (min.isJsonPrimitive() && min.getAsJsonPrimitive().isNumber()) {
|
||||
result.min = min.getAsNumber().doubleValue();
|
||||
result.setMin(min.getAsNumber().doubleValue());
|
||||
}
|
||||
else throw new JsonSyntaxException("Expected number as min of numeric entry");
|
||||
}
|
||||
if (max != null) {
|
||||
if (max.isJsonPrimitive() && max.getAsJsonPrimitive().isNumber()) {
|
||||
result.max = max.getAsNumber().doubleValue();
|
||||
result.setMax(max.getAsNumber().doubleValue());
|
||||
}
|
||||
else throw new JsonSyntaxException("Expected number as max of numeric entry");
|
||||
}
|
||||
|
|
|
@ -10,16 +10,44 @@ import io.gitlab.jfronny.respackopts.util.IndentingStringBuilder;
|
|||
import java.util.Objects;
|
||||
|
||||
public class ConfigNumericEntry extends ConfigEntry<Double> implements DNumber {
|
||||
public Double min = null;
|
||||
public Double max = null;
|
||||
private Double min = null;
|
||||
private Double max = null;
|
||||
private boolean integer = false;
|
||||
|
||||
public ConfigNumericEntry() {
|
||||
super(Double.class);
|
||||
setValue(0d);
|
||||
}
|
||||
|
||||
public ConfigNumericEntry asInteger() {
|
||||
this.integer = true;
|
||||
if (min != null && (min % 1.0 != 0)) {
|
||||
this.integer = false;
|
||||
throw new RuntimeException("Minimum value (" + min + ") is not integer for integer entry");
|
||||
}
|
||||
if (max != null && (max % 1.0 != 0)) {
|
||||
this.integer = false;
|
||||
throw new RuntimeException("Minimum value (" + max + ") is not integer for integer entry");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setMin(Double value) {
|
||||
if (value != null && integer && (value % 1.0 != 0))
|
||||
throw new RuntimeException("Minimum value (" + value + ") is not integer for integer entry");
|
||||
this.min = value;
|
||||
}
|
||||
|
||||
public void setMax(Double value) {
|
||||
if (value != null && integer && (value % 1.0 != 0))
|
||||
throw new RuntimeException("Maximum value (" + value + ") is not integer for integer entry");
|
||||
this.max = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double setDefault(Double value) {
|
||||
if (integer && (value % 1.0 != 0))
|
||||
throw new RuntimeException("Default value (" + value + ") is not integer for integer entry");
|
||||
if ((min != null && value < min) || (max != null && value > max))
|
||||
throw new RuntimeException("Default value (" + value + ") out of range in number entry definition (" + min + "-" + max + ")");
|
||||
return super.setDefault(value);
|
||||
|
@ -30,26 +58,25 @@ public class ConfigNumericEntry extends ConfigEntry<Double> implements DNumber {
|
|||
super.sync(source, mode);
|
||||
ConfigNumericEntry n = (ConfigNumericEntry) source;
|
||||
if (mode == ConfigSyncMode.RESPACK_LOAD) {
|
||||
if (n.min != null)
|
||||
min = n.min;
|
||||
if (n.max != null)
|
||||
max = n.max;
|
||||
min = n.min;
|
||||
max = n.max;
|
||||
integer = n.integer;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendString(IndentingStringBuilder sb) {
|
||||
sb.line(getValue() + " (" + getDefault() + ", " + min + "-" + max + ")");
|
||||
sb.line(getValue() + " (" + getDefault() + ", " + min + "-" + max + (integer ? ", integer" : "") + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigEntry<Double> clone() {
|
||||
ConfigNumericEntry ce = new ConfigNumericEntry();
|
||||
ce.max = max;
|
||||
ce.min = min;
|
||||
ce.setMax(max);
|
||||
ce.setMin(min);
|
||||
ce.setValue(getValue());
|
||||
ce.setDefault(getDefault());
|
||||
return ce;
|
||||
return integer ? ce.asInteger() : ce;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,13 +89,43 @@ public class ConfigNumericEntry extends ConfigEntry<Double> implements DNumber {
|
|||
|
||||
@Override
|
||||
public CategoryBuilder<?> buildEntry(GuiEntryBuilderParam args) {
|
||||
return args.builder().value(args.name(), getDefault(), min == null ? Double.NEGATIVE_INFINITY : min, max == null ? Double.POSITIVE_INFINITY : max, this::getValue, v -> {
|
||||
if (!Objects.equals(getValue(), v)) {
|
||||
if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.info("ConfigNumericEntryNormal SaveCallback");
|
||||
args.saveCallback();
|
||||
}
|
||||
setValue(v);
|
||||
});
|
||||
double min = this.min == null ? Double.NEGATIVE_INFINITY : this.min;
|
||||
double max = this.max == null ? Double.NEGATIVE_INFINITY : this.max;
|
||||
if (integer) {
|
||||
return args.builder().value(
|
||||
args.name(),
|
||||
asLong(getDefault()),
|
||||
min,
|
||||
max,
|
||||
() -> asLong(getValue()),
|
||||
v -> {
|
||||
if (!Objects.equals(asLong(getValue()), v)) {
|
||||
if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.info("ConfigNumericEntryNormal SaveCallback");
|
||||
args.saveCallback();
|
||||
}
|
||||
setValue(v == null ? null : v.doubleValue());
|
||||
}
|
||||
);
|
||||
} else {
|
||||
return args.builder().value(
|
||||
args.name(),
|
||||
getDefault(),
|
||||
min,
|
||||
max,
|
||||
this::getValue,
|
||||
v -> {
|
||||
if (!Objects.equals(getValue(), v)) {
|
||||
if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.info("ConfigNumericEntryNormal SaveCallback");
|
||||
args.saveCallback();
|
||||
}
|
||||
setValue(v);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static Long asLong(Double d) {
|
||||
return d == null ? null : d.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,11 +133,15 @@ public class ConfigNumericEntry extends ConfigEntry<Double> implements DNumber {
|
|||
if (this == o) return true;
|
||||
if (!(o instanceof ConfigNumericEntry that)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
return Objects.equals(getValue(), that.getValue()) && Objects.equals(getDefault(), that.getDefault()) && Objects.equals(min, that.min) && Objects.equals(max, that.max);
|
||||
return Objects.equals(getValue(), that.getValue())
|
||||
&& Objects.equals(getDefault(), that.getDefault())
|
||||
&& Objects.equals(min, that.min)
|
||||
&& Objects.equals(max, that.max)
|
||||
&& integer == that.integer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), getValue(), getDefault(), min, max);
|
||||
return Objects.hash(super.hashCode(), getValue(), getDefault(), min, max, integer);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue