[construct, core, weaver-pojo] Replace simple class injections with more sophisticated construction

This commit is contained in:
2025-04-23 11:16:15 +02:00
parent de92d6843f
commit 6e79957207
22 changed files with 1163 additions and 223 deletions

View File

@@ -3,6 +3,7 @@ plugins {
}
dependencies {
implementation(project(":tweed5-construct"))
api(project(":tweed5-patchwork"))
api(project(":tweed5-utils"))
}
}

View File

@@ -1,5 +1,6 @@
package de.siphalor.tweed5.core.api.container;
import de.siphalor.tweed5.construct.api.TweedConstructFactory;
import de.siphalor.tweed5.core.api.extension.EntryExtensionsData;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.extension.RegisteredExtensionData;
@@ -16,6 +17,8 @@ import java.util.Map;
* @see ConfigContainerSetupPhase
*/
public interface ConfigContainer<T> {
@SuppressWarnings("rawtypes")
TweedConstructFactory<ConfigContainer> FACTORY = TweedConstructFactory.builder(ConfigContainer.class).build();
default void registerExtensions(TweedExtension... extensions) {
for (TweedExtension extension : extensions) {

View File

@@ -1,133 +0,0 @@
package de.siphalor.tweed5.core.impl.entry;
import de.siphalor.tweed5.core.api.entry.*;
import lombok.Getter;
import lombok.Value;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
@Getter
public class ReflectiveCompoundConfigEntryImpl<T> extends BaseConfigEntry<T> implements CompoundConfigEntry<T> {
private final Constructor<T> noArgsConstructor;
private final Map<String, CompoundEntry> compoundEntries;
public ReflectiveCompoundConfigEntryImpl(Class<T> valueClass) {
super(valueClass);
try {
this.noArgsConstructor = valueClass.getConstructor();
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Value class must have a no-arg constructor", e);
}
this.compoundEntries = new LinkedHashMap<>();
}
public void addSubEntry(String name, Field field, ConfigEntry<?> configEntry) {
requireUnsealed();
if (field.getType() != valueClass()) {
throw new IllegalArgumentException("Field is not defined on the correct type");
}
//noinspection unchecked
compoundEntries.put(name, new CompoundEntry(name, field, (ConfigEntry<Object>) configEntry));
}
public Map<String, ConfigEntry<?>> subEntries() {
return compoundEntries.values().stream().collect(Collectors.toMap(CompoundEntry::name, CompoundEntry::configEntry));
}
@Override
public <V> void set(T compoundValue, String key, V value) {
CompoundEntry compoundEntry = compoundEntries.get(key);
if (compoundEntry == null) {
throw new IllegalArgumentException("Unknown config entry: " + key);
}
try {
compoundEntry.field().set(compoundValue, value);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
@Override
public <V> V get(T compoundValue, String key) {
CompoundEntry compoundEntry = compoundEntries.get(key);
if (compoundEntry == null) {
throw new IllegalArgumentException("Unknown config entry: " + key);
}
try {
//noinspection unchecked
return (V) compoundEntry.field().get(compoundValue);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
@Override
public T instantiateCompoundValue() {
try {
return noArgsConstructor.newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Failed to instantiate compound value", e);
}
}
@Override
public void visitInOrder(ConfigEntryVisitor visitor) {
if (visitor.enterCompoundEntry(this)) {
for (Map.Entry<String, CompoundEntry> entry : compoundEntries.entrySet()) {
if (visitor.enterCompoundSubEntry(entry.getKey())) {
entry.getValue().configEntry().visitInOrder(visitor);
visitor.leaveCompoundSubEntry(entry.getKey());
}
}
visitor.leaveCompoundEntry(this);
}
}
@Override
public void visitInOrder(ConfigEntryValueVisitor visitor, T value) {
if (visitor.enterCompoundEntry(this, value)) {
compoundEntries.forEach((key, entry) -> {
if (visitor.enterCompoundSubEntry(key)) {
try {
visitor.visitEntry(entry.configEntry(), entry.field().get(value));
} catch (IllegalAccessException ignored) {
// ignored
}
visitor.leaveCompoundSubEntry(key);
}
});
visitor.leaveCompoundEntry(this, value);
}
}
@Override
public @NotNull T deepCopy(@NotNull T value) {
try {
T copy = instantiateCompoundValue();
for (CompoundEntry compoundEntry : compoundEntries.values()) {
compoundEntry.field.set(copy, compoundEntry.field.get(value));
}
return copy;
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
@Value
public static class CompoundEntry {
String name;
Field field;
ConfigEntry<Object> configEntry;
}
}