diff --git a/src/main/java/dev/lukebemish/codecextras/mutable/DataElementType.java b/src/main/java/dev/lukebemish/codecextras/mutable/DataElementType.java index e37cfca..030acae 100644 --- a/src/main/java/dev/lukebemish/codecextras/mutable/DataElementType.java +++ b/src/main/java/dev/lukebemish/codecextras/mutable/DataElementType.java @@ -1,24 +1,24 @@ package dev.lukebemish.codecextras.mutable; -import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.Dynamic; import com.mojang.serialization.JsonOps; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.lukebemish.codecextras.Asymmetry; + import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; public interface DataElementType { DataElement from(D data); Codec codec(); - DataElement create(); + String name(); - static DataElementType defaulted(Codec codec, T defaultValue, Function> getter) { + static DataElementType defaulted(String name, Codec codec, Function> getter) { return new DataElementType<>() { @Override public DataElement from(D data) { @@ -31,21 +31,29 @@ public Codec codec() { } @Override - public DataElement create() { - return new DataElement.Simple<>(defaultValue); + public String name() { + return name; } }; } - static Codec, D>> codec(List> elements, boolean encodeAll) { - MapCodec>> partial = RecordCodecBuilder.mapCodec(i -> i.group( - Codec.INT.fieldOf("index").forGetter(Pair::getFirst), - Codec.PASSTHROUGH.fieldOf("value").forGetter(Pair::getSecond) - ).apply(i, Pair::of)); + @SafeVarargs + static Codec, D>> codec(boolean encodeAll, DataElementType... elements) { + List> list = List.of(elements); + return codec(encodeAll, list); + } + + static Codec, D>> codec(boolean encodeAll, List> elements) { + Map> elementTypeMap = new HashMap<>(); + for (var element : elements) { + elementTypeMap.put(element.name(), element); + } + + Codec>> partial = Codec.unboundedMap(Codec.STRING, Codec.PASSTHROUGH); return Asymmetry.flatSplit( - partial.codec().listOf(), - list -> { + partial, + map -> { record Mutation(DataElementType element, T value) { private static DataResult> of(DataElementType type, Dynamic dynamic) { return type.codec().parse(dynamic).map(value -> new Mutation<>(type, value)); @@ -57,13 +65,13 @@ public void set(D data) { } List> mutations = new ArrayList<>(); - for (var pair : list) { - int index = pair.getFirst(); - if (index < 0 || index >= elements.size()) { - return DataResult.error(() -> "Invalid index for DataElementType: " + index); + for (var pair : map.entrySet()) { + String name = pair.getKey(); + var type = elementTypeMap.get(name); + if (type == null) { + return DataResult.error(() -> "Invalid name for DataElementType: " + name); } - var type = elements.get(index); - var mutation = Mutation.of(type, pair.getSecond()); + var mutation = Mutation.of(type, pair.getValue()); if (mutation.error().isPresent()) { return DataResult.error(mutation.error().get().messageSupplier()); } @@ -77,20 +85,19 @@ public void set(D data) { }); }, data -> { - List>> list = new ArrayList<>(); - for (int i = 0; i < elements.size(); i++) { - var type = elements.get(i); + Map> map = new HashMap<>(); + for (DataElementType type : elements) { var element = type.from(data); if (encodeAll || element.dirty()) { var result = forElement(type, data); if (result.result().isPresent()) { - list.add(Pair.of(i, result.result().get())); + map.put(type.name(), result.result().get()); } else { - return DataResult.error(result.error().get().messageSupplier(), list); + return DataResult.error(result.error().get().messageSupplier(), map); } } } - return DataResult.success(list); + return DataResult.success(map); } ); } diff --git a/src/main/java/dev/lukebemish/codecextras/mutable/package-info.java b/src/main/java/dev/lukebemish/codecextras/mutable/package-info.java index d198e0a..9b0bc5a 100644 --- a/src/main/java/dev/lukebemish/codecextras/mutable/package-info.java +++ b/src/main/java/dev/lukebemish/codecextras/mutable/package-info.java @@ -1,4 +1,6 @@ @NullMarked +@ApiStatus.Experimental package dev.lukebemish.codecextras.mutable; +import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; diff --git a/src/stream/java/dev/lukebemish/codecextras/stream/mutable/StreamDataElementType.java b/src/stream/java/dev/lukebemish/codecextras/stream/mutable/StreamDataElementType.java index 7b437a5..213e1aa 100644 --- a/src/stream/java/dev/lukebemish/codecextras/stream/mutable/StreamDataElementType.java +++ b/src/stream/java/dev/lukebemish/codecextras/stream/mutable/StreamDataElementType.java @@ -6,17 +6,18 @@ import dev.lukebemish.codecextras.mutable.DataElement; import dev.lukebemish.codecextras.mutable.DataElementType; import io.netty.handler.codec.DecoderException; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; + import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.codec.StreamCodec; public interface StreamDataElementType extends DataElementType { StreamCodec streamCodec(); - static StreamDataElementType defaulted(Codec codec, StreamCodec streamCodec, T defaultValue, Function> getter) { + static StreamDataElementType defaulted(String name, Codec codec, StreamCodec streamCodec, Function> getter) { return new StreamDataElementType<>() { @Override public StreamCodec streamCodec() { @@ -34,13 +35,19 @@ public Codec codec() { } @Override - public DataElement create() { - return new DataElement.Simple<>(defaultValue); + public String name() { + return name; } }; } - static StreamCodec, D>> streamCodec(List> elements, boolean encodeAll) { + @SafeVarargs + static StreamCodec, D>> streamCodec(boolean encodeAll, StreamDataElementType... elements) { + List> list = List.of(elements); + return streamCodec(encodeAll, list); + } + + static StreamCodec, D>> streamCodec(boolean encodeAll, List> elements) { return StreamCodec.of((buffer, asymmetry) -> { var data = asymmetry.encoding().getOrThrow(); List>> toEncode = new ArrayList<>(); diff --git a/src/stream/java/dev/lukebemish/codecextras/stream/mutable/package-info.java b/src/stream/java/dev/lukebemish/codecextras/stream/mutable/package-info.java index 31f6afb..6b5786c 100644 --- a/src/stream/java/dev/lukebemish/codecextras/stream/mutable/package-info.java +++ b/src/stream/java/dev/lukebemish/codecextras/stream/mutable/package-info.java @@ -1,4 +1,6 @@ @NullMarked +@ApiStatus.Experimental package dev.lukebemish.codecextras.stream.mutable; +import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; diff --git a/src/test/java/dev/lukebemish/codecextras/test/mutalbe/TestDataElements.java b/src/test/java/dev/lukebemish/codecextras/test/mutalbe/TestDataElements.java index e066e02..93eaf00 100644 --- a/src/test/java/dev/lukebemish/codecextras/test/mutalbe/TestDataElements.java +++ b/src/test/java/dev/lukebemish/codecextras/test/mutalbe/TestDataElements.java @@ -9,21 +9,21 @@ import dev.lukebemish.codecextras.mutable.DataElement; import dev.lukebemish.codecextras.mutable.DataElementType; import dev.lukebemish.codecextras.test.CodecAssertions; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.Objects; +import java.util.function.Consumer; + class TestDataElements { private static class WithDataElements { - private static final DataElementType STRING = DataElementType.defaulted(Codec.STRING, "", d -> d.string); - private static final DataElementType INTEGER = DataElementType.defaulted(Codec.INT, 0, d -> d.integer); - private static final Codec, WithDataElements>> CODEC = DataElementType.codec(List.of(STRING, INTEGER), true); - private static final Codec, WithDataElements>> CHANGED_CODEC = DataElementType.codec(List.of(STRING, INTEGER), false); + private static final DataElementType STRING = DataElementType.defaulted("string", Codec.STRING, d -> d.string); + private static final DataElementType INTEGER = DataElementType.defaulted("integer", Codec.INT, d -> d.integer); + private static final Codec, WithDataElements>> CODEC = DataElementType.codec(true, STRING, INTEGER); + private static final Codec, WithDataElements>> CHANGED_CODEC = DataElementType.codec(false, STRING, INTEGER); - private final DataElement string = STRING.create(); - private final DataElement integer = INTEGER.create(); + private final DataElement string = new DataElement.Simple<>(""); + private final DataElement integer = new DataElement.Simple<>(0); @Override public boolean equals(Object o) { diff --git a/version.properties b/version.properties index 1d50c83..13794c2 100644 --- a/version.properties +++ b/version.properties @@ -1 +1 @@ -version=2.1.0 +version=2.2.0