aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/dev/isxander/yacl3/config/v3/CodecConfig.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/dev/isxander/yacl3/config/v3/CodecConfig.java')
-rw-r--r--src/main/java/dev/isxander/yacl3/config/v3/CodecConfig.java77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/main/java/dev/isxander/yacl3/config/v3/CodecConfig.java b/src/main/java/dev/isxander/yacl3/config/v3/CodecConfig.java
new file mode 100644
index 0000000..833a7ef
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/config/v3/CodecConfig.java
@@ -0,0 +1,77 @@
+package dev.isxander.yacl3.config.v3;
+
+import com.mojang.datafixers.util.Pair;
+import com.mojang.serialization.*;
+import org.jetbrains.annotations.ApiStatus;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@ApiStatus.Experimental
+public abstract class CodecConfig<S extends CodecConfig<S>> implements EntryAddable, Codec<S> {
+ private final List<ReadonlyConfigEntry<?>> entries = new ArrayList<>();
+
+ public CodecConfig() {
+ // cast here to throw immediately on construction
+ var ignored = (S) this;
+ }
+
+ @Override
+ public <T> ConfigEntry<T> register(String fieldName, T defaultValue, Codec<T> codec) {
+ ConfigEntry<T> entry = new CodecConfigEntryImpl<>(fieldName, defaultValue, codec);
+ entries.add(entry);
+ return entry;
+ }
+
+ @Override
+ public <T extends CodecConfig<T>> ReadonlyConfigEntry<T> register(String fieldName, T configInstance) {
+ ReadonlyConfigEntry<T> entry = new ChildConfigEntryImpl<>(fieldName, configInstance);
+ entries.add(entry);
+ return entry;
+ }
+
+ protected void onFinishedDecode(boolean successful) {
+ }
+
+ @Override
+ public <R> DataResult<R> encode(S input, DynamicOps<R> ops, R prefix) {
+ if (input != null && input != this) {
+ throw new IllegalArgumentException("`input` is ignored. It must be null or equal to `this`.");
+ }
+
+ return this.encode(ops, prefix);
+ }
+
+ @Override
+ public <R> DataResult<Pair<S, R>> decode(DynamicOps<R> ops, R input) {
+ this.decode(input, ops);
+ return DataResult.success(Pair.of((S) this, input));
+ }
+
+ public final <R> DataResult<R> encode(DynamicOps<R> ops, R prefix) {
+ RecordBuilder<R> builder = ops.mapBuilder();
+ for (ReadonlyConfigEntry<?> entry : entries) {
+ builder = entry.encode(ops, builder);
+ }
+ return builder.build(prefix);
+ }
+
+ public final <R> DataResult<R> encodeStart(DynamicOps<R> ops) {
+ return this.encode(ops, ops.empty());
+ }
+
+ /**
+ * @return true if decoding of all entries was successful
+ */
+ public final <R> boolean decode(R encoded, DynamicOps<R> ops) {
+ boolean success = true;
+
+ for (ReadonlyConfigEntry<?> entry : entries) {
+ success &= entry.decode(encoded, ops);
+ }
+
+ onFinishedDecode(success);
+
+ return success;
+ }
+}