Tag Lifecycle Events (#10993)

* wip tags

* use generics in tag registrars

* comment out varargs methods for now

* split up patch

* cache loaded service provider

* finish renames

* use builderWithExpectedSize

* finalize
This commit is contained in:
Jake Potrebic
2024-09-08 11:56:09 -07:00
parent a21216b976
commit 969432263f
8 changed files with 1013 additions and 48 deletions

View File

@@ -134,12 +134,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.intellij.lang.annotations.Subst;
+
+public final class PaperRegistryListenerManager {
+public class PaperRegistryListenerManager {
+
+ public static final PaperRegistryListenerManager INSTANCE = new PaperRegistryListenerManager();
+
+ public final RegistryEventMap valueAddHooks = new RegistryEventMap("value add");
+ public final RegistryEventMap freezeHooks = new RegistryEventMap("freeze");
+ public final RegistryEventMap valueAddEventTypes = new RegistryEventMap("value add");
+ public final RegistryEventMap freezeEventTypes = new RegistryEventMap("freeze");
+
+ private PaperRegistryListenerManager() {
+ }
@@ -200,7 +200,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ) {
+ 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 @Nullable RegistryEntryInfo<M, T> entry = PaperRegistries.getEntry(registry.key());
+ if (!RegistryEntry.Modifiable.isModifiable(entry) || !this.valueAddHooks.hasHooks(entry.apiKey())) {
+ if (!RegistryEntry.Modifiable.isModifiable(entry) || !this.valueAddEventTypes.hasHandlers(entry.apiKey())) {
+ return registerMethod.register((WritableRegistry<M>) registry, key, nms, registrationInfo);
+ }
+ final RegistryEntry.Modifiable<M, T, B> modifiableEntry = RegistryEntry.Modifiable.asModifiable(entry);
@@ -217,7 +217,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final RegistrationInfo registrationInfo,
+ final Conversions conversions
+ ) {
+ if (!RegistryEntry.Modifiable.isModifiable(entry) || !this.valueAddHooks.hasHooks(entry.apiKey())) {
+ if (!RegistryEntry.Modifiable.isModifiable(entry) || !this.valueAddEventTypes.hasHandlers(entry.apiKey())) {
+ registry.register(key, builder.build(), registrationInfo);
+ return;
+ }
@@ -237,7 +237,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ @Subst("namespace:key") final ResourceLocation beingAdded = key.location();
+ @SuppressWarnings("PatternValidation") final TypedKey<T> typedKey = TypedKey.create(entry.apiKey(), Key.key(beingAdded.getNamespace(), beingAdded.getPath()));
+ final RegistryEntryAddEventImpl<T, B> event = entry.createEntryAddEvent(typedKey, builder, conversions);
+ LifecycleEventRunner.INSTANCE.callEvent(this.valueAddHooks.getHook(entry.apiKey()), event);
+ LifecycleEventRunner.INSTANCE.callEvent(this.valueAddEventTypes.getEventType(entry.apiKey()), event);
+ if (oldNms != null) {
+ ((MappedRegistry<M>) registry).clearIntrusiveHolder(oldNms);
+ }
@@ -261,27 +261,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ public <M, T extends org.bukkit.Keyed, B extends PaperRegistryBuilder<M, T>> void runFreezeListeners(final ResourceKey<? extends Registry<M>> resourceKey, final Conversions conversions) {
+ final @Nullable RegistryEntryInfo<M, T> entry = PaperRegistries.getEntry(resourceKey);
+ if (!RegistryEntry.Addable.isAddable(entry) || !this.freezeHooks.hasHooks(entry.apiKey())) {
+ if (!RegistryEntry.Addable.isAddable(entry) || !this.freezeEventTypes.hasHandlers(entry.apiKey())) {
+ return;
+ }
+ final RegistryEntry.Addable<M, T, B> writableEntry = RegistryEntry.Addable.asAddable(entry);
+ final WritableCraftRegistry<M, T, B> writableRegistry = PaperRegistryAccess.instance().getWritableRegistry(entry.apiKey());
+ final RegistryFreezeEventImpl<T, B> event = writableEntry.createFreezeEvent(writableRegistry, conversions);
+ LifecycleEventRunner.INSTANCE.callEvent(this.freezeHooks.getHook(entry.apiKey()), event);
+ LifecycleEventRunner.INSTANCE.callEvent(this.freezeEventTypes.getEventType(entry.apiKey()), event);
+ }
+
+ public <T, B extends RegistryBuilder<T>> RegistryEntryAddEventType<T, B> getRegistryValueAddEventType(final RegistryEventProvider<T, B> type) {
+ if (!RegistryEntry.Modifiable.isModifiable(PaperRegistries.getEntry(type.registryKey()))) {
+ throw new IllegalArgumentException(type.registryKey() + " does not support RegistryEntryAddEvent");
+ }
+ return this.valueAddHooks.getOrCreate(type, RegistryEntryAddEventTypeImpl::new);
+ return this.valueAddEventTypes.getOrCreate(type.registryKey(), RegistryEntryAddEventTypeImpl::new);
+ }
+
+ public <T, B extends RegistryBuilder<T>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryFreezeEvent<T, B>> getRegistryFreezeEventType(final RegistryEventProvider<T, B> type) {
+ if (!RegistryEntry.Addable.isAddable(PaperRegistries.getEntry(type.registryKey()))) {
+ throw new IllegalArgumentException(type.registryKey() + " does not support RegistryFreezeEvent");
+ }
+ return this.freezeHooks.getOrCreate(type, RegistryLifecycleEventType::new);
+ return this.freezeEventTypes.getOrCreate(type.registryKey(), RegistryLifecycleEventType::new);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java b/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java
@@ -702,9 +702,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.registry.event;
+
+import io.papermc.paper.plugin.bootstrap.BootstrapContext;
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner;
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
+import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
+import io.papermc.paper.registry.RegistryBuilder;
+import io.papermc.paper.registry.RegistryKey;
+import java.util.HashMap;
+import java.util.Map;
@@ -713,7 +714,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+public final class RegistryEventMap {
+
+ private final Map<RegistryKey<?>, LifecycleEventType<BootstrapContext, ? extends RegistryEvent<?>, ?>> hooks = new HashMap<>();
+ private final Map<RegistryKey<?>, LifecycleEventType<BootstrapContext, ? extends LifecycleEvent, ?>> eventTypes = new HashMap<>();
+ private final String name;
+
+ public RegistryEventMap(final String name) {
@@ -721,25 +722,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T, B extends RegistryBuilder<T>, E extends RegistryEvent<T>, ET extends LifecycleEventType<BootstrapContext, E, ?>> ET getOrCreate(final RegistryEventProvider<T, B> type, final BiFunction<? super RegistryEventProvider<T, B>, ? super String, ET> eventTypeCreator) {
+ final ET registerHook;
+ if (this.hooks.containsKey(type.registryKey())) {
+ registerHook = (ET) this.hooks.get(type.registryKey());
+ public <T, E extends LifecycleEvent, ET extends LifecycleEventType<BootstrapContext, E, ?>> ET getOrCreate(final RegistryKey<T> registryKey, final BiFunction<? super RegistryKey<T>, ? super String, ET> eventTypeCreator) {
+ final ET eventType;
+ if (this.eventTypes.containsKey(registryKey)) {
+ eventType = (ET) this.eventTypes.get(registryKey);
+ } else {
+ registerHook = eventTypeCreator.apply(type, this.name);
+ LifecycleEventRunner.INSTANCE.addEventType(registerHook);
+ this.hooks.put(type.registryKey(), registerHook);
+ eventType = eventTypeCreator.apply(registryKey, this.name);
+ LifecycleEventRunner.INSTANCE.addEventType(eventType);
+ this.eventTypes.put(registryKey, eventType);
+ }
+ return registerHook;
+ return eventType;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T, E extends RegistryEvent<T>> LifecycleEventType<BootstrapContext, E, ?> getHook(final RegistryKey<T> registryKey) {
+ return (LifecycleEventType<BootstrapContext, E, ?>) Objects.requireNonNull(this.hooks.get(registryKey), "No hook for " + registryKey);
+ public <T, E extends LifecycleEvent> LifecycleEventType<BootstrapContext, E, ?> getEventType(final RegistryKey<T> registryKey) {
+ return (LifecycleEventType<BootstrapContext, E, ?>) Objects.requireNonNull(this.eventTypes.get(registryKey), "No hook for " + registryKey);
+ }
+
+ public boolean hasHooks(final RegistryKey<?> registryKey) {
+ return this.hooks.containsKey(registryKey);
+ public boolean hasHandlers(final RegistryKey<?> registryKey) {
+ final AbstractLifecycleEventType<?, ?, ?> type = ((AbstractLifecycleEventType<?, ?, ?>) this.eventTypes.get(registryKey));
+ return type != null && type.hasHandlers();
+ }
+
+}
@@ -830,15 +832,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
+import io.papermc.paper.plugin.lifecycle.event.types.PrioritizableLifecycleEventType;
+import io.papermc.paper.registry.RegistryBuilder;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.event.RegistryEntryAddEvent;
+import io.papermc.paper.registry.event.RegistryEventProvider;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+public class RegistryEntryAddEventTypeImpl<T, B extends RegistryBuilder<T>> extends PrioritizableLifecycleEventType<BootstrapContext, RegistryEntryAddEvent<T, B>, RegistryEntryAddConfiguration<T>> implements RegistryEntryAddEventType<T, B> {
+
+ public RegistryEntryAddEventTypeImpl(final RegistryEventProvider<T, B> type, final String eventName) {
+ super(type.registryKey() + " / " + eventName, BootstrapContext.class);
+ public RegistryEntryAddEventTypeImpl(final RegistryKey<T> registryKey, final String eventName) {
+ super(registryKey + " / " + eventName, BootstrapContext.class);
+ }
+
+ @Override
@@ -914,14 +916,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+import io.papermc.paper.plugin.bootstrap.BootstrapContext;
+import io.papermc.paper.plugin.lifecycle.event.types.PrioritizableLifecycleEventType;
+import io.papermc.paper.registry.RegistryBuilder;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.event.RegistryEvent;
+import io.papermc.paper.registry.event.RegistryEventProvider;
+
+public final class RegistryLifecycleEventType<T, B extends RegistryBuilder<T>, E extends RegistryEvent<T>> extends PrioritizableLifecycleEventType.Simple<BootstrapContext, E> {
+public final class RegistryLifecycleEventType<T, E extends RegistryEvent<T>> extends PrioritizableLifecycleEventType.Simple<BootstrapContext, E> {
+
+ public RegistryLifecycleEventType(final RegistryEventProvider<T, B> type, final String eventName) {
+ super(type.registryKey() + " / " + eventName, BootstrapContext.class);
+ public RegistryLifecycleEventType(final RegistryKey<T> registryKey, final String eventName) {
+ super(registryKey + " / " + eventName, BootstrapContext.class);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java b/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java