From a0b3326609f664848e1013df24ebeecbe4d74309 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sun, 22 Dec 2024 21:17:16 -0800 Subject: refactor registry entry to detach 'delayed' from other meta Also fixes an issue with direct holders --- .../io/papermc/paper/registry/PaperRegistries.java | 2 +- .../paper/registry/PaperRegistryAccess.java | 7 +- .../paper/registry/PaperRegistryBuilder.java | 10 +- .../registry/PaperRegistryListenerManager.java | 41 +++---- .../paper/registry/WritableCraftRegistry.java | 19 ++-- .../paper/registry/entry/AddableRegistryEntry.java | 41 ------- .../paper/registry/entry/ApiRegistryEntry.java | 27 ----- .../paper/registry/entry/BaseRegistryEntry.java | 27 ----- .../paper/registry/entry/CraftRegistryEntry.java | 51 --------- .../registry/entry/ModifiableRegistryEntry.java | 29 ----- .../paper/registry/entry/RegistryEntry.java | 86 ++------------- .../paper/registry/entry/RegistryEntryBuilder.java | 28 ++++- .../paper/registry/entry/RegistryEntryImpl.java | 13 +++ .../paper/registry/entry/RegistryEntryInfo.java | 12 -- .../paper/registry/entry/RegistryEntryMeta.java | 122 +++++++++++++++++++++ .../registry/entry/WritableRegistryEntry.java | 25 ----- .../registry/legacy/DelayedRegistryEntry.java | 16 +-- .../java/org/bukkit/craftbukkit/CraftRegistry.java | 6 +- .../paper/registry/RegistryBuilderTest.java | 15 +-- 19 files changed, 220 insertions(+), 357 deletions(-) delete mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/AddableRegistryEntry.java delete mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/ApiRegistryEntry.java delete mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/BaseRegistryEntry.java delete mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/CraftRegistryEntry.java delete mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/ModifiableRegistryEntry.java create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryImpl.java delete mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryInfo.java create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java delete mode 100644 paper-server/src/main/java/io/papermc/paper/registry/entry/WritableRegistryEntry.java diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java index 3ebc3dbc86..a41356e136 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -104,7 +104,7 @@ public final class PaperRegistries { start(Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN).craft(TrimPattern.class, CraftTrimPattern::new).build().delayed(), start(Registries.DAMAGE_TYPE, RegistryKey.DAMAGE_TYPE).craft(DamageType.class, CraftDamageType::new).build().delayed(), start(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT).craft(Wolf.Variant.class, CraftWolf.CraftVariant::new).build().delayed(), - start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).writable(PaperEnchantmentRegistryEntry.PaperBuilder::new).withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(), + start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).serializationUpdater(FieldRename.ENCHANTMENT_RENAME).writable(PaperEnchantmentRegistryEntry.PaperBuilder::new).delayed(), start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).build().delayed(), start(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN).craft(PatternType.class, CraftPatternType::new).build().delayed(), start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java index ed071ed34e..3be7e0a1fb 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java @@ -1,7 +1,7 @@ package io.papermc.paper.registry; -import io.papermc.paper.registry.entry.ApiRegistryEntry; import io.papermc.paper.registry.entry.RegistryEntry; +import io.papermc.paper.registry.entry.RegistryEntryMeta; import io.papermc.paper.registry.legacy.DelayedRegistry; import io.papermc.paper.registry.legacy.DelayedRegistryEntry; import io.papermc.paper.registry.legacy.LegacyRegistryIdentifiers; @@ -31,7 +31,10 @@ public class PaperRegistryAccess implements RegistryAccess { @VisibleForTesting public Set> getLoadedServerBackedRegistries() { - return this.registries.keySet().stream().filter(registryHolder -> !(PaperRegistries.getEntry(registryHolder) instanceof ApiRegistryEntry)).collect(Collectors.toUnmodifiableSet()); + return this.registries.keySet().stream().filter(registryHolder -> { + final RegistryEntry entry = PaperRegistries.getEntry(registryHolder); + return entry != null && !(entry.meta() instanceof RegistryEntryMeta.ApiOnly); + }).collect(Collectors.toUnmodifiableSet()); } @SuppressWarnings("unchecked") diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilder.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilder.java index 6a60d7b7ed..a3cb9a4209 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilder.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilder.java @@ -12,14 +12,8 @@ public interface PaperRegistryBuilder extends RegistryBuilder { B fill(Conversions conversions, @Nullable M nms); - default Factory asFactory() { - return (lookup) -> this.fill(lookup, null); + default B create(final Conversions conversions) { + return this.fill(conversions, null); } } - - @FunctionalInterface - interface Factory> { - - B create(Conversions conversions); - } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java index 4f98c15d40..540aaa0964 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java @@ -9,7 +9,7 @@ import io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.entry.RegistryEntry; -import io.papermc.paper.registry.entry.RegistryEntryInfo; +import io.papermc.paper.registry.entry.RegistryEntryMeta; import io.papermc.paper.registry.event.RegistryEntryAddEventImpl; import io.papermc.paper.registry.event.RegistryEventMap; import io.papermc.paper.registry.event.RegistryEventProvider; @@ -28,6 +28,7 @@ import net.minecraft.core.WritableRegistry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import org.bukkit.Keyed; import org.intellij.lang.annotations.Subst; import org.jspecify.annotations.Nullable; @@ -86,8 +87,7 @@ public class PaperRegistryListenerManager { this.registerWithListeners(registry, key, nms, registrationInfo, WritableRegistry::register, conversions); } - // TODO remove Keyed - public , R> R registerWithListeners( + public , R> R registerWithListeners( // TODO remove Keyed final Registry registry, final ResourceKey key, final M nms, @@ -96,34 +96,33 @@ public class PaperRegistryListenerManager { final Conversions conversions ) { Preconditions.checkState(LaunchEntryPointHandler.INSTANCE.hasEntered(Entrypoint.BOOTSTRAPPER), registry.key() + " tried to run modification listeners before bootstrappers have been called"); // verify that bootstrappers have been called - final RegistryEntryInfo entry = PaperRegistries.getEntry(registry.key()); - if (!RegistryEntry.Modifiable.isModifiable(entry) || !this.valueAddEventTypes.hasHandlers(entry.apiKey())) { + final RegistryEntry entry = PaperRegistries.getEntry(registry.key()); + if (entry == null || !entry.meta().modificationApiSupport().canModify() || !this.valueAddEventTypes.hasHandlers(entry.apiKey())) { return registerMethod.register((WritableRegistry) registry, key, nms, registrationInfo); } - final RegistryEntry.Modifiable modifiableEntry = RegistryEntry.Modifiable.asModifiable(entry); - @SuppressWarnings("PatternValidation") final TypedKey typedKey = TypedKey.create(entry.apiKey(), Key.key(key.location().getNamespace(), key.location().getPath())); - final B builder = modifiableEntry.fillBuilder(conversions, nms); + final RegistryEntryMeta.Buildable modifiableEntry = (RegistryEntryMeta.Buildable) entry.meta(); + final B builder = modifiableEntry.builderFiller().fill(conversions, nms); return this.registerWithListeners(registry, modifiableEntry, key, nms, builder, registrationInfo, registerMethod, conversions); } - > void registerWithListeners( // TODO remove Keyed + > void registerWithListeners( // TODO remove Keyed final WritableRegistry registry, - final RegistryEntryInfo entry, + final RegistryEntryMeta.Buildable entry, final ResourceKey key, final B builder, final RegistrationInfo registrationInfo, final Conversions conversions ) { - if (!RegistryEntry.Modifiable.isModifiable(entry) || !this.valueAddEventTypes.hasHandlers(entry.apiKey())) { + if (!entry.modificationApiSupport().canModify() || !this.valueAddEventTypes.hasHandlers(entry.apiKey())) { registry.register(key, builder.build(), registrationInfo); return; } - this.registerWithListeners(registry, RegistryEntry.Modifiable.asModifiable(entry), key, null, builder, registrationInfo, WritableRegistry::register, conversions); + this.registerWithListeners(registry, entry, key, null, builder, registrationInfo, WritableRegistry::register, conversions); } - public , R> R registerWithListeners( // TODO remove Keyed + public , R> R registerWithListeners( // TODO remove Keyed final Registry registry, - final RegistryEntry.Modifiable entry, + final RegistryEntryMeta.Buildable entry, final ResourceKey key, final @Nullable M oldNms, final B builder, @@ -156,26 +155,28 @@ public class PaperRegistryListenerManager { R register(WritableRegistry writableRegistry, ResourceKey key, M value, RegistrationInfo registrationInfo); } - public > void runFreezeListeners(final ResourceKey> resourceKey, final Conversions conversions) { - final RegistryEntryInfo entry = PaperRegistries.getEntry(resourceKey); - if (!RegistryEntry.Addable.isAddable(entry) || !this.freezeEventTypes.hasHandlers(entry.apiKey())) { + public > void runFreezeListeners(final ResourceKey> resourceKey, final Conversions conversions) { + final RegistryEntry entry = PaperRegistries.getEntry(resourceKey); + if (entry == null || !entry.meta().modificationApiSupport().canAdd() || !this.freezeEventTypes.hasHandlers(entry.apiKey())) { return; } - final RegistryEntry.Addable writableEntry = RegistryEntry.Addable.asAddable(entry); + final RegistryEntryMeta.Buildable writableEntry = (RegistryEntryMeta.Buildable) entry.meta(); final WritableCraftRegistry writableRegistry = PaperRegistryAccess.instance().getWritableRegistry(entry.apiKey()); final RegistryFreezeEventImpl event = writableEntry.createFreezeEvent(writableRegistry, conversions); LifecycleEventRunner.INSTANCE.callEvent(this.freezeEventTypes.getEventType(entry.apiKey()), event); } public > RegistryEntryAddEventType getRegistryValueAddEventType(final RegistryEventProvider type) { - if (!RegistryEntry.Modifiable.isModifiable(PaperRegistries.getEntry(type.registryKey()))) { + final RegistryEntry entry = PaperRegistries.getEntry(type.registryKey()); + if (entry == null || !entry.meta().modificationApiSupport().canModify()) { throw new IllegalArgumentException(type.registryKey() + " does not support RegistryEntryAddEvent"); } return this.valueAddEventTypes.getOrCreate(type.registryKey(), RegistryEntryAddEventTypeImpl::new); } public > LifecycleEventType.Prioritizable> getRegistryFreezeEventType(final RegistryEventProvider type) { - if (!RegistryEntry.Addable.isAddable(PaperRegistries.getEntry(type.registryKey()))) { + final RegistryEntry entry = PaperRegistries.getEntry(type.registryKey()); + if (entry == null || !entry.meta().modificationApiSupport().canAdd()) { throw new IllegalArgumentException(type.registryKey() + " does not support RegistryFreezeEvent"); } return this.freezeEventTypes.getOrCreate(type.registryKey(), RegistryLifecycleEventType::new); diff --git a/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java index f201f14250..6c17623e76 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java @@ -3,6 +3,7 @@ package io.papermc.paper.registry; import com.mojang.serialization.Lifecycle; import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.entry.RegistryEntry; +import io.papermc.paper.registry.entry.RegistryEntryMeta; import io.papermc.paper.registry.entry.RegistryTypeMapper; import io.papermc.paper.registry.event.WritableRegistry; import java.util.Optional; @@ -20,22 +21,16 @@ public class WritableCraftRegistry entry; + private final RegistryEntryMeta.Buildable meta; private final MappedRegistry registry; - private final PaperRegistryBuilder.Factory builderFactory; public WritableCraftRegistry( - final RegistryEntry.BuilderHolder entry, - final Class classToPreload, final MappedRegistry registry, - final BiFunction serializationUpdater, - final PaperRegistryBuilder.Factory builderFactory, - final RegistryTypeMapper minecraftToBukkit + final RegistryEntryMeta.Buildable meta ) { - super(classToPreload, registry, minecraftToBukkit, serializationUpdater); - this.entry = entry; + super(meta, registry); this.registry = registry; - this.builderFactory = builderFactory; + this.meta = meta; } public void register(final TypedKey key, final Consumer value, final Conversions conversions) { @@ -45,7 +40,7 @@ public class WritableCraftRegistry { diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/AddableRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/AddableRegistryEntry.java deleted file mode 100644 index c44edcf13e..0000000000 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/AddableRegistryEntry.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.papermc.paper.registry.entry; - -import io.papermc.paper.registry.PaperRegistryBuilder; -import io.papermc.paper.registry.RegistryHolder; -import io.papermc.paper.registry.RegistryKey; -import io.papermc.paper.registry.WritableCraftRegistry; -import io.papermc.paper.registry.data.util.Conversions; -import net.minecraft.core.MappedRegistry; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import org.bukkit.Keyed; - -public class AddableRegistryEntry> extends CraftRegistryEntry implements RegistryEntry.Addable { - - private final PaperRegistryBuilder.Filler builderFiller; - - protected AddableRegistryEntry( - final ResourceKey> mcKey, - final RegistryKey apiKey, - final Class classToPreload, - final RegistryTypeMapper minecraftToBukkit, - final PaperRegistryBuilder.Filler builderFiller - ) { - super(mcKey, apiKey, classToPreload, minecraftToBukkit); - this.builderFiller = builderFiller; - } - - private WritableCraftRegistry createRegistry(final Registry registry) { - return new WritableCraftRegistry<>(this, this.classToPreload, (MappedRegistry) registry, this.updater, this.builderFiller.asFactory(), this.minecraftToBukkit); - } - - @Override - public RegistryHolder createRegistryHolder(final Registry nmsRegistry) { - return new RegistryHolder.Memoized<>(() -> this.createRegistry(nmsRegistry)); - } - - @Override - public B fillBuilder(final Conversions conversions, final M nms) { - return this.builderFiller.fill(conversions, nms); - } -} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/ApiRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/ApiRegistryEntry.java deleted file mode 100644 index 2295b0d145..0000000000 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/ApiRegistryEntry.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.papermc.paper.registry.entry; - -import io.papermc.paper.registry.RegistryHolder; -import io.papermc.paper.registry.RegistryKey; -import java.util.function.Supplier; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import org.bukkit.Keyed; - -public class ApiRegistryEntry extends BaseRegistryEntry { - - private final Supplier> registrySupplier; - - protected ApiRegistryEntry( - final ResourceKey> mcKey, - final RegistryKey apiKey, - final Supplier> registrySupplier - ) { - super(mcKey, apiKey); - this.registrySupplier = registrySupplier; - } - - @Override - public RegistryHolder createRegistryHolder(final Registry nmsRegistry) { - return new RegistryHolder.Memoized<>(this.registrySupplier); - } -} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/BaseRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/BaseRegistryEntry.java deleted file mode 100644 index ceb217dbbb..0000000000 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/BaseRegistryEntry.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.papermc.paper.registry.entry; - -import io.papermc.paper.registry.RegistryKey; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import org.bukkit.Keyed; - -public abstract class BaseRegistryEntry implements RegistryEntry { // TODO remove Keyed - - private final ResourceKey> minecraftRegistryKey; - private final RegistryKey apiRegistryKey; - - protected BaseRegistryEntry(final ResourceKey> minecraftRegistryKey, final RegistryKey apiRegistryKey) { - this.minecraftRegistryKey = minecraftRegistryKey; - this.apiRegistryKey = apiRegistryKey; - } - - @Override - public final ResourceKey> mcKey() { - return this.minecraftRegistryKey; - } - - @Override - public final RegistryKey apiKey() { - return this.apiRegistryKey; - } -} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/CraftRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/CraftRegistryEntry.java deleted file mode 100644 index d8b28e823a..0000000000 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/CraftRegistryEntry.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.papermc.paper.registry.entry; - -import com.google.common.base.Preconditions; -import com.mojang.datafixers.util.Either; -import io.papermc.paper.registry.RegistryHolder; -import io.papermc.paper.registry.RegistryKey; -import java.util.function.BiFunction; -import java.util.function.Function; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import org.bukkit.Keyed; -import org.bukkit.NamespacedKey; -import org.bukkit.craftbukkit.CraftRegistry; -import org.bukkit.craftbukkit.util.ApiVersion; - -public class CraftRegistryEntry extends BaseRegistryEntry { // TODO remove Keyed - - private static final BiFunction EMPTY = (namespacedKey, apiVersion) -> namespacedKey; - - protected final Class classToPreload; - protected final RegistryTypeMapper minecraftToBukkit; - protected BiFunction updater = EMPTY; - - protected CraftRegistryEntry( - final ResourceKey> mcKey, - final RegistryKey apiKey, - final Class classToPreload, - final RegistryTypeMapper minecraftToBukkit - ) { - super(mcKey, apiKey); - Preconditions.checkArgument(!classToPreload.getPackageName().startsWith("net.minecraft"), classToPreload + " should not be in the net.minecraft package as the class-to-preload"); - this.classToPreload = classToPreload; - this.minecraftToBukkit = minecraftToBukkit; - } - - @Override - public RegistryEntry withSerializationUpdater(final BiFunction updater) { - this.updater = updater; - return this; - } - - @Override - public RegistryHolder createRegistryHolder(final Registry nmsRegistry) { - return new RegistryHolder.Memoized<>(() -> this.createApiRegistry(nmsRegistry)); - } - - private CraftRegistry createApiRegistry(final Registry nmsRegistry) { - return new CraftRegistry<>(this.classToPreload, nmsRegistry, this.minecraftToBukkit, this.updater); - } -} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/ModifiableRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/ModifiableRegistryEntry.java deleted file mode 100644 index 4254335e55..0000000000 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/ModifiableRegistryEntry.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.papermc.paper.registry.entry; - -import io.papermc.paper.registry.PaperRegistryBuilder; -import io.papermc.paper.registry.RegistryKey; -import io.papermc.paper.registry.data.util.Conversions; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import org.bukkit.Keyed; - -public class ModifiableRegistryEntry> extends CraftRegistryEntry implements RegistryEntry.Modifiable { - - protected final PaperRegistryBuilder.Filler builderFiller; - - protected ModifiableRegistryEntry( - final ResourceKey> mcKey, - final RegistryKey apiKey, - final Class toPreload, - final RegistryTypeMapper minecraftToBukkit, - final PaperRegistryBuilder.Filler builderFiller - ) { - super(mcKey, apiKey, toPreload, minecraftToBukkit); - this.builderFiller = builderFiller; - } - - @Override - public B fillBuilder(final Conversions conversions, final M nms) { - return this.builderFiller.fill(conversions, nms); - } -} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java index 32089721ed..17c7ec77cf 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java @@ -1,27 +1,24 @@ package io.papermc.paper.registry.entry; -import io.papermc.paper.registry.PaperRegistryBuilder; import io.papermc.paper.registry.RegistryHolder; import io.papermc.paper.registry.RegistryKey; -import io.papermc.paper.registry.TypedKey; -import io.papermc.paper.registry.WritableCraftRegistry; -import io.papermc.paper.registry.data.util.Conversions; -import io.papermc.paper.registry.event.RegistryEntryAddEventImpl; -import io.papermc.paper.registry.event.RegistryFreezeEventImpl; import io.papermc.paper.registry.legacy.DelayedRegistryEntry; -import java.util.function.BiFunction; import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; -import org.bukkit.NamespacedKey; -import org.bukkit.craftbukkit.util.ApiVersion; -import org.jspecify.annotations.Nullable; -public interface RegistryEntry extends RegistryEntryInfo { // TODO remove Keyed +public interface RegistryEntry { // TODO remove Keyed - RegistryHolder createRegistryHolder(Registry nmsRegistry); + RegistryHolder createRegistryHolder(Registry nmsRegistry); - default RegistryEntry withSerializationUpdater(final BiFunction updater) { - return this; + RegistryEntryMeta meta(); + + default RegistryKey apiKey() { + return this.meta().apiKey(); + } + + default ResourceKey> mcKey() { + return this.meta().mcKey(); } /** @@ -30,66 +27,7 @@ public interface RegistryEntry extends RegistryEntryInfo delayed() { + default RegistryEntry delayed() { return new DelayedRegistryEntry<>(this); } - - interface BuilderHolder> extends RegistryEntryInfo { - - B fillBuilder(Conversions conversions, M nms); - } - - /** - * Can mutate values being added to the registry - */ - interface Modifiable> extends BuilderHolder { - - static boolean isModifiable(final @Nullable RegistryEntryInfo entry) { - return entry instanceof RegistryEntry.Modifiable || (entry instanceof final DelayedRegistryEntry delayed && delayed.delegate() instanceof RegistryEntry.Modifiable); - } - - static > Modifiable asModifiable(final RegistryEntryInfo entry) { // TODO remove Keyed - return (Modifiable) possiblyUnwrap(entry); - } - - default RegistryEntryAddEventImpl createEntryAddEvent(final TypedKey key, final B initialBuilder, final Conversions conversions) { - return new RegistryEntryAddEventImpl<>(key, initialBuilder, this.apiKey(), conversions); - } - } - - /** - * Can only add new values to the registry, not modify any values. - */ - interface Addable> extends BuilderHolder { // TODO remove Keyed - - default RegistryFreezeEventImpl createFreezeEvent(final WritableCraftRegistry writableRegistry, final Conversions conversions) { - return new RegistryFreezeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions); - } - - static boolean isAddable(final @Nullable RegistryEntryInfo entry) { - return entry instanceof RegistryEntry.Addable || (entry instanceof final DelayedRegistryEntry delayed && delayed.delegate() instanceof RegistryEntry.Addable); - } - - static > Addable asAddable(final RegistryEntryInfo entry) { - return (Addable) possiblyUnwrap(entry); - } - } - - /** - * Can mutate values and add new values. - */ - interface Writable> extends Modifiable, Addable { // TODO remove Keyed - - static boolean isWritable(final @Nullable RegistryEntryInfo entry) { - return entry instanceof RegistryEntry.Writable || (entry instanceof final DelayedRegistryEntry delayed && delayed.delegate() instanceof RegistryEntry.Writable); - } - - static > Writable asWritable(final RegistryEntryInfo entry) { // TODO remove Keyed - return (Writable) possiblyUnwrap(entry); - } - } - - private static RegistryEntryInfo possiblyUnwrap(final RegistryEntryInfo entry) { - return entry instanceof final DelayedRegistryEntry delayed ? delayed.delegate() : entry; - } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java index 5352ec936c..bb7d19ee00 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java @@ -1,6 +1,5 @@ package io.papermc.paper.registry.entry; -import com.mojang.datafixers.util.Either; import io.papermc.paper.registry.PaperRegistryBuilder; import io.papermc.paper.registry.RegistryKey; import java.util.function.BiFunction; @@ -11,6 +10,11 @@ import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.util.ApiVersion; + +import static io.papermc.paper.registry.entry.RegistryEntryMeta.RegistryModificationApiSupport.ADDABLE; +import static io.papermc.paper.registry.entry.RegistryEntryMeta.RegistryModificationApiSupport.MODIFIABLE; +import static io.papermc.paper.registry.entry.RegistryEntryMeta.RegistryModificationApiSupport.WRITABLE; public class RegistryEntryBuilder { // TODO remove Keyed @@ -30,7 +34,7 @@ public class RegistryEntryBuilder { // TODO remove Keyed } public RegistryEntry apiOnly(final Supplier> apiRegistrySupplier) { - return new ApiRegistryEntry<>(this.mcKey, this.apiKey, apiRegistrySupplier); + return new RegistryEntryImpl<>(new RegistryEntryMeta.ApiOnly<>(this.mcKey, this.apiKey, apiRegistrySupplier)); } public CraftStage craft(final Class classToPreload, final BiFunction minecraftToBukkit) { @@ -43,8 +47,11 @@ public class RegistryEntryBuilder { // TODO remove Keyed public static final class CraftStage extends RegistryEntryBuilder { // TODO remove Keyed + private static final BiFunction EMPTY = (namespacedKey, apiVersion) -> namespacedKey; + private final Class classToPreload; private final RegistryTypeMapper minecraftToBukkit; + private BiFunction serializationUpdater = EMPTY; private CraftStage( final ResourceKey> mcKey, @@ -57,20 +64,29 @@ public class RegistryEntryBuilder { // TODO remove Keyed this.minecraftToBukkit = minecraftToBukkit; } + public CraftStage serializationUpdater(final BiFunction serializationUpdater) { + this.serializationUpdater = serializationUpdater; + return this; + } + public RegistryEntry build() { - return new CraftRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit); + return new RegistryEntryImpl<>(new RegistryEntryMeta.Craft<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, this.serializationUpdater)); } public > RegistryEntry modifiable(final PaperRegistryBuilder.Filler filler) { - return new ModifiableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler); + return this.create(filler, MODIFIABLE); } public > RegistryEntry addable(final PaperRegistryBuilder.Filler filler) { - return new AddableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler); + return this.create(filler, ADDABLE); } public > RegistryEntry writable(final PaperRegistryBuilder.Filler filler) { - return new WritableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler); + return this.create(filler, WRITABLE); + } + + private > RegistryEntry create(final PaperRegistryBuilder.Filler filler, final RegistryEntryMeta.RegistryModificationApiSupport support) { + return new RegistryEntryImpl<>(new RegistryEntryMeta.Buildable<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, this.serializationUpdater, filler, support)); } } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryImpl.java new file mode 100644 index 0000000000..1c8b2d4855 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryImpl.java @@ -0,0 +1,13 @@ +package io.papermc.paper.registry.entry; + +import io.papermc.paper.registry.RegistryHolder; +import net.minecraft.core.Registry; +import org.bukkit.Keyed; + +record RegistryEntryImpl(RegistryEntryMeta meta) implements RegistryEntry { + + @Override + public RegistryHolder createRegistryHolder(final Registry nmsRegistry) { + return new RegistryHolder.Memoized<>(() -> this.meta().createApiRegistry(nmsRegistry)); + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryInfo.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryInfo.java deleted file mode 100644 index 0ae855e80f..0000000000 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryInfo.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.papermc.paper.registry.entry; - -import io.papermc.paper.registry.RegistryKey; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; - -public interface RegistryEntryInfo { - - ResourceKey> mcKey(); - - RegistryKey apiKey(); -} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java new file mode 100644 index 0000000000..7cd152734f --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java @@ -0,0 +1,122 @@ +package io.papermc.paper.registry.entry; + +import com.google.common.base.Preconditions; +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.WritableCraftRegistry; +import io.papermc.paper.registry.data.util.Conversions; +import io.papermc.paper.registry.event.RegistryEntryAddEventImpl; +import io.papermc.paper.registry.event.RegistryFreezeEventImpl; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.CraftRegistry; +import org.bukkit.craftbukkit.util.ApiVersion; + +public sealed interface RegistryEntryMeta permits RegistryEntryMeta.ApiOnly, RegistryEntryMeta.ServerSide { // TODO remove Keyed + + ResourceKey> mcKey(); + + RegistryKey apiKey(); + + org.bukkit.Registry createApiRegistry(final Registry nmsRegistry); + + default RegistryModificationApiSupport modificationApiSupport() { + return RegistryModificationApiSupport.NONE; + } + + record ApiOnly(ResourceKey> mcKey, RegistryKey apiKey, Supplier> registrySupplier) implements RegistryEntryMeta { // TODO remove Keyed + + @Override + public org.bukkit.Registry createApiRegistry(final Registry nmsRegistry) { + return this.registrySupplier.get(); + } + } + + sealed interface ServerSide extends RegistryEntryMeta permits RegistryEntryMeta.Craft, RegistryEntryMeta.Buildable { // TODO remove Keyed + + Class classToPreload(); + + RegistryTypeMapper registryTypeMapper(); + + BiFunction serializationUpdater(); + + default org.bukkit.Registry createApiRegistry(final Registry nmsRegistry) { + return new CraftRegistry<>(this, nmsRegistry); + } + } + + record Craft( + ResourceKey> mcKey, + RegistryKey apiKey, + Class classToPreload, + RegistryTypeMapper registryTypeMapper, + BiFunction serializationUpdater + ) implements ServerSide { // TODO remove Keyed + + public Craft { + Preconditions.checkArgument(!classToPreload.getPackageName().startsWith("net.minecraft"), classToPreload + " should not be in the net.minecraft package as the class-to-preload"); + } + } + + enum RegistryModificationApiSupport { + /** + * Cannot add or modify values in the registry. + */ + NONE, + /** + * Can only add new values to the registry, not modify any values. + */ + ADDABLE, + /** + * Can mutate values being added to the registry + */ + MODIFIABLE, + /** + * Can mutate values and add new values. + */ + WRITABLE, + ; + + public boolean canAdd() { + return this != MODIFIABLE && this != NONE; + } + + public boolean canModify() { + return this != ADDABLE && this != NONE; + } + } + + record Buildable>( // TODO remove Keyed + ResourceKey> mcKey, + RegistryKey apiKey, + Class classToPreload, + RegistryTypeMapper registryTypeMapper, + BiFunction serializationUpdater, + PaperRegistryBuilder.Filler builderFiller, + RegistryModificationApiSupport modificationApiSupport + ) implements ServerSide { + + public RegistryEntryAddEventImpl createEntryAddEvent(final TypedKey key, final B initialBuilder, final Conversions conversions) { + return new RegistryEntryAddEventImpl<>(key, initialBuilder, this.apiKey(), conversions); + } + + public RegistryFreezeEventImpl createFreezeEvent(final WritableCraftRegistry writableRegistry, final Conversions conversions) { + return new RegistryFreezeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions); + } + + @Override + public org.bukkit.Registry createApiRegistry(final Registry nmsRegistry) { + if (this.modificationApiSupport.canAdd()) { + return new WritableCraftRegistry<>((MappedRegistry) nmsRegistry, this); + } else { + return ServerSide.super.createApiRegistry(nmsRegistry); + } + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/WritableRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/WritableRegistryEntry.java deleted file mode 100644 index 7ff5dbea3f..0000000000 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/WritableRegistryEntry.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.papermc.paper.registry.entry; - -import com.mojang.datafixers.util.Either; -import io.papermc.paper.registry.PaperRegistryBuilder; -import io.papermc.paper.registry.RegistryKey; -import java.util.function.BiFunction; -import java.util.function.Function; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import org.bukkit.Keyed; -import org.bukkit.NamespacedKey; - -public class WritableRegistryEntry> extends AddableRegistryEntry implements RegistryEntry.Writable { // TODO remove Keyed - - protected WritableRegistryEntry( - final ResourceKey> mcKey, - final RegistryKey apiKey, - final Class classToPreload, - final RegistryTypeMapper minecraftToBukkit, - final PaperRegistryBuilder.Filler builderFiller - ) { - super(mcKey, apiKey, classToPreload, minecraftToBukkit, builderFiller); - } -} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistryEntry.java index 110b8d559f..168afab750 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistryEntry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistryEntry.java @@ -1,26 +1,20 @@ package io.papermc.paper.registry.legacy; import io.papermc.paper.registry.RegistryHolder; -import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.entry.RegistryEntry; +import io.papermc.paper.registry.entry.RegistryEntryMeta; import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; -public record DelayedRegistryEntry(RegistryEntry delegate) implements RegistryEntry { +public record DelayedRegistryEntry(RegistryEntry delegate) implements RegistryEntry { @Override - public ResourceKey> mcKey() { - return this.delegate.mcKey(); + public RegistryEntryMeta meta() { + return this.delegate.meta(); } @Override - public RegistryKey apiKey() { - return this.delegate.apiKey(); - } - - @Override - public RegistryHolder createRegistryHolder(final Registry nmsRegistry) { + public RegistryHolder createRegistryHolder(final Registry nmsRegistry) { return this.delegate.createRegistryHolder(nmsRegistry); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index a94cebfd26..332215f8b4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; +import io.papermc.paper.registry.entry.RegistryEntryMeta; import io.papermc.paper.util.Holderable; import java.util.HashMap; import java.util.Iterator; @@ -97,7 +98,7 @@ public class CraftRegistry implements Registry { // Paper start - support direct Holders final java.util.Optional> resourceKey = registry.getResourceKey(minecraft); if (resourceKey.isEmpty() && bukkitRegistry instanceof final CraftRegistry craftRegistry && craftRegistry.supportsDirectHolders()) { - return ((CraftRegistry) registry).convertDirectHolder(Holder.direct(minecraft)); + return ((CraftRegistry) bukkitRegistry).convertDirectHolder(Holder.direct(minecraft)); } else if (resourceKey.isEmpty()) { throw new IllegalStateException(String.format("Cannot convert '%s' to bukkit representation, since it is not registered.", minecraft)); } @@ -207,6 +208,9 @@ public class CraftRegistry implements Registry { // Paper start - switch to Holder this(bukkitClass, minecraftRegistry, new io.papermc.paper.registry.entry.RegistryTypeMapper<>(minecraftToBukkit), serializationUpdater); } + public CraftRegistry(final RegistryEntryMeta.ServerSide meta, final net.minecraft.core.Registry minecraftRegistry) { + this(meta.classToPreload(), minecraftRegistry, meta.registryTypeMapper(), meta.serializationUpdater()); + } public CraftRegistry(Class bukkitClass, net.minecraft.core.Registry minecraftRegistry, io.papermc.paper.registry.entry.RegistryTypeMapper minecraftToBukkit, BiFunction serializationUpdater) { // Paper - relax preload class // Paper end - support Holders this.bukkitClass = bukkitClass; diff --git a/paper-server/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java b/paper-server/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java index 55f5fc45cf..7fa18dd100 100644 --- a/paper-server/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java +++ b/paper-server/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java @@ -2,8 +2,7 @@ package io.papermc.paper.registry; import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.entry.RegistryEntry; -import io.papermc.paper.registry.entry.RegistryEntryInfo; -import io.papermc.paper.registry.legacy.DelayedRegistryEntry; +import io.papermc.paper.registry.entry.RegistryEntryMeta; import java.util.Map; import java.util.stream.Stream; import net.minecraft.core.Registry; @@ -23,21 +22,17 @@ class RegistryBuilderTest { static Stream registries() { return PaperRegistries.REGISTRY_ENTRIES.stream() - .map(RegistryBuilderTest::possiblyUnwrap) - .filter(RegistryEntry.BuilderHolder.class::isInstance) + .map(RegistryEntry::meta) + .filter(RegistryEntryMeta.Buildable.class::isInstance) .map(Arguments::arguments); } - private static RegistryEntryInfo possiblyUnwrap(final RegistryEntryInfo entry) { - return entry instanceof final DelayedRegistryEntry delayed ? delayed.delegate() : entry; - } - @ParameterizedTest @MethodSource("registries") - void testEquality(final RegistryEntry.BuilderHolder registryEntry) { + void testEquality(final RegistryEntryMeta.Buildable registryEntry) { // TODO remove Keyed final Registry registry = RegistryHelper.getRegistry().lookupOrThrow(registryEntry.mcKey()); for (final Map.Entry, M> entry : registry.entrySet()) { - final M built = registryEntry.fillBuilder(new Conversions(new RegistryOps.HolderLookupAdapter(RegistryHelper.getRegistry())), entry.getValue()).build(); + final M built = registryEntry.builderFiller().fill(new Conversions(new RegistryOps.HolderLookupAdapter(RegistryHelper.getRegistry())), entry.getValue()).build(); assertEquals(entry.getValue(), built); } } -- cgit v1.2.3