diff --git a/README.md b/README.md index 5a5e9e3..e853293 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ field should not be final. Mark this field with the annotation `@Config`. The in default (fallback) value. You can add a comment by setting the `comment` attribute. ```java public class Configs { - @Config(comment = "This is an example!") + @Config public static String exampleString = "default"; } ``` diff --git a/common/src/main/java/dev/xpple/betterconfig/api/Config.java b/common/src/main/java/dev/xpple/betterconfig/api/Config.java index b9afd4b..cd8702c 100644 --- a/common/src/main/java/dev/xpple/betterconfig/api/Config.java +++ b/common/src/main/java/dev/xpple/betterconfig/api/Config.java @@ -82,8 +82,16 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Config { /** - * An explanatory comment about the config. This value will be used in the {@code comment} subcommand of the config command. - * @return the comment + * A method name that will be used to display an explanatory comment about the config. The method should have no parameters + * and return the chat component type: {@link net.minecraft.network.chat.Component} on Fabric and {@link net.kyori.adventure.text.Component} + * on Paper. This value will be used in the {@code comment} subcommand of the config command. Below is an example for Fabric: + * {@snippet lang = java: + * @Config(comment = "comment") + * public static Component comment() { + * return Component.literal("This should be helpful!"); + * } + * } + * @return the method name */ String comment() default ""; diff --git a/common/src/main/java/dev/xpple/betterconfig/api/ModConfig.java b/common/src/main/java/dev/xpple/betterconfig/api/ModConfig.java index e7d3ef3..7bb353c 100644 --- a/common/src/main/java/dev/xpple/betterconfig/api/ModConfig.java +++ b/common/src/main/java/dev/xpple/betterconfig/api/ModConfig.java @@ -27,6 +27,23 @@ public interface ModConfig
{
*/
Path getConfigsPath();
+ /**
+ * Get the default (initial) value for a config. Note that the returned value is a
+ * deep copy of the config's default value.
+ * @param config the config's key
+ * @return (a deep copy of) the default value
+ * @throws IllegalArgumentException when there is no config associated to this key
+ */
+ Object getDefault(String config);
+
+ /**
+ * Get the comment for a config.
+ * @param config the config's key
+ * @return the config comment
+ * @throws IllegalArgumentException when there is no config associated to this key
+ */
+ P getComment(String config);
+
/**
* Get a config value based on the key.
* @param config the config's key
diff --git a/common/src/main/java/dev/xpple/betterconfig/command/AbstractConfigCommand.java b/common/src/main/java/dev/xpple/betterconfig/command/AbstractConfigCommand.java
index c7c453a..912fe3f 100644
--- a/common/src/main/java/dev/xpple/betterconfig/command/AbstractConfigCommand.java
+++ b/common/src/main/java/dev/xpple/betterconfig/command/AbstractConfigCommand.java
@@ -13,6 +13,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.function.Predicate;
+import java.util.function.Supplier;
import static com.mojang.brigadier.arguments.StringArgumentType.*;
@@ -38,9 +39,9 @@ protected final LiteralArgumentBuilder create(Collection extends ModConfigI
configLiteral.then(LiteralArgumentBuilder.literal("reset").executes(ctx -> reset(ctx.getSource(), modConfig, config)));
}
- String comment = modConfig.getComments().get(config);
+ Supplier
comment = modConfig.getComments().get(config);
if (comment != null) {
- configLiteral.then(LiteralArgumentBuilder.literal("comment").executes(ctx -> comment(ctx.getSource(), config, comment)));
+ configLiteral.then(LiteralArgumentBuilder.literal("comment").executes(ctx -> comment(ctx.getSource(), config, comment.get())));
}
if (modConfig.getSetters().containsKey(config)) {
@@ -148,7 +149,7 @@ protected final LiteralArgumentBuilder create(Collection extends ModConfigI
return root;
}
- protected abstract int comment(S source, String config, String comment);
+ protected abstract int comment(S source, String config, P comment);
protected abstract int get(S source, ModConfigImpl modConfig, String config);
diff --git a/common/src/main/java/dev/xpple/betterconfig/impl/BetterConfigInternals.java b/common/src/main/java/dev/xpple/betterconfig/impl/BetterConfigInternals.java
index 30f3d2d..8599aa8 100644
--- a/common/src/main/java/dev/xpple/betterconfig/impl/BetterConfigInternals.java
+++ b/common/src/main/java/dev/xpple/betterconfig/impl/BetterConfigInternals.java
@@ -58,9 +58,7 @@ public static void init(ModConfigImpl, ?, ?> modConfig) {
throw new AssertionError(e);
}
- if (!annotation.comment().isEmpty()) {
- modConfig.getComments().put(fieldName, annotation.comment());
- }
+ initComment(modConfig, annotation.comment(), fieldName);
if (!annotation.temporary()) {
try {
@@ -107,6 +105,35 @@ public static void init(ModConfigImpl, ?, ?> modConfig) {
}
}
+ private static void initComment(ModConfigImpl, ?, ?> modConfig, String commentMethodName, String fieldName) {
+ if (commentMethodName.isEmpty()) {
+ return;
+ }
+ Method commentMethod;
+ try {
+ commentMethod = modConfig.getConfigsClass().getDeclaredMethod(commentMethodName);
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
+ }
+ Class> componentClass = Platform.current.getComponentClass();
+ if (commentMethod.getReturnType() != componentClass) {
+ throw new AssertionError("Comment method '" + commentMethodName + "' does not return Component");
+ }
+ if (!Modifier.isStatic(commentMethod.getModifiers())) {
+ throw new AssertionError("Comment method '" + commentMethodName + "' is not static");
+ }
+ commentMethod.setAccessible(true);
+
+ //noinspection rawtypes, unchecked
+ modConfig.getComments().put(fieldName, (Supplier) () -> {
+ try {
+ return commentMethod.invoke(null);
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
+ }
+ });
+ }
+
private static void initChatRepresentation(ModConfigImpl, ?, ?> modConfig, Field field, String chatRepresentationMethodName) {
if (chatRepresentationMethodName.isEmpty()) {
return;
diff --git a/common/src/main/java/dev/xpple/betterconfig/impl/ModConfigImpl.java b/common/src/main/java/dev/xpple/betterconfig/impl/ModConfigImpl.java
index 9619c64..59f99ab 100644
--- a/common/src/main/java/dev/xpple/betterconfig/impl/ModConfigImpl.java
+++ b/common/src/main/java/dev/xpple/betterconfig/impl/ModConfigImpl.java
@@ -52,7 +52,7 @@ public class ModConfigImpl implements ModConfig
{
private final Map comment = this.comments.get(config);
+ if (comment == null) {
+ throw new IllegalArgumentException();
+ }
+ return comment.get();
+ }
+
@Override
public Object get(String config) {
Field field = this.configs.get(config);
diff --git a/fabric/src/client/java/dev/xpple/betterconfig/command/client/ConfigCommandClient.java b/fabric/src/client/java/dev/xpple/betterconfig/command/client/ConfigCommandClient.java
index d49c047..1a35d4a 100644
--- a/fabric/src/client/java/dev/xpple/betterconfig/command/client/ConfigCommandClient.java
+++ b/fabric/src/client/java/dev/xpple/betterconfig/command/client/ConfigCommandClient.java
@@ -22,9 +22,9 @@ public static void register(CommandDispatcher