RegistrySet API

This commit is contained in:
Jake Potrebic 2024-05-11 19:26:33 -07:00
parent 711f82e01e
commit e6a1ff1354
No known key found for this signature in database
GPG Key ID: ECE0B3C133C016C5
2 changed files with 422 additions and 0 deletions

View File

@ -0,0 +1,303 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 11 May 2024 19:25:48 -0700
Subject: [PATCH] RegistrySet API
This API is supposed to be the API equivalent of nms'
HolderSet and HolderSet$Named.
diff --git a/src/main/java/io/papermc/paper/registry/set/RegistryKeySet.java b/src/main/java/io/papermc/paper/registry/set/RegistryKeySet.java
new file mode 100644
index 0000000000000000000000000000000000000000..356336015ec153d4d0b57a5466d952db6518eaa9
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/set/RegistryKeySet.java
@@ -0,0 +1,25 @@
+package io.papermc.paper.registry.set;
+
+import io.papermc.paper.registry.TypedKey;
+import io.papermc.paper.registry.tag.TagKey;
+import java.util.Collection;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Unmodifiable;
+
+@ApiStatus.Experimental
+public sealed interface RegistryKeySet<T> extends RegistrySet<T> permits RegistryKeySet.Named, RegistryKeySetImpl {
+
+ @Override
+ default int size() {
+ return this.values().size();
+ }
+
+ @NotNull @Unmodifiable Collection<TypedKey<T>> values();
+
+ @ApiStatus.Experimental
+ non-sealed interface Named<T> extends RegistryKeySet<T> {
+
+ @NotNull TagKey<T> tagKey();
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/set/RegistryKeySetImpl.java b/src/main/java/io/papermc/paper/registry/set/RegistryKeySetImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..db957c3129f462641bb81b5042ac4c73d4f31a67
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/set/RegistryKeySetImpl.java
@@ -0,0 +1,54 @@
+package io.papermc.paper.registry.set;
+
+import com.google.common.base.Preconditions;
+import io.papermc.paper.registry.RegistryAccess;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Registry;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable;
+
+@ApiStatus.Internal
+@DefaultQualifier(NonNull.class)
+record RegistryKeySetImpl<T extends Keyed>(RegistryKey<T> registryKey, List<TypedKey<T>> values) implements RegistryKeySet<T> { // TODO remove Keyed
+
+ static <T extends Keyed> RegistryKeySet<T> create(final RegistryKey<T> registryKey, final Iterable<? extends T> values) {
+ final Registry<T> registry = RegistryAccess.registryAccess().getRegistry(registryKey);
+ final ArrayList<TypedKey<T>> keys = new ArrayList<>();
+ for (final T value : values) {
+ final @Nullable NamespacedKey key = registry.getKey(value);
+ Preconditions.checkArgument(key != null, value + " does not have a key in " + registryKey);
+ keys.add(TypedKey.create(registryKey, key));
+ }
+ return new RegistryKeySetImpl<>(registryKey, keys);
+ }
+
+ RegistryKeySetImpl {
+ values = List.copyOf(values);
+ }
+
+ @Override
+ public boolean contains(final TypedKey<T> valueKey) {
+ return false;
+ }
+
+ @Override
+ public Collection<T> resolve() {
+ final Registry<T> registry = RegistryAccess.registryAccess().getRegistry(this.registryKey);
+ final List<T> values = new ArrayList<>(this.values.size());
+ for (final TypedKey<T> key : this.values) {
+ final @Nullable T value = registry.get(key);
+ Preconditions.checkState(value != null, "Trying to access unbound TypedKey: " + key);
+ values.add(value);
+ }
+ return Collections.unmodifiableList(values);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/set/RegistrySet.java b/src/main/java/io/papermc/paper/registry/set/RegistrySet.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1da80995af0aa3ff424f1edb3b1f48f40a0da1f
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/set/RegistrySet.java
@@ -0,0 +1,74 @@
+package io.papermc.paper.registry.set;
+
+import com.google.common.collect.Lists;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import java.util.Collection;
+import java.util.Iterator;
+import org.bukkit.Keyed;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Unmodifiable;
+
+@ApiStatus.Experimental
+public sealed interface RegistrySet<T> extends Iterable<T> permits RegistryKeySet, RegistryValueSet {
+
+ // TODO uncomment when API finally needs this
+ // @Contract(value = "_, _ -> new", pure = true)
+ // static <T> @NotNull RegistryValueSet<T> direct(final @NotNull RegistryKey<T> registryKey, final @NotNull Iterable<? extends T> values) {
+ // return new RegistryValueSetImpl<>(registryKey, Lists.newArrayList(values));
+ // }
+
+ /**
+ * Creates an indirect {@link RegistrySet} from {@link TypedKey TypedKeys}.
+ *
+ * @param registryKey the registry key for the owner of these values
+ * @param values the values
+ * @return a new registry set
+ * @param <T> the type of the values
+ * @throws IllegalArgumentException if any of the values doesn't have a key
+ * @throws IllegalArgumentException if the registry isn't available yet
+ */
+ @Contract(value = "_, _ -> new", pure = true)
+ static <T extends Keyed> @NotNull RegistryKeySet<T> indirect(final @NotNull RegistryKey<T> registryKey, final @NotNull Iterable<? extends T> values) { // TODO remove Keyed
+ return RegistryKeySetImpl.create(registryKey, values);
+ }
+
+ /**
+ * Creates an indirect {@link RegistrySet} from {@link TypedKey TypedKeys}.
+ *
+ * @param registryKey the registry key for the owner of these keys
+ * @param keys the keys for the values
+ * @return a new registry set
+ * @param <T> the type of the values
+ */
+ @SuppressWarnings("BoundedWildcard")
+ @Contract(value = "_, _ -> new", pure = true)
+ static <T extends Keyed> @NotNull RegistryKeySet<T> indirectKeys(final @NotNull RegistryKey<T> registryKey, final @NotNull Iterable<TypedKey<T>> keys) { // TODO remove Keyed
+ return new RegistryKeySetImpl<>(registryKey, Lists.newArrayList(keys));
+ }
+
+ /**
+ * Get the registry key for this set.
+ *
+ * @return the registry key
+ */
+ @NotNull RegistryKey<T> registryKey();
+
+ /**
+ * Get the size of this set.
+ *
+ * @return the size
+ */
+ int size();
+
+ boolean contains(@NotNull TypedKey<T> valueKey);
+
+ @NotNull @Unmodifiable Collection<T> resolve();
+
+ @Override
+ default @NotNull Iterator<T> iterator() {
+ return this.resolve().iterator();
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/set/RegistryValueSet.java b/src/main/java/io/papermc/paper/registry/set/RegistryValueSet.java
new file mode 100644
index 0000000000000000000000000000000000000000..bcc33e22fabd7a20922a276fd01b0f4b7229c41b
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/set/RegistryValueSet.java
@@ -0,0 +1,28 @@
+package io.papermc.paper.registry.set;
+
+import io.papermc.paper.registry.TypedKey;
+import java.util.Collection;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Unmodifiable;
+
+@ApiStatus.Experimental
+public sealed interface RegistryValueSet<T> extends RegistrySet<T> permits RegistryValueSetImpl {
+
+ @Override
+ default int size() {
+ return this.values().size();
+ }
+
+ @Override
+ default boolean contains(final @NotNull TypedKey<T> valueKey) {
+ return false;
+ }
+
+ @Override
+ default @NotNull @Unmodifiable Collection<T> resolve() {
+ return this.values();
+ }
+
+ @NotNull @Unmodifiable Collection<T> values();
+}
diff --git a/src/main/java/io/papermc/paper/registry/set/RegistryValueSetImpl.java b/src/main/java/io/papermc/paper/registry/set/RegistryValueSetImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..988789492f91eb00c194ecd673efc445ea9dd23b
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/set/RegistryValueSetImpl.java
@@ -0,0 +1,9 @@
+package io.papermc.paper.registry.set;
+
+import io.papermc.paper.registry.RegistryKey;
+import java.util.List;
+import org.jetbrains.annotations.ApiStatus;
+
+@ApiStatus.Internal
+record RegistryValueSetImpl<T>(RegistryKey<T> registryKey, List<T> values) implements RegistryValueSet<T> {
+}
diff --git a/src/main/java/io/papermc/paper/registry/tag/TagKey.java b/src/main/java/io/papermc/paper/registry/tag/TagKey.java
new file mode 100644
index 0000000000000000000000000000000000000000..238b23346a5321527fb2c39ba381a8f265cb9c1e
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/tag/TagKey.java
@@ -0,0 +1,32 @@
+package io.papermc.paper.registry.tag;
+
+import io.papermc.paper.registry.RegistryKey;
+import net.kyori.adventure.key.Key;
+import net.kyori.adventure.key.Keyed;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+@ApiStatus.Experimental
+public sealed interface TagKey<T> extends Keyed permits TagKeyImpl {
+
+ /**
+ * Creates a new tag key for a registry.
+ *
+ * @param registryKey the registry for the tag
+ * @param key the specific key for the tag
+ * @return a new tag key
+ * @param <T> the registry value type
+ */
+ @Contract(value = "_, _ -> new", pure = true)
+ static <T> @NotNull TagKey<T> create(final @NotNull RegistryKey<T> registryKey, final @NotNull Key key) {
+ return new TagKeyImpl<>(registryKey, key);
+ }
+
+ /**
+ * Get the registry key for this tag key.
+ *
+ * @return the registry key
+ */
+ @NotNull RegistryKey<T> registryKey();
+}
diff --git a/src/main/java/io/papermc/paper/registry/tag/TagKeyImpl.java b/src/main/java/io/papermc/paper/registry/tag/TagKeyImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..741770080259ea2225d2b9081f73d55148788860
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/tag/TagKeyImpl.java
@@ -0,0 +1,10 @@
+package io.papermc.paper.registry.tag;
+
+import io.papermc.paper.registry.RegistryKey;
+import net.kyori.adventure.key.Key;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+
+@DefaultQualifier(NonNull.class)
+record TagKeyImpl<T>(RegistryKey<T> registryKey, Key key) implements TagKey<T> {
+}
diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
index 88bb3b9ae99fae97ec21972b75ec43cb6b7b22b5..ca06368fee6dd83111aa91bc3c0c06d2ea10bf0f 100644
--- a/src/main/java/org/bukkit/Registry.java
+++ b/src/main/java/org/bukkit/Registry.java
@@ -396,6 +396,16 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
}
// Paper end - improve Registry
+ // Paper start - RegistrySet API
+ default boolean hasTag(final io.papermc.paper.registry.tag.TagKey<T> key) {
+ throw new UnsupportedOperationException(this + " doesn't have tags");
+ }
+
+ default io.papermc.paper.registry.set.RegistryKeySet.@NotNull Named<T> getTag(final io.papermc.paper.registry.tag.TagKey<T> key) {
+ throw new UnsupportedOperationException(this + " doesn't have tags");
+ }
+ // Paper end - RegistrySet API
+
/**
* Returns a new stream, which contains all registry items, which are registered to the registry.
*

View File

@ -0,0 +1,119 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 11 May 2024 19:26:18 -0700
Subject: [PATCH] RegistrySet API
diff --git a/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java b/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java
index 5562e8da5ebaef2a3add46e88d64358b7737b59e..59c82a6f01645697e0129b97fc4cb45217b2da65 100644
--- a/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java
+++ b/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java
@@ -1,12 +1,13 @@
package io.papermc.paper.registry.legacy;
+import io.papermc.paper.registry.set.RegistryKeySet;
+import io.papermc.paper.registry.tag.TagKey;
import java.util.Iterator;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
-import org.bukkit.craftbukkit.CraftRegistry;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.NotNull;
@@ -52,4 +53,14 @@ public final class DelayedRegistry<T extends Keyed, R extends Registry<T>> imple
public NamespacedKey getKey(final T value) {
return this.delegate().getKey(value);
}
+
+ @Override
+ public boolean hasTag(final TagKey<T> key) {
+ return this.delegate().hasTag(key);
+ }
+
+ @Override
+ public RegistryKeySet.@NotNull Named<T> getTag(final TagKey<T> key) {
+ return this.delegate().getTag(key);
+ }
}
diff --git a/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java b/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..30871d0d0db5b745204429fc816941f4cacce4c3
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java
@@ -0,0 +1,51 @@
+package io.papermc.paper.registry.set;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import io.papermc.paper.registry.RegistryAccess;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import io.papermc.paper.registry.tag.TagKey;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import net.minecraft.core.Holder;
+import net.minecraft.core.HolderSet;
+import org.bukkit.Keyed;
+import org.bukkit.Registry;
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Unmodifiable;
+
+@DefaultQualifier(NonNull.class)
+public record NamedRegistryKeySetImpl<T extends Keyed, M>( // TODO remove Keyed
+ TagKey<T> tagKey,
+ HolderSet.Named<M> namedSet
+) implements RegistryKeySet.Named<T> {
+
+ @Override
+ public @NotNull @Unmodifiable Collection<TypedKey<T>> values() {
+ return List.of();
+ }
+
+ @Override
+ public @NotNull RegistryKey<T> registryKey() {
+ return this.tagKey.registryKey();
+ }
+
+ @Override
+ public boolean contains(final @NotNull TypedKey<T> valueKey) {
+ return this.namedSet.stream().anyMatch(h -> {
+ return ((Holder.Reference<?>) h).key().location().equals(PaperAdventure.asVanilla(valueKey.key()));
+ });
+ }
+
+ @Override
+ public @NotNull @Unmodifiable Collection<T> resolve() {
+ final Registry<T> registry = RegistryAccess.registryAccess().getRegistry(this.registryKey());
+ return this.namedSet.stream().map(h -> {
+ return Objects.requireNonNull(registry.get(CraftNamespacedKey.fromMinecraft(((Holder.Reference<M>) h).key().location())));
+ }).toList();
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
index 5c725faae98a126ee0e34eea53cfa484d2315709..055556b06877660951f3b39455588684a03b059b 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
@@ -223,4 +223,17 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
return this.byValue.get(value);
}
// Paper end - improve Registry
+
+ // Paper start - RegistrySet API
+ @Override
+ public boolean hasTag(final io.papermc.paper.registry.tag.TagKey<B> key) {
+ return this.minecraftRegistry.getTag(net.minecraft.tags.TagKey.create(this.minecraftRegistry.key(), io.papermc.paper.adventure.PaperAdventure.asVanilla(key.key()))).isPresent();
+ }
+
+ @Override
+ public io.papermc.paper.registry.set.RegistryKeySet.Named<B> getTag(final io.papermc.paper.registry.tag.TagKey<B> key) {
+ final net.minecraft.core.HolderSet.Named<M> namedHolderSet = this.minecraftRegistry.getTag(net.minecraft.tags.TagKey.create(this.minecraftRegistry.key(), io.papermc.paper.adventure.PaperAdventure.asVanilla(key.key()))).orElseThrow();
+ return new io.papermc.paper.registry.set.NamedRegistryKeySetImpl<>(key, namedHolderSet);
+ }
+ // Paper end - RegistrySet API
}