[*] Generalize the entry system by introducing "structured entries"

This commit is contained in:
2025-08-12 10:04:05 +02:00
parent 6f2e715b2a
commit 83cbe91e35
22 changed files with 307 additions and 288 deletions

View File

@@ -1,15 +1,44 @@
package de.siphalor.tweed5.core.api.entry;
import org.jspecify.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.function.Consumer;
public interface CollectionConfigEntry<E, T extends Collection<E>> extends ConfigEntry<T> {
public interface CollectionConfigEntry<E, T extends Collection<E>> extends StructuredConfigEntry<T> {
@Override
default CollectionConfigEntry<E, T> apply(Consumer<ConfigEntry<T>> function) {
ConfigEntry.super.apply(function);
StructuredConfigEntry.super.apply(function);
return this;
}
@Override
default void visitInOrder(ConfigEntryValueVisitor visitor, @Nullable T value) {
if (value == null) {
return;
}
if (visitor.enterStructuredEntry(this, value)) {
int index = 0;
for (E item : value) {
String indexString = Integer.toString(index);
if (visitor.enterStructuredSubEntry("element", indexString)) {
elementEntry().visitInOrder(visitor, item);
visitor.leaveStructuredSubEntry("element", indexString);
}
index++;
}
visitor.leaveStructuredEntry(this, value);
}
}
@Override
default Map<String, ConfigEntry<?>> subEntries() {
return Collections.singletonMap("element", elementEntry());
}
ConfigEntry<E> elementEntry();
T instantiateCollection(int size);

View File

@@ -1,17 +1,14 @@
package de.siphalor.tweed5.core.api.entry;
import java.util.Map;
import java.util.function.Consumer;
public interface CompoundConfigEntry<T> extends ConfigEntry<T> {
public interface CompoundConfigEntry<T> extends StructuredConfigEntry<T> {
@Override
default CompoundConfigEntry<T> apply(Consumer<ConfigEntry<T>> function) {
ConfigEntry.super.apply(function);
StructuredConfigEntry.super.apply(function);
return this;
}
Map<String, ConfigEntry<?>> subEntries();
<V> void set(T compoundValue, String key, V value);
<V> V get(T compoundValue, String key);

View File

@@ -3,26 +3,18 @@ package de.siphalor.tweed5.core.api.entry;
public interface ConfigEntryValueVisitor {
<T> void visitEntry(ConfigEntry<T> entry, T value);
default <T> boolean enterCollectionEntry(ConfigEntry<T> entry, T value) {
default <T> boolean enterStructuredEntry(ConfigEntry<T> entry, T value) {
visitEntry(entry, value);
return true;
}
default <T> void leaveCollectionEntry(ConfigEntry<T> entry, T value) {
}
default <T> boolean enterCompoundEntry(ConfigEntry<T> entry, T value) {
visitEntry(entry, value);
default boolean enterStructuredSubEntry(String entryKey, String valueKey) {
return true;
}
default boolean enterCompoundSubEntry(String key) {
return true;
default void leaveStructuredSubEntry(String entryKey, String valueKey) {
}
default void leaveCompoundSubEntry(String key) {
}
default <T> void leaveCompoundEntry(ConfigEntry<T> entry, T value) {
default <T> void leaveStructuredEntry(ConfigEntry<T> entry, T value) {
}
}

View File

@@ -3,26 +3,18 @@ package de.siphalor.tweed5.core.api.entry;
public interface ConfigEntryVisitor {
void visitEntry(ConfigEntry<?> entry);
default boolean enterCollectionEntry(ConfigEntry<?> entry) {
default boolean enterStructuredEntry(ConfigEntry<?> entry) {
visitEntry(entry);
return true;
}
default void leaveCollectionEntry(ConfigEntry<?> entry) {
}
default boolean enterCompoundEntry(ConfigEntry<?> entry) {
visitEntry(entry);
default boolean enterStructuredSubEntry(String key) {
return true;
}
default boolean enterCompoundSubEntry(String key) {
return true;
default void leaveStructuredSubEntry(String key) {
}
default void leaveCompoundSubEntry(String key) {
}
default void leaveCompoundEntry(ConfigEntry<?> entry) {
default void leaveStructuredEntry(ConfigEntry<?> entry) {
}
}

View File

@@ -0,0 +1,27 @@
package de.siphalor.tweed5.core.api.entry;
import java.util.Map;
import java.util.function.Consumer;
public interface StructuredConfigEntry<T> extends ConfigEntry<T> {
@Override
default StructuredConfigEntry<T> apply(Consumer<ConfigEntry<T>> function) {
ConfigEntry.super.apply(function);
return this;
}
@Override
default void visitInOrder(ConfigEntryVisitor visitor) {
if (visitor.enterStructuredEntry(this)) {
subEntries().forEach((key, entry) -> {
if (visitor.enterStructuredSubEntry(key)) {
entry.visitInOrder(visitor);
visitor.leaveStructuredSubEntry(key);
}
});
visitor.leaveStructuredEntry(this);
}
}
Map<String, ConfigEntry<?>> subEntries();
}

View File

@@ -31,26 +31,6 @@ public class CollectionConfigEntryImpl<E, T extends Collection<E>> extends BaseC
return collectionConstructor.apply(size);
}
@Override
public void visitInOrder(ConfigEntryVisitor visitor) {
if (visitor.enterCollectionEntry(this)) {
elementEntry.visitInOrder(visitor);
visitor.leaveCollectionEntry(this);
}
}
@Override
public void visitInOrder(ConfigEntryValueVisitor visitor, T value) {
if (visitor.enterCollectionEntry(this, value)) {
if (value != null) {
for (E element : value) {
visitor.visitEntry(elementEntry, element);
}
}
visitor.leaveCollectionEntry(this, value);
}
}
@Override
public T deepCopy(T value) {
T copy = collectionConstructor.apply(value.size());

View File

@@ -51,32 +51,19 @@ public class StaticMapCompoundConfigEntryImpl<T extends Map<String, Object>> ext
return mapConstructor.apply(compoundEntries.size());
}
@Override
public void visitInOrder(ConfigEntryVisitor visitor) {
if (visitor.enterCompoundEntry(this)) {
compoundEntries.forEach((key, entry) -> {
if (visitor.enterCompoundSubEntry(key)) {
entry.visitInOrder(visitor);
visitor.leaveCompoundSubEntry(key);
}
});
visitor.leaveCompoundEntry(this);
}
}
@Override
public void visitInOrder(ConfigEntryValueVisitor visitor, T value) {
if (visitor.enterCompoundEntry(this, value)) {
if (visitor.enterStructuredEntry(this, value)) {
if (value != null) {
compoundEntries.forEach((key, entry) -> {
if (visitor.enterCompoundSubEntry(key)) {
if (visitor.enterStructuredSubEntry(key, key)) {
//noinspection unchecked
((ConfigEntry<Object>) entry).visitInOrder(visitor, value.get(key));
visitor.leaveCompoundSubEntry(key);
visitor.leaveStructuredSubEntry(key, key);
}
});
}
visitor.leaveCompoundEntry(this, value);
visitor.leaveStructuredEntry(this, value);
}
}