ill try smth
This commit is contained in:
parent
77decae10c
commit
a365f70873
28 changed files with 433 additions and 96 deletions
|
|
@ -5,14 +5,23 @@ import org.jetbrains.annotations.Nullable;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class AbstractStorable<T> implements Storable<T> {
|
||||
private final List<ValueChangeSubscriber> subscribers = new ArrayList<>();
|
||||
@Nullable
|
||||
private final Supplier<T> defaultValue;
|
||||
protected T value = null;
|
||||
|
||||
private final List<ValueRequirement<T>> requirements = new ArrayList<>();
|
||||
|
||||
protected AbstractStorable(Supplier<T> defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
protected AbstractStorable(T defaultValue) {
|
||||
this(() -> defaultValue);
|
||||
}
|
||||
|
||||
protected void requireValue(Predicate<T> predicate, String error) {
|
||||
requirements.add(new ValueRequirement<>(predicate, error));
|
||||
}
|
||||
|
|
@ -29,7 +38,7 @@ public abstract class AbstractStorable<T> implements Storable<T> {
|
|||
|
||||
@Override
|
||||
public void value(@Nullable T value) {
|
||||
this.value = value;
|
||||
this.value = value != null ? value : defaultValue.get();
|
||||
subscribers.forEach(ValueChangeSubscriber::notifyValueChange);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,15 @@ import com.google.gson.JsonElement;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class WrappedStorable<R, T> extends AbstractStorable<T> {
|
||||
|
||||
private final Storable<R> realStorable;
|
||||
private boolean skipUpdates = false;
|
||||
|
||||
public WrappedStorable(Storable<R> realStorable) {
|
||||
public WrappedStorable(Storable<R> realStorable, Supplier<T> defaultValue) {
|
||||
super(defaultValue);
|
||||
this.realStorable = realStorable;
|
||||
realStorable.subscribe(() -> {
|
||||
if (realStorable.value() == null)
|
||||
|
|
@ -20,16 +22,25 @@ public abstract class WrappedStorable<R, T> extends AbstractStorable<T> {
|
|||
});
|
||||
}
|
||||
|
||||
public WrappedStorable(Storable<R> realStorable, T defaultValue) {
|
||||
this(realStorable, () -> defaultValue);
|
||||
}
|
||||
|
||||
abstract protected T wrap(R real);
|
||||
|
||||
abstract protected R unwrap(T value);
|
||||
|
||||
@Override
|
||||
public void value(@Nullable T value) {
|
||||
if (skipUpdates)
|
||||
return;
|
||||
super.value(value);
|
||||
skipUpdates(() -> realStorable.value(value == null ? null : unwrap(value)));
|
||||
if (skipUpdates) return;
|
||||
|
||||
try {
|
||||
skipUpdates = true;
|
||||
realStorable.value(value != null ? unwrap(value) : null);
|
||||
} finally {
|
||||
skipUpdates = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -51,16 +62,4 @@ public abstract class WrappedStorable<R, T> extends AbstractStorable<T> {
|
|||
public @Nullable Storable<?> getSubField(String name) {
|
||||
return realStorable.getSubField(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run action without updating the value
|
||||
*/
|
||||
private void skipUpdates(Action action) {
|
||||
try {
|
||||
skipUpdates = true;
|
||||
action.apply();
|
||||
} finally {
|
||||
skipUpdates = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@ package site.lab0x13.scrow.configurator.storable.complex;
|
|||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import site.lab0x13.scrow.configurator.storable.Storable;
|
||||
|
||||
public abstract class ComplexStorable<T> extends SubFieldedStorable<T> {
|
||||
|
||||
@Override
|
||||
protected @Nullable T defaultValue() {
|
||||
return null;
|
||||
protected ComplexStorable(T defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -24,6 +22,10 @@ public abstract class ComplexStorable<T> extends SubFieldedStorable<T> {
|
|||
|
||||
@Override
|
||||
public void loadJson(JsonElement json) {
|
||||
if (json == null) {
|
||||
value(null);
|
||||
return;
|
||||
}
|
||||
var obj = json.getAsJsonObject();
|
||||
skipUpdates(() -> fieldRegistry().subFields().forEach((subFieldName, subField) ->
|
||||
subField.storable().loadJson(obj.get(subFieldName))));
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ public class FieldRegistry<T> {
|
|||
|
||||
private final Map<String, Field<T, ?>> subFields = new HashMap<>();
|
||||
|
||||
// TODO move field stuff into own class where register field is one block and after that ready is called
|
||||
public <S> void registerField(String name, Storable<S> storable, Function<T, S> getter) {
|
||||
subFields.put(name, new Field<>(storable, getter));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ public abstract class SubFieldedStorable<T> extends AbstractStorable<T> {
|
|||
private final FieldRegistry<T> fieldRegistry = new FieldRegistry<>();
|
||||
private boolean skipUpdates = false;
|
||||
|
||||
public SubFieldedStorable() {
|
||||
public SubFieldedStorable(T defaultValue) {
|
||||
super(defaultValue);
|
||||
this.registerFields(fieldRegistry);
|
||||
fieldRegistry.subFields().values().forEach(f -> f.storable().subscribe(this::updateValue));
|
||||
}
|
||||
|
|
@ -22,8 +23,6 @@ public abstract class SubFieldedStorable<T> extends AbstractStorable<T> {
|
|||
|
||||
protected abstract T construct(FieldReader<T> reader);
|
||||
|
||||
protected abstract @Nullable T defaultValue();
|
||||
|
||||
/**
|
||||
* Run action without updating the value
|
||||
*/
|
||||
|
|
@ -44,17 +43,16 @@ public abstract class SubFieldedStorable<T> extends AbstractStorable<T> {
|
|||
|
||||
@Override
|
||||
public void value(@Nullable T value) {
|
||||
if (value == null) {
|
||||
super.value(defaultValue());
|
||||
return;
|
||||
}
|
||||
super.value(value);
|
||||
|
||||
// reflect value change no sub fields
|
||||
skipUpdates(() -> fieldRegistry.subFields().values().forEach(_field -> {
|
||||
var field = (Field<T, Object>) _field;
|
||||
field.storable().value(field.getter().apply(value));
|
||||
}));
|
||||
if (value == null) {
|
||||
// reset if null
|
||||
skipUpdates(() -> fieldRegistry.subFields().values().forEach(f -> f.storable().value(null)));
|
||||
} else {
|
||||
skipUpdates(() -> fieldRegistry.subFields().values().forEach(_field -> {
|
||||
var field = (Field<T, Object>) _field;
|
||||
field.storable().value(field.getter().apply(value));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package site.lab0x13.scrow.configurator.storable.impl;
|
||||
|
||||
import site.lab0x13.scrow.configurator.storable.complex.ComplexStorable;
|
||||
import site.lab0x13.scrow.configurator.storable.complex.FieldReader;
|
||||
import site.lab0x13.scrow.configurator.storable.complex.FieldRegistry;
|
||||
import site.lab0x13.scrow.configurator.storable.primitive.IntStorable;
|
||||
import site.lab0x13.scrow.configurator.storable.primitive.LongStorable;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class DurationStorable extends ComplexStorable<Duration> {
|
||||
|
||||
@Override
|
||||
protected void registerFields(FieldRegistry<Duration> registry) {
|
||||
registry.registerField("seconds", new LongStorable(), Duration::getSeconds);
|
||||
registry.registerField("nanos", new IntStorable(), Duration::getNano);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Duration construct(FieldReader<Duration> reader) {
|
||||
return Duration.ofSeconds(reader.read("seconds"), reader.read("nanos"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package site.lab0x13.scrow.configurator.storable.impl;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import site.lab0x13.scrow.configurator.storable.WrappedStorable;
|
||||
import site.lab0x13.scrow.configurator.storable.primitive.StringStorable;
|
||||
|
||||
public class MiniMessageStorable extends WrappedStorable<String, Component> {
|
||||
|
||||
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||
|
||||
public MiniMessageStorable() {
|
||||
super(new StringStorable());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Component wrap(String real) {
|
||||
return miniMessage.deserialize(real);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String unwrap(Component value) {
|
||||
return miniMessage.serialize(value);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,8 @@ public class LocationStorable extends ComplexStorable<Location> {
|
|||
|
||||
private final List<StorableAction<?, ?>> actions;
|
||||
|
||||
public LocationStorable() {
|
||||
public LocationStorable(Location defaultValue) {
|
||||
super(defaultValue);
|
||||
actions = new ArrayList<>(super.actions());
|
||||
actions.add(new LocationPickCurrentAction());
|
||||
actions.add(new LocationTeleportAction());
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ import site.lab0x13.scrow.configurator.storable.Storable;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.util.Objects.*;
|
||||
|
||||
class LocationTeleportAction implements StorableAction<Location, Storable<Location>> {
|
||||
|
||||
|
|
@ -28,8 +31,7 @@ class LocationTeleportAction implements StorableAction<Location, Storable<Locati
|
|||
|
||||
@Override
|
||||
public void execute(Storable<Location> node, ScrowBukkitCC ctx) {
|
||||
assert node.value() != null;
|
||||
ctx.player().teleport(node.value());
|
||||
ctx.player().teleport(requireNonNull(node.value()));
|
||||
ctx.player().sendMessage(ctx.style().ok("You've been teleported."));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ public class WorldStorable extends WrappedStorable<String, World> {
|
|||
|
||||
private final List<StorableAction<?, ?>> actions;
|
||||
|
||||
public WorldStorable() {
|
||||
super(new StringStorable());
|
||||
public WorldStorable(World defaultValue) {
|
||||
super(new StringStorable(), defaultValue);
|
||||
actions = new ArrayList<>(super.actions());
|
||||
actions.add(new SetWorldAction());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package site.lab0x13.scrow.configurator.storable.impl.list;
|
||||
package site.lab0x13.scrow.configurator.storable.list;
|
||||
|
||||
import de.kentoj.scrow.bukkit.command.ScrowBukkitCC;
|
||||
import site.lab0x13.scrow.commands.model.argument.Argument;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package site.lab0x13.scrow.configurator.storable.impl.list;
|
||||
package site.lab0x13.scrow.configurator.storable.list;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
|
|
@ -9,19 +9,21 @@ import site.lab0x13.scrow.configurator.storable.AbstractStorable;
|
|||
import site.lab0x13.scrow.configurator.storable.Storable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class ListStorable<S extends Storable<?>> extends AbstractStorable<List<S>> {
|
||||
public class ListStorable<S> extends AbstractStorable<List<S>> {
|
||||
|
||||
private final Supplier<S> newElementSupplier;
|
||||
private final Supplier<Storable<S>> newElementSupplier;
|
||||
private final List<StorableAction<?, ?>> actions;
|
||||
|
||||
public ListStorable(Supplier<S> newElementSupplier) {
|
||||
private final List<Storable<S>> _value = new ArrayList<>();
|
||||
|
||||
public ListStorable(Supplier<Storable<S>> newElementSupplier) {
|
||||
super(new ArrayList<>());
|
||||
this.newElementSupplier = newElementSupplier;
|
||||
actions = super.actions();
|
||||
actions.add(new ListExpandAction<>());
|
||||
|
|
@ -32,51 +34,42 @@ public class ListStorable<S extends Storable<?>> extends AbstractStorable<List<S
|
|||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<S> value() {
|
||||
var v = super.value();
|
||||
if (v == null) {
|
||||
v = new ArrayList<>();
|
||||
value(v);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands the list with a default value storable
|
||||
*/
|
||||
public S expandList() {
|
||||
public Storable<S> expandList() {
|
||||
var newElement = newElementSupplier.get();
|
||||
requireNonNull(value()).add(newElement);
|
||||
newElement.subscribe(() -> value(_value.stream().map(Storable::value).toList()));
|
||||
_value.add(newElement);
|
||||
return newElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJson() {
|
||||
var out = new JsonArray();
|
||||
requireNonNull(value()).forEach(storable -> out.add(storable.toJson()));
|
||||
_value.forEach(storable -> out.add(storable.toJson()));
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadJson(JsonElement json) {
|
||||
if (json == null) {
|
||||
_value.clear();
|
||||
return;
|
||||
}
|
||||
var in = json.getAsJsonArray();
|
||||
in.forEach(jsonElement -> expandList().loadJson(jsonElement));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> subFieldNames() {
|
||||
var v = value();
|
||||
if (v == null) return Collections.emptyList();
|
||||
return IntStream.range(0, v.size())
|
||||
return IntStream.range(0, _value.size())
|
||||
.mapToObj(Integer::toString)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Storable<?> getSubField(String name) {
|
||||
var v = value();
|
||||
if (v == null) return null;
|
||||
return v.get(Integer.parseInt(name));
|
||||
return _value.get(Integer.parseInt(name));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package site.lab0x13.scrow.configurator.storable.primitive;
|
||||
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
public class LongStorable extends PrimitiveStorable<Long> {
|
||||
public LongStorable() {
|
||||
super(0L, JsonPrimitive::new, JsonPrimitive::getAsLong);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ public class PrimitiveStorable<V> extends AbstractStorable<V> {
|
|||
|
||||
@Override
|
||||
public void loadJson(JsonElement json) {
|
||||
if (json.isJsonNull())
|
||||
if (json == null || json.isJsonNull())
|
||||
value(defaultValue);
|
||||
else
|
||||
value(deserializer.apply(json.getAsJsonPrimitive()));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue