Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ReflectiveConfig.Section implement ValueTreeNode.Section #49

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/main/java/org/quiltmc/config/api/InternalsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package org.quiltmc.config.api;

import org.jetbrains.annotations.ApiStatus;
import org.quiltmc.config.api.values.ValueTreeNode;
import org.quiltmc.config.impl.builders.ReflectiveConfigCreator;

/**
* Provides the implementation packages access to package-private methods. <strong>DO NOT USE THIS CLASS</strong>
Expand All @@ -29,5 +31,14 @@ private InternalsHelper() {

public static <T extends ReflectiveConfig> void setWrappedConfig(T wrapped, Config config) {
wrapped.setWrappedConfig(config);
for (ValueTreeNode node : config.nodes()) {
if (node instanceof ValueTreeNode.Section) {
ValueTreeNode.Section section = (ValueTreeNode.Section) node;
ReflectiveConfigCreator.SectionMarker marker = section.metadata(ReflectiveConfigCreator.SectionMarker.TYPE);
if (marker != null) {
marker.self.setWrappedSection(section);
}
}
}
Comment on lines +34 to +42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this should either be put into ReflectiveConfig.setWrappedConfig, or into the impl package with another setWrappedSection in here.

}
}
40 changes: 39 additions & 1 deletion src/main/java/org/quiltmc/config/api/ReflectiveConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.quiltmc.config.api.metadata.MetadataType;
import org.quiltmc.config.api.values.TrackedValue;
import org.quiltmc.config.api.values.ValueKey;
import org.quiltmc.config.api.values.ValueList;
import org.quiltmc.config.api.values.ValueMap;
import org.quiltmc.config.api.values.ValueTreeNode;
Expand All @@ -27,6 +28,7 @@

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

Expand Down Expand Up @@ -112,7 +114,9 @@ public final <T> ValueMap.TrackedBuilder<T> map(T defaultValue) {
return new ValueMapBuilderImpl.TrackedValueMapBuilderImpl<>(defaultValue, this::value);
}

public static class Section {
public static class Section implements ValueTreeNode.Section {
private ValueTreeNode.Section wrapped;

public final <T> TrackedValue<T> value(T defaultValue) {
ConfigUtils.assertValueType(defaultValue);

Expand All @@ -127,5 +131,39 @@ public final <T> TrackedValue<ValueList<T>> list(T defaultValue, T... values) {
public final <T> ValueMap.TrackedBuilder<T> map(T defaultValue) {
return new ValueMapBuilderImpl.TrackedValueMapBuilderImpl<>(defaultValue, this::value);
}

@Override
public ValueKey key() {
return this.wrapped.key();
}

@Override
public void propagateInheritedMetadata(Map<MetadataType<?, ?>, Object> inheritedMetadata) {
this.wrapped.propagateInheritedMetadata(inheritedMetadata);
}

@Override
public <M> M metadata(MetadataType<M, ?> type) {
return this.wrapped.metadata(type);
}

@Override
public <M> boolean hasMetadata(MetadataType<M, ?> type) {
return this.wrapped.hasMetadata(type);
}

@Override
public Map<MetadataType<?, ?>, Object> metadata() {
return this.wrapped.metadata();
}

@Override
public Iterator<ValueTreeNode> iterator() {
return this.wrapped.iterator();
}

final void setWrappedSection(ValueTreeNode.Section section) {
this.wrapped = section;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
import org.quiltmc.config.impl.ConfigFieldAnnotationProcessors;
import org.quiltmc.config.api.exceptions.ConfigCreationException;
import org.quiltmc.config.api.exceptions.ConfigFieldException;
import org.quiltmc.config.api.metadata.MetadataType;
import org.quiltmc.config.impl.tree.TrackedValueImpl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Objects;

public class ReflectiveConfigCreator<C> implements Config.Creator {
private final Class<C> creatorClass;
Expand All @@ -39,6 +41,31 @@ public ReflectiveConfigCreator(Class<C> creatorClass) {
this.creatorClass = creatorClass;
}

public static class SectionMarker {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im not sure if we should use metadata for pure implementation details. You can get all metadata an elements holds, so it would leak implementation details I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm not a huge fan of it either, but this was a quick fix and trying to keep track of this information in the creator looked like a pain. I could take a look at doing that in the future, but I'm not sure when I'll have the time...

public static MetadataType<SectionMarker, Builder> TYPE = MetadataType.create(Builder::new);
public final ReflectiveConfig.Section self;

private SectionMarker(ReflectiveConfig.Section self) {
this.self = self;
}

// ReadWriteCycleTest needs these to be equal
@Override
public boolean equals(Object obj) {
return obj instanceof SectionMarker && ((SectionMarker) obj).self.getClass().equals(this.self.getClass());
}

public static class Builder implements MetadataType.Builder<SectionMarker> {
private ReflectiveConfig.Section self;

@Override
public ReflectiveConfigCreator.SectionMarker build() {
Objects.requireNonNull(this.self);
return new SectionMarker(this.self);
}
}
}

@SuppressWarnings({"unchecked", "rawtypes"})
private void createField(Config.SectionBuilder builder, Object object, Field field) throws IllegalAccessException {
if (!Modifier.isStatic(field.getModifiers()) && !Modifier.isTransient(field.getModifiers())) {
Expand Down Expand Up @@ -127,6 +154,8 @@ private void createField(Config.SectionBuilder builder, Object object, Field fie
}
}
}

b.metadata(SectionMarker.TYPE, metaBuilder -> metaBuilder.self = (ReflectiveConfig.Section) defaultValue);
});
} else if (defaultValue == null) {
throw new ConfigFieldException("Default value for field '" + field.getName() + "' cannot be null");
Expand Down