diff options
Diffstat (limited to 'patches/api/0440-Add-Lifecycle-Event-system.patch')
-rw-r--r-- | patches/api/0440-Add-Lifecycle-Event-system.patch | 646 |
1 files changed, 646 insertions, 0 deletions
diff --git a/patches/api/0440-Add-Lifecycle-Event-system.patch b/patches/api/0440-Add-Lifecycle-Event-system.patch new file mode 100644 index 0000000000..5dfac8ef46 --- /dev/null +++ b/patches/api/0440-Add-Lifecycle-Event-system.patch @@ -0,0 +1,646 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic <[email protected]> +Date: Tue, 18 Jul 2023 14:47:02 -0700 +Subject: [PATCH] Add Lifecycle Event system + +This event system is separate from Bukkit's event system and is +meant for managing resources across reloads and from points in the +PluginBootstrap. + +diff --git a/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java b/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java +index 4c47414fc08e1183b1e59369bacc4d7f7042f262..577a9d5aeae55a3b8452b6d873b51b30384c1fea 100644 +--- a/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java ++++ b/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java +@@ -1,5 +1,7 @@ + package io.papermc.paper.plugin.bootstrap; + ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; + import org.jetbrains.annotations.ApiStatus; + import org.jspecify.annotations.NullMarked; + +@@ -12,5 +14,13 @@ import org.jspecify.annotations.NullMarked; + @ApiStatus.Experimental + @NullMarked + @ApiStatus.NonExtendable +-public interface BootstrapContext extends PluginProviderContext { ++public interface BootstrapContext extends PluginProviderContext, LifecycleEventOwner { ++ ++ /** ++ * Get the lifecycle event manager for registering handlers ++ * for lifecycle events allowed on the {@link BootstrapContext}. ++ * ++ * @return the lifecycle event manager ++ */ ++ LifecycleEventManager<BootstrapContext> getLifecycleManager(); + } +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0b8eafd3e79494d4a750cd9182387fbaead24011 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java +@@ -0,0 +1,17 @@ ++package io.papermc.paper.plugin.lifecycle.event; ++ ++import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * Base type for all Lifecycle Events. ++ * <p> ++ * Lifecycle events are generally fired when the older ++ * event system is not available, like during early ++ * server initialization. ++ * @see LifecycleEvents ++ */ ++public interface LifecycleEvent { ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e05cdb7ab166f92e270ea1b85e75f465878d05f2 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java +@@ -0,0 +1,53 @@ ++package io.papermc.paper.plugin.lifecycle.event; ++ ++import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; ++import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; ++import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; ++import org.jetbrains.annotations.ApiStatus; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * Manages a plugin's lifecycle events. Can be obtained ++ * from {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext}. ++ * ++ * @param <O> the owning type, {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext} ++ */ ++@NullMarked ++public interface LifecycleEventManager<O extends LifecycleEventOwner> { ++ ++ /** ++ * Registers an event handler for a specific event type. ++ * <p> ++ * This is shorthand for creating a new {@link LifecycleEventHandlerConfiguration} and ++ * just passing in the {@link LifecycleEventHandler}. ++ * <pre>{@code ++ * LifecycleEventHandler<RegistrarEvent<Commands>> handler = new Handler(); ++ * manager.registerEventHandler(LifecycleEvents.COMMANDS, handler); ++ * }</pre> ++ * is equivalent to ++ * <pre>{@code ++ * LifecycleEventHandler<RegistrarEvent<Commands>> handler = new Handler(); ++ * manager.registerEventHandler(LifecycleEvents.COMMANDS.newHandler(handler)); ++ * }</pre> ++ * ++ * @param eventType the event type to listen to ++ * @param eventHandler the handler for that event ++ * @param <E> the type of the event object ++ */ ++ default <E extends LifecycleEvent> void registerEventHandler(final LifecycleEventType<? super O, ? extends E, ?> eventType, final LifecycleEventHandler<? super E> eventHandler) { ++ this.registerEventHandler(eventType.newHandler(eventHandler)); ++ } ++ ++ /** ++ * Registers an event handler configuration. ++ * <p> ++ * Configurations are created via {@link LifecycleEventType#newHandler(LifecycleEventHandler)}. ++ * Event types may have different configurations options available on the builder-like object ++ * returned by {@link LifecycleEventType#newHandler(LifecycleEventHandler)}. ++ * ++ * @param handlerConfiguration the handler configuration to register ++ */ ++ void registerEventHandler(LifecycleEventHandlerConfiguration<? super O> handlerConfiguration); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ce5891eb110464a1c0cd7416712110851d010a1b +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java +@@ -0,0 +1,25 @@ ++package io.papermc.paper.plugin.lifecycle.event; ++ ++import io.papermc.paper.plugin.configuration.PluginMeta; ++import org.jetbrains.annotations.ApiStatus; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * Implemented by types that are considered owners ++ * of registered handlers for lifecycle events. Generally ++ * the types that implement this interface also provide ++ * a {@link LifecycleEventManager} where you can register ++ * event handlers. ++ */ ++@NullMarked ++public interface LifecycleEventOwner { ++ ++ /** ++ * Get the plugin meta for this plugin. ++ * ++ * @return the plugin meta ++ */ ++ PluginMeta getPluginMeta(); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3093ef23dd92f86240854065f7a7bb6c11ecf4fe +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java +@@ -0,0 +1,19 @@ ++package io.papermc.paper.plugin.lifecycle.event.handler; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * A handler for a specific event. Can be implemented ++ * in a concrete class or as a lambda. ++ * ++ * @param <E> the event ++ */ ++@NullMarked ++@FunctionalInterface ++public interface LifecycleEventHandler<E extends LifecycleEvent> { ++ ++ void run(E event); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9b9f4655f222597b4e00519cfe128147bc438367 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java +@@ -0,0 +1,20 @@ ++package io.papermc.paper.plugin.lifecycle.event.handler.configuration; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; ++import org.jetbrains.annotations.ApiStatus; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * Base type for constructing configured event handlers for ++ * lifecycle events. Usually created via {@link io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType#newHandler(LifecycleEventHandler)} ++ * from event types in {@link io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents} ++ * ++ * @param <O> ++ */ ++@SuppressWarnings("unused") ++@NullMarked ++public interface LifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> { ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a2acc6e3867d6805c68e4c630aca3d14aa958a1d +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java +@@ -0,0 +1,27 @@ ++package io.papermc.paper.plugin.lifecycle.event.handler.configuration; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * Handler configuration for event types that allow "monitor" handlers. ++ * ++ * @param <O> the required owner type ++ */ ++@NullMarked ++public interface MonitorLifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> extends LifecycleEventHandlerConfiguration<O> { ++ ++ /** ++ * Sets this handler configuration to be considered a "monitor". ++ * These handlers will run last and should only be used by plugins ++ * to observe changes from previously run handlers. ++ * ++ * @return this configuration for chaining ++ */ ++ @Contract("-> this") ++ MonitorLifecycleEventHandlerConfiguration<O> monitor(); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java +new file mode 100644 +index 0000000000000000000000000000000000000000..100e5d169f1f644e54a042c697649f08fff1e6de +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java +@@ -0,0 +1,41 @@ ++package io.papermc.paper.plugin.lifecycle.event.handler.configuration; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * Handler configuration that allows both "monitor" and prioritized handlers. ++ * The default priority is 0. ++ * ++ * @param <O> the required owner type ++ */ ++@NullMarked ++public interface PrioritizedLifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> extends LifecycleEventHandlerConfiguration<O> { ++ ++ /** ++ * Sets the priority for this handler. Resets ++ * all previous calls to {@link #monitor()}. A ++ * lower numeric value correlates to the handler ++ * being run earlier. ++ * ++ * @param priority the numerical priority ++ * @return this configuration for chaining ++ */ ++ @Contract("_ -> this") ++ PrioritizedLifecycleEventHandlerConfiguration<O> priority(int priority); ++ ++ /** ++ * Sets this handler configuration to be considered a "monitor". ++ * These handlers will run last and should only be used by plugins ++ * to observe any changes from previously ran handlers. ++ * ++ * @return this configuration for chaining ++ */ ++ @Contract("-> this") ++ PrioritizedLifecycleEventHandlerConfiguration<O> monitor(); ++ ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fd9c3605a8f5e6bdd31e42f18a45154d4074eb67 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java +@@ -0,0 +1,12 @@ ++package io.papermc.paper.plugin.lifecycle.event.registrar; ++ ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * To be implemented by types that provide ways to register types ++ * either on server start or during a reload ++ */ ++public interface Registrar { ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7dca6be092a8b5deca9c45b152a96ffe72fe2533 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java +@@ -0,0 +1,28 @@ ++package io.papermc.paper.plugin.lifecycle.event.registrar; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * A lifecycle event that exposes a {@link Registrar} of some kind ++ * to allow management of various things. Look at implementations of ++ * {@link Registrar} for an idea of what uses this event. ++ * ++ * @param <R> registrar type ++ * @see ReloadableRegistrarEvent ++ */ ++@NullMarked ++public interface RegistrarEvent<R extends Registrar> extends LifecycleEvent { ++ ++ /** ++ * Get the registrar related to this event. ++ * ++ * @return the registrar ++ */ ++ @Contract(pure = true) ++ R registrar(); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9bce1c13c8092238939fbbec6b499d1ca85e5b89 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java +@@ -0,0 +1,39 @@ ++package io.papermc.paper.plugin.lifecycle.event.registrar; ++ ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * A lifecycle event that exposes a {@link Registrar} that is ++ * reloadable. ++ * ++ * @param <R> the registrar type ++ * @see RegistrarEvent ++ */ ++@NullMarked ++public interface ReloadableRegistrarEvent<R extends Registrar> extends RegistrarEvent<R> { ++ ++ /** ++ * Get the cause of this reload. ++ * ++ * @return the cause ++ */ ++ @Contract(pure = true) ++ Cause cause(); ++ ++ @ApiStatus.Experimental ++ enum Cause { ++ /** ++ * The initial load of the server. ++ */ ++ INITIAL, ++ /** ++ * A reload, triggered via one of the various mechanisms like ++ * the bukkit or minecraft reload commands. ++ */ ++ RELOAD ++ } ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..75d9e20f53735ead4fa4aec478b4b72b85ca5e1e +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java +@@ -0,0 +1,74 @@ ++package io.papermc.paper.plugin.lifecycle.event.types; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; ++import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; ++import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfiguration; ++import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * Base type for all types of lifecycle events. Differs from ++ * {@link LifecycleEvent} which is the actual event object, whereas ++ * this is an object representing the type of the event. Used ++ * to construct subtypes of {@link LifecycleEventHandlerConfiguration} for ++ * use in {@link LifecycleEventManager} ++ * ++ * @param <O> the required owner type ++ * @param <E> the event object type ++ * @param <C> the configuration type ++ */ ++@NullMarked ++public interface LifecycleEventType<O extends LifecycleEventOwner, E extends LifecycleEvent, C extends LifecycleEventHandlerConfiguration<O>> { ++ ++ /** ++ * Gets the name of the lifecycle event. ++ * ++ * @return the name ++ */ ++ @Contract(pure = true) ++ String name(); ++ ++ /** ++ * Create a configuration for this event with the specified ++ * handler. ++ * ++ * @param handler the event handler ++ * @return a new configuration ++ * @see LifecycleEventManager#registerEventHandler(LifecycleEventHandlerConfiguration) ++ */ ++ @Contract("_ -> new") ++ C newHandler(LifecycleEventHandler<? super E> handler); ++ ++ /** ++ * Lifecycle event type that supports separate registration ++ * of handlers as "monitors" that are run last. Useful ++ * if a plugin wants to only observe the changes other handlers ++ * made. ++ * ++ * @param <O> the required owner type ++ * @param <E> the event object type ++ */ ++ @ApiStatus.Experimental ++ @ApiStatus.NonExtendable ++ interface Monitorable<O extends LifecycleEventOwner, E extends LifecycleEvent> extends LifecycleEventType<O, E, MonitorLifecycleEventHandlerConfiguration<O>> { ++ } ++ ++ /** ++ * Lifecycle event type that supports both {@link Monitorable "monitors"} and ++ * specific numeric-based priorities. ++ * ++ * @param <O> the required owner type ++ * @param <E> the event object type ++ */ ++ @ApiStatus.Experimental ++ @ApiStatus.NonExtendable ++ interface Prioritizable<O extends LifecycleEventOwner, E extends LifecycleEvent> extends LifecycleEventType<O, E, PrioritizedLifecycleEventHandlerConfiguration<O>> { ++ } ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e15e09c2a4d3f43db6a0159fa8af6179362ea8d6 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java +@@ -0,0 +1,24 @@ ++package io.papermc.paper.plugin.lifecycle.event.types; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import java.util.Optional; ++import java.util.ServiceLoader; ++import org.jetbrains.annotations.ApiStatus; ++import org.jspecify.annotations.NullMarked; ++ ++@NullMarked ++interface LifecycleEventTypeProvider { ++ ++ Optional<LifecycleEventTypeProvider> INSTANCE = ServiceLoader.load(LifecycleEventTypeProvider.class) ++ .findFirst(); ++ ++ static LifecycleEventTypeProvider provider() { ++ return INSTANCE.orElseThrow(); ++ } ++ ++ <O extends LifecycleEventOwner, E extends LifecycleEvent> LifecycleEventType.Monitorable<O, E> monitor(String name, Class<? extends O> ownerType); ++ ++ <O extends LifecycleEventOwner, E extends LifecycleEvent> LifecycleEventType.Prioritizable<O, E> prioritized(String name, Class<? extends O> ownerType); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f70814de0d6c40b2c1c9921b8abdd1162e1d3995 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java +@@ -0,0 +1,54 @@ ++package io.papermc.paper.plugin.lifecycle.event.types; ++ ++import io.papermc.paper.plugin.bootstrap.BootstrapContext; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import org.bukkit.plugin.Plugin; ++import org.jetbrains.annotations.ApiStatus; ++import org.jspecify.annotations.NullMarked; ++ ++/** ++ * Holds various types of lifecycle events for ++ * use when creating event handler configurations ++ * in {@link LifecycleEventManager}. ++ */ ++@NullMarked ++public final class LifecycleEvents { ++ ++ //<editor-fold desc="helper methods" defaultstate="collapsed"> ++ @ApiStatus.Internal ++ static <E extends LifecycleEvent> LifecycleEventType.Monitorable<Plugin, E> plugin(final String name) { ++ return monitor(name, Plugin.class); ++ } ++ ++ @ApiStatus.Internal ++ static <E extends LifecycleEvent> LifecycleEventType.Prioritizable<Plugin, E> pluginPrioritized(final String name) { ++ return prioritized(name, Plugin.class); ++ } ++ ++ @ApiStatus.Internal ++ static <E extends LifecycleEvent> LifecycleEventType.Monitorable<BootstrapContext, E> bootstrap(final String name) { ++ return monitor(name, BootstrapContext.class); ++ } ++ ++ @ApiStatus.Internal ++ static <E extends LifecycleEvent> LifecycleEventType.Prioritizable<BootstrapContext, E> bootstrapPrioritized(final String name) { ++ return prioritized(name, BootstrapContext.class); ++ } ++ ++ @ApiStatus.Internal ++ static <O extends LifecycleEventOwner, E extends LifecycleEvent, O2 extends O> LifecycleEventType.Monitorable<O, E> monitor(final String name, final Class<O2> ownerType) { ++ return LifecycleEventTypeProvider.provider().monitor(name, ownerType); ++ } ++ ++ @ApiStatus.Internal ++ static <O extends LifecycleEventOwner, E extends LifecycleEvent> LifecycleEventType.Prioritizable<O, E> prioritized(final String name, final Class<? extends O> ownerType) { ++ return LifecycleEventTypeProvider.provider().prioritized(name, ownerType); ++ } ++ //</editor-fold> ++ ++ private LifecycleEvents() { ++ } ++} +diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java +index 94913f522d3c060c609f6ec7d7b0d92ea5587fc8..a0b02efdb3beed93cb1656e840f24cb98f5fd555 100644 +--- a/src/main/java/org/bukkit/UnsafeValues.java ++++ b/src/main/java/org/bukkit/UnsafeValues.java +@@ -271,4 +271,12 @@ public interface UnsafeValues { + */ + @Nullable org.bukkit.Color getSpawnEggLayerColor(org.bukkit.entity.EntityType entityType, int layer); + // Paper end - spawn egg color visibility ++ ++ // Paper start - lifecycle event API ++ /** ++ * @hidden ++ */ ++ @org.jetbrains.annotations.ApiStatus.Internal ++ io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.plugin.Plugin> createPluginLifecycleEventManager(final org.bukkit.plugin.java.JavaPlugin plugin, final java.util.function.BooleanSupplier registrationCheck); ++ // Paper end - lifecycle event API + } +diff --git a/src/main/java/org/bukkit/plugin/Plugin.java b/src/main/java/org/bukkit/plugin/Plugin.java +index 46fc37a36403c8fbc4c0c9f863d4d57eb3896bd4..0ff8b53f900092dc419d61a8ede0a7cd72a2e1e1 100644 +--- a/src/main/java/org/bukkit/plugin/Plugin.java ++++ b/src/main/java/org/bukkit/plugin/Plugin.java +@@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable; + * <p> + * The use of {@link PluginBase} is recommended for actual Implementation + */ +-public interface Plugin extends TabExecutor { ++public interface Plugin extends TabExecutor, io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner { // Paper + /** + * Returns the folder that the plugin data files are located in. The + * folder may not yet exist. +@@ -224,4 +224,14 @@ public interface Plugin extends TabExecutor { + */ + @NotNull + public String getName(); ++ ++ // Paper start - lifecycle events ++ /** ++ * Get the lifecycle event manager for registering handlers ++ * for lifecycle events allowed on the {@link Plugin}. ++ * ++ * @return the lifecycle event manager ++ */ ++ io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager<Plugin> getLifecycleManager(); ++ // Paper end - lifecycle events + } +diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +index 2d64fc065d53dcd8c01d05215c3e63aaf4428177..e0203f199700c397961a0667a79792497da7f796 100644 +--- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java ++++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +@@ -48,6 +48,11 @@ public abstract class JavaPlugin extends PluginBase { + private FileConfiguration newConfig = null; + private File configFile = null; + private Logger logger = null; // Paper - PluginLogger -> Logger ++ // Paper start - lifecycle events ++ @SuppressWarnings("deprecation") ++ private final io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.plugin.Plugin> lifecycleEventManager = org.bukkit.Bukkit.getUnsafe().createPluginLifecycleEventManager(this, () -> this.allowsLifecycleRegistration); ++ private boolean allowsLifecycleRegistration = true; ++ // Paper end + + public JavaPlugin() { + // Paper start +@@ -279,7 +284,9 @@ public abstract class JavaPlugin extends PluginBase { + isEnabled = enabled; + + if (isEnabled) { ++ try { // Paper - lifecycle events + onEnable(); ++ } finally { this.allowsLifecycleRegistration = false; } // Paper - lifecycle events + } else { + onDisable(); + } +@@ -457,4 +464,11 @@ public abstract class JavaPlugin extends PluginBase { + } + return plugin; + } ++ ++ // Paper start - lifecycle events ++ @Override ++ public final io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager<org.bukkit.plugin.Plugin> getLifecycleManager() { ++ return this.lifecycleEventManager; ++ } ++ // Paper end - lifecycle events + } +diff --git a/src/test/java/org/bukkit/plugin/TestPlugin.java b/src/test/java/org/bukkit/plugin/TestPlugin.java +index 43b58e920e739bb949ac0673e9ef73ba7b500dc9..affe88cf8e98a787e197936f5fc443464a2343c6 100644 +--- a/src/test/java/org/bukkit/plugin/TestPlugin.java ++++ b/src/test/java/org/bukkit/plugin/TestPlugin.java +@@ -133,4 +133,11 @@ public class TestPlugin extends PluginBase { + public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + throw new UnsupportedOperationException("Not supported."); + } ++ ++ // Paper start - lifecycle events ++ @Override ++ public io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<Plugin> getLifecycleManager() { ++ throw new UnsupportedOperationException("Not supported."); ++ } ++ // Paper end - lifecycle events + } |