implement getType method in registries

This commit is contained in:
dfsek
2021-12-19 17:41:04 -07:00
parent aeb0372d59
commit 9872d22c06
15 changed files with 260 additions and 46 deletions

View File

@@ -0,0 +1,91 @@
package com.dfsek.terra.api.command;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.context.CommandContext;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.registry.exception.NoSuchEntryException;
import io.leangen.geantyref.TypeToken;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List;
import java.util.Queue;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
public class RegistryArgument<T, R> extends CommandArgument<T, R> {
@SuppressWarnings("unchecked")
private RegistryArgument(
final boolean required,
final @NonNull String name,
final Registry<R> registry,
final @NonNull String defaultValue,
final @Nullable BiFunction<@NonNull CommandContext<T>, @NonNull String,
@NonNull List<@NonNull String>> suggestionsProvider,
final @NonNull ArgumentDescription description
) {
super(required,
name,
new RegistryArgumentParser<>(registry),
defaultValue,
(TypeToken<R>) TypeToken.get(registry.getType().getType()),
suggestionsProvider,
description);
}
public static <T, R> Builder<T, R> builder(String name, Registry<R> registry) {
return new Builder<>(name, registry);
}
public static final class Builder<T, R> extends CommandArgument.Builder<T, R> {
private final Registry<R> registry;
@SuppressWarnings("unchecked")
private Builder(@NonNull String name, Registry<R> registry) {
super((TypeToken<R>) registry.getType().getType(), name);
this.registry = registry;
}
@Override
public @NonNull RegistryArgument<T, R> build() {
return new RegistryArgument<>(
isRequired(),
getName(),
registry,
getDefaultValue(),
getSuggestionsProvider(),
getDefaultDescription()
);
}
}
private static final class RegistryArgumentParser<T, R> implements ArgumentParser<T, R> {
private final Registry<R> registry;
private RegistryArgumentParser(Registry<R> registry) {
this.registry = registry;
}
@Override
public @NonNull ArgumentParseResult<@NonNull R> parse(@NonNull CommandContext<@NonNull T> commandContext,
@NonNull Queue<@NonNull String> inputQueue) {
String input = inputQueue.remove();
return registry.get(input).map(ArgumentParseResult::success).orElse(ArgumentParseResult.failure(new NoSuchEntryException("No such entry: " + input)));
}
@Override
public @NonNull List<@NonNull String> suggestions(@NonNull CommandContext<T> commandContext, @NonNull String input) {
return registry.keys().stream().sorted().collect(Collectors.toList());
}
}
}

View File

@@ -35,15 +35,11 @@ public interface ConfigPack extends LoaderRegistrar, ConfigLoadingDelegate, Regi
BiomeProvider getBiomeProvider();
<T> CheckedRegistry<T> getOrCreateRegistry(Type clazz);
default <T> CheckedRegistry<T> getOrCreateRegistry(Class<T> clazz) {
return getOrCreateRegistry((Type) clazz);
return getOrCreateRegistry(TypeKey.of(clazz));
}
default <T> CheckedRegistry<T> getOrCreateRegistry(TypeKey<T> type) {
return getOrCreateRegistry(type.getType());
}
<T> CheckedRegistry<T> getOrCreateRegistry(TypeKey<T> type);
List<GenerationStage> getStages();
@@ -53,10 +49,10 @@ public interface ConfigPack extends LoaderRegistrar, ConfigLoadingDelegate, Regi
Version getVersion();
<T> ConfigPack registerShortcut(Type clazz, String shortcut, ShortcutLoader<T> loader);
<T> ConfigPack registerShortcut(TypeKey<T> clazz, String shortcut, ShortcutLoader<T> loader);
default <T> ConfigPack registerShortcut(Class<T> clazz, String shortcut, ShortcutLoader<T> loader) {
return registerShortcut((Type) clazz, shortcut, loader);
return registerShortcut(TypeKey.of(clazz), shortcut, loader);
}
ChunkGeneratorProvider getGeneratorProvider();

View File

@@ -8,6 +8,10 @@
package com.dfsek.terra.api.registry;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.google.common.reflect.TypeToken;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@@ -70,4 +74,6 @@ public interface Registry<T> extends TypeLoader<T> {
@NotNull
@Contract(pure = true)
Set<String> keys();
TypeKey<T> getType();
}

View File

@@ -7,6 +7,8 @@
package com.dfsek.terra.api.util.reflection;
import com.dfsek.tectonic.util.ClassAnnotatedTypeImpl;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.GenericArrayType;
@@ -33,6 +35,17 @@ public class TypeKey<T> {
this.hashCode = type.hashCode();
}
protected TypeKey(Class<T> clazz) {
this.type = clazz;
this.rawType = clazz;
this.annotatedType = new ClassAnnotatedTypeImpl(clazz);
this.hashCode = type.hashCode();
}
public static <T> TypeKey<T> of(Class<T> clazz) {
return new TypeKey<>(clazz);
}
public static boolean equals(Type a, Type b) {
if(a == b) {
return true;