geforkt von Mirrors/Paper
Lifecycle Event System (#9629)
* registering stuff event system * simply by removing a ton of unneeded generics * separate RegistryEvent and RegistrarEvent * add logic for removing hooks when a plugin is disabled * cleanup more * swap around the way things are registered * block further hook registrations for JavaPlugin * Slightly more extensible to support registry mod API * rename some types * more moving/renaming * remove 'hook' name * Rename to 'lifecycle' * move more impls for the server * add priorities * added lock for bootstrap event registration * slight refactor to allow 'register anywhere' event types * Move event type list to server impl * use builder pattern to create event handler configurations * add some more javadocs * fix some issues, slight refactors * call predicate and method renames * add owner aware events * rebased and refactored owner aware events * add single helper method for registering simple handler * compile fixes * check owner and fix generics on register helper * javadoc fixes and a few type renames * more javadoc fixes * move service loader file to correct location * rename to Monitorable and Prioritizable * add invalidation system for events after running them * block reloading plugins in certain situations * update test plugin * remove dummy events * rebase
Dieser Commit ist enthalten in:
Ursprung
679f34297e
Commit
4f9f09bb9b
628
patches/api/Add-Lifecycle-Event-system.patch
Normale Datei
628
patches/api/Add-Lifecycle-Event-system.patch
Normale Datei
@ -0,0 +1,628 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents the context provided to a {@link PluginBootstrap} during both the bootstrapping and plugin
|
||||
@@ -0,0 +0,0 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
@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
|
||||
+ */
|
||||
+ @NotNull 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * 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}
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+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 @NotNull LifecycleEventType<? super O, ? extends E, ?> eventType, final @NotNull 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(@NotNull 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event;
|
||||
+
|
||||
+import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * 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.
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+public interface LifecycleEventOwner {
|
||||
+
|
||||
+ /**
|
||||
+ * Get the plugin meta for this plugin.
|
||||
+ *
|
||||
+ * @return the plugin meta
|
||||
+ */
|
||||
+ @NotNull 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.handler;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A handler for a specific event. Can be implemented
|
||||
+ * in a concrete class or as a lambda.
|
||||
+ *
|
||||
+ * @param <E> the event
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@FunctionalInterface
|
||||
+public interface LifecycleEventHandler<E extends LifecycleEvent> {
|
||||
+
|
||||
+ void run(@NotNull 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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;
|
||||
+
|
||||
+/**
|
||||
+ * 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")
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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;
|
||||
+
|
||||
+/**
|
||||
+ * Handler configuration for event types that allow "monitor" handlers.
|
||||
+ *
|
||||
+ * @param <O> the required owner type
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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;
|
||||
+
|
||||
+/**
|
||||
+ * Handler configuration that allows both "monitor" and prioritized handlers.
|
||||
+ * The default priority is 0.
|
||||
+ *
|
||||
+ * @param <O> the required owner type
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * 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
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+public interface RegistrarEvent<R extends Registrar> extends LifecycleEvent {
|
||||
+
|
||||
+ /**
|
||||
+ * Get the registrar related to this event.
|
||||
+ *
|
||||
+ * @return the registrar
|
||||
+ */
|
||||
+ @Contract(pure = true)
|
||||
+ @NotNull 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.registrar;
|
||||
+
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A lifecycle event that exposes a {@link Registrar} that is
|
||||
+ * reloadable.
|
||||
+ *
|
||||
+ * @param <R> the registrar type
|
||||
+ * @see RegistrarEvent
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+public interface ReloadableRegistrarEvent<R extends Registrar> extends RegistrarEvent<R> {
|
||||
+
|
||||
+ /**
|
||||
+ * Get the cause of this reload.
|
||||
+ *
|
||||
+ * @return the cause
|
||||
+ */
|
||||
+ @Contract(pure = true)
|
||||
+ @NotNull 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * 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
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+@ApiStatus.NonExtendable
|
||||
+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)
|
||||
+ @NotNull 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")
|
||||
+ @NotNull C newHandler(@NotNull 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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.ServiceLoader;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+
|
||||
+@ApiStatus.Internal
|
||||
+interface LifecycleEventTypeProvider {
|
||||
+
|
||||
+ LifecycleEventTypeProvider PROVIDER = ServiceLoader.load(LifecycleEventTypeProvider.class)
|
||||
+ .findFirst()
|
||||
+ .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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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;
|
||||
+
|
||||
+/**
|
||||
+ * Holds various types of lifecycle events for
|
||||
+ * use when creating event handler configurations
|
||||
+ * in {@link LifecycleEventManager}.
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+public final class LifecycleEvents {
|
||||
+
|
||||
+ //<editor-fold desc="helper methods" defaultstate="collapsed">
|
||||
+ @ApiStatus.Internal
|
||||
+ private static <E extends LifecycleEvent> LifecycleEventType.Monitorable<Plugin, E> plugin(final String name) {
|
||||
+ return monitor(name, Plugin.class);
|
||||
+ }
|
||||
+
|
||||
+ @ApiStatus.Internal
|
||||
+ private static <E extends LifecycleEvent> LifecycleEventType.Prioritizable<Plugin, E> pluginPrioritized(final String name) {
|
||||
+ return prioritized(name, Plugin.class);
|
||||
+ }
|
||||
+
|
||||
+ @ApiStatus.Internal
|
||||
+ private static <E extends LifecycleEvent> LifecycleEventType.Monitorable<BootstrapContext, E> bootstrap(final String name) {
|
||||
+ return monitor(name, BootstrapContext.class);
|
||||
+ }
|
||||
+
|
||||
+ @ApiStatus.Internal
|
||||
+ private static <E extends LifecycleEvent> LifecycleEventType.Prioritizable<BootstrapContext, E> bootstrapPrioritized(final String name) {
|
||||
+ return prioritized(name, BootstrapContext.class);
|
||||
+ }
|
||||
+
|
||||
+ @ApiStatus.Internal
|
||||
+ private 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
|
||||
+ private 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/UnsafeValues.java
|
||||
+++ b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/Plugin.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/Plugin.java
|
||||
@@ -0,0 +0,0 @@ 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's files are located in. The
|
||||
* folder may not yet exist.
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ public abstract class JavaPlugin extends PluginBase {
|
||||
isEnabled = enabled;
|
||||
|
||||
if (isEnabled) {
|
||||
+ try { // Paper - lifecycle events
|
||||
onEnable();
|
||||
+ } finally { this.allowsLifecycleRegistration = false; } // Paper - lifecycle events
|
||||
} else {
|
||||
onDisable();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/plugin/TestPlugin.java
|
||||
+++ b/src/test/java/org/bukkit/plugin/TestPlugin.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
781
patches/server/Add-Lifecycle-Event-system.patch
Normale Datei
781
patches/server/Add-Lifecycle-Event-system.patch
Normale Datei
@ -0,0 +1,781 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 18 Jul 2023 17:49:38 -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/PluginBootstrapContextImpl.java b/src/main/java/io/papermc/paper/plugin/bootstrap/PluginBootstrapContextImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/bootstrap/PluginBootstrapContextImpl.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/bootstrap/PluginBootstrapContextImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package io.papermc.paper.plugin.bootstrap;
|
||||
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEventManager;
|
||||
import io.papermc.paper.plugin.provider.PluginProvider;
|
||||
import java.nio.file.Path;
|
||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
@@ -0,0 +0,0 @@ public final class PluginBootstrapContextImpl implements BootstrapContext {
|
||||
private final Path dataFolder;
|
||||
private final ComponentLogger logger;
|
||||
private final Path pluginSource;
|
||||
+ // Paper start - lifecycle events
|
||||
+ private boolean allowsLifecycleRegistration = true;
|
||||
+ private final PaperLifecycleEventManager<BootstrapContext> lifecycleEventManager = new PaperLifecycleEventManager<>(this, () -> this.allowsLifecycleRegistration); // Paper - lifecycle events
|
||||
+ // Paper end - lifecycle events
|
||||
|
||||
public PluginBootstrapContextImpl(PluginMeta config, Path dataFolder, ComponentLogger logger, Path pluginSource) {
|
||||
this.config = config;
|
||||
@@ -0,0 +0,0 @@ public final class PluginBootstrapContextImpl implements BootstrapContext {
|
||||
public @NotNull Path getPluginSource() {
|
||||
return this.pluginSource;
|
||||
}
|
||||
+
|
||||
+ // Paper start - lifecycle event system
|
||||
+ @Override
|
||||
+ public @NotNull PluginMeta getPluginMeta() {
|
||||
+ return this.config;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public LifecycleEventManager<BootstrapContext> getLifecycleManager() {
|
||||
+ return this.lifecycleEventManager;
|
||||
+ }
|
||||
+
|
||||
+ public void lockLifecycleEventRegistration() {
|
||||
+ this.allowsLifecycleRegistration = false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event;
|
||||
+
|
||||
+import com.google.common.base.Suppliers;
|
||||
+import com.mojang.logging.LogUtils;
|
||||
+import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.registrar.PaperRegistrar;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.registrar.RegistrarEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.registrar.RegistrarEventImpl;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.OwnerAwareLifecycleEvent;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.Set;
|
||||
+import java.util.function.Predicate;
|
||||
+import java.util.function.Supplier;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+import org.slf4j.Logger;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class LifecycleEventRunner {
|
||||
+
|
||||
+ private static final Logger LOGGER = LogUtils.getClassLogger();
|
||||
+ private static final Supplier<Set<LifecycleEventType<?, ?, ?>>> BLOCKS_RELOADING = Suppliers.memoize(() -> Set.of( // lazy due to cyclic initialization
|
||||
+ ));
|
||||
+ public static final LifecycleEventRunner INSTANCE = new LifecycleEventRunner();
|
||||
+
|
||||
+ private final List<LifecycleEventType<?, ?, ?>> lifecycleEventTypes = new ArrayList<>();
|
||||
+ private boolean blockPluginReloading = false;
|
||||
+
|
||||
+ public void checkRegisteredHandler(final LifecycleEventOwner owner, final LifecycleEventType<?, ?, ?> eventType) {
|
||||
+ /*
|
||||
+ Lifecycle event handlers for reloadable events that are registered from the BootstrapContext prevent
|
||||
+ the server from reloading plugins. This is because reloading plugins requires disabling all the plugins,
|
||||
+ running the reload logic (which would include places where these events should fire) and then re-enabling plugins.
|
||||
+ */
|
||||
+ if (owner instanceof BootstrapContext && BLOCKS_RELOADING.get().contains(eventType)) {
|
||||
+ this.blockPluginReloading = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean blocksPluginReloading() {
|
||||
+ return this.blockPluginReloading;
|
||||
+ }
|
||||
+
|
||||
+ public <O extends LifecycleEventOwner, E extends LifecycleEvent, ET extends LifecycleEventType<O, E, ?>> ET addEventType(final ET eventType) {
|
||||
+ this.lifecycleEventTypes.add(eventType);
|
||||
+ return eventType;
|
||||
+ }
|
||||
+
|
||||
+ public <O extends LifecycleEventOwner, E extends PaperLifecycleEvent> void callEvent(final LifecycleEventType<O, ? super E, ?> eventType, final E event) {
|
||||
+ this.callEvent(eventType, event, $ -> true);
|
||||
+ }
|
||||
+
|
||||
+ public <O extends LifecycleEventOwner, E extends PaperLifecycleEvent> void callEvent(final LifecycleEventType<O, ? super E, ?> eventType, final E event, final Predicate<? super O> ownerPredicate) {
|
||||
+ final AbstractLifecycleEventType<O, ? super E, ?, ?> lifecycleEventType = (AbstractLifecycleEventType<O, ? super E, ?, ?>) eventType;
|
||||
+ lifecycleEventType.forEachHandler(registeredHandler -> {
|
||||
+ try {
|
||||
+ if (event instanceof final OwnerAwareLifecycleEvent<?> ownerAwareEvent) {
|
||||
+ ownerAwareGenericHelper(ownerAwareEvent, registeredHandler.owner());
|
||||
+ }
|
||||
+ registeredHandler.lifecycleEventHandler().run(event);
|
||||
+ } catch (final Throwable ex) {
|
||||
+ LOGGER.error("Could not run '{}' lifecycle event handler from {}", lifecycleEventType.name(), registeredHandler.owner().getPluginMeta().getDisplayName(), ex);
|
||||
+ } finally {
|
||||
+ if (event instanceof final OwnerAwareLifecycleEvent<?> ownerAwareEvent) {
|
||||
+ ownerAwareEvent.setOwner(null);
|
||||
+ }
|
||||
+ }
|
||||
+ }, handler -> ownerPredicate.test(handler.owner()));
|
||||
+ event.invalidate();
|
||||
+ }
|
||||
+
|
||||
+ private static <O extends LifecycleEventOwner> void ownerAwareGenericHelper(final OwnerAwareLifecycleEvent<O> event, final LifecycleEventOwner possibleOwner) {
|
||||
+ final @Nullable O owner = event.castOwner(possibleOwner);
|
||||
+ if (owner != null) {
|
||||
+ event.setOwner(owner);
|
||||
+ } else {
|
||||
+ throw new IllegalStateException("Found invalid owner " + possibleOwner + " for event " + event);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void unregisterAllEventHandlersFor(final Plugin plugin) {
|
||||
+ for (final LifecycleEventType<?, ?, ?> lifecycleEventType : this.lifecycleEventTypes) {
|
||||
+ this.removeEventHandlersOwnedBy(lifecycleEventType, plugin);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private <O extends LifecycleEventOwner> void removeEventHandlersOwnedBy(final LifecycleEventType<O, ?, ?> eventType, final Plugin possibleOwner) {
|
||||
+ final AbstractLifecycleEventType<O, ?, ?, ?> lifecycleEventType = (AbstractLifecycleEventType<O, ?, ?, ?>) eventType;
|
||||
+ lifecycleEventType.removeMatching(registeredHandler -> registeredHandler.owner().getPluginMeta().getName().equals(possibleOwner.getPluginMeta().getName()));
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public <O extends LifecycleEventOwner, R extends PaperRegistrar<? super O>> void callStaticRegistrarEvent(final LifecycleEventType<O, ? extends RegistrarEvent<? super R>, ?> lifecycleEventType, final R registrar, final Class<? extends O> ownerClass) {
|
||||
+ this.callEvent((LifecycleEventType<O, RegistrarEvent<? super R>, ?>) lifecycleEventType, new RegistrarEventImpl<>(registrar, ownerClass), ownerClass::isInstance);
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public <O extends LifecycleEventOwner, R extends PaperRegistrar<? super O>> void callReloadableRegistrarEvent(final LifecycleEventType<O, ? extends ReloadableRegistrarEvent<? super R>, ?> lifecycleEventType, final R registrar, final Class<? extends O> ownerClass, final ReloadableRegistrarEvent.Cause cause) {
|
||||
+ this.callEvent((LifecycleEventType<O, ReloadableRegistrarEvent<? super R>, ?>) lifecycleEventType, new RegistrarEventImpl.ReloadableImpl<>(registrar, ownerClass, cause), ownerClass::isInstance);
|
||||
+ }
|
||||
+
|
||||
+ private LifecycleEventRunner() {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event;
|
||||
+
|
||||
+public interface PaperLifecycleEvent extends LifecycleEvent {
|
||||
+
|
||||
+ // called after all handlers have been run. Can be
|
||||
+ // used to invalid various contexts to plugins can't
|
||||
+ // try to re-use them by storing them from the event
|
||||
+ default void invalidate() {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEventManager.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEventManager.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEventManager.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.AbstractLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration;
|
||||
+import java.util.function.BooleanSupplier;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class PaperLifecycleEventManager<O extends LifecycleEventOwner> implements LifecycleEventManager<O> {
|
||||
+
|
||||
+ private final O owner;
|
||||
+ public final BooleanSupplier registrationCheck;
|
||||
+
|
||||
+ public PaperLifecycleEventManager(final O owner, final BooleanSupplier registrationCheck) {
|
||||
+ this.owner = owner;
|
||||
+ this.registrationCheck = registrationCheck;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void registerEventHandler(final LifecycleEventHandlerConfiguration<? super O> handlerConfiguration) {
|
||||
+ Preconditions.checkState(this.registrationCheck.getAsBoolean(), "Cannot register lifecycle event handlers");
|
||||
+ ((AbstractLifecycleEventHandlerConfiguration<? super O, ?, ?>) handlerConfiguration).registerFrom(this.owner);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/AbstractLifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/AbstractLifecycleEventHandlerConfiguration.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/AbstractLifecycleEventHandlerConfiguration.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.handler.configuration;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public abstract class AbstractLifecycleEventHandlerConfiguration<O extends LifecycleEventOwner, E extends LifecycleEvent, CI extends AbstractLifecycleEventHandlerConfiguration<O, E, CI>> implements LifecycleEventHandlerConfiguration<O> {
|
||||
+
|
||||
+ private final LifecycleEventHandler<? super E> handler;
|
||||
+ private final AbstractLifecycleEventType<O, E, ?, CI> type;
|
||||
+
|
||||
+ protected AbstractLifecycleEventHandlerConfiguration(final LifecycleEventHandler<? super E> handler, final AbstractLifecycleEventType<O, E, ?, CI> type) {
|
||||
+ this.handler = handler;
|
||||
+ this.type = type;
|
||||
+ }
|
||||
+
|
||||
+ public abstract CI config();
|
||||
+
|
||||
+ public final void registerFrom(final O owner) {
|
||||
+ this.type.tryRegister(owner, this.handler, this.config());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfigurationImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfigurationImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfigurationImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.handler.configuration;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class MonitorLifecycleEventHandlerConfigurationImpl<O extends LifecycleEventOwner, E extends LifecycleEvent> extends AbstractLifecycleEventHandlerConfiguration<O, E, MonitorLifecycleEventHandlerConfigurationImpl<O, E>> implements MonitorLifecycleEventHandlerConfiguration<O> {
|
||||
+
|
||||
+ private boolean monitor = false;
|
||||
+
|
||||
+ public MonitorLifecycleEventHandlerConfigurationImpl(final LifecycleEventHandler<? super E> handler, final AbstractLifecycleEventType<O, E, ?, MonitorLifecycleEventHandlerConfigurationImpl<O, E>> eventType) {
|
||||
+ super(handler, eventType);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public MonitorLifecycleEventHandlerConfigurationImpl<O, E> config() {
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isMonitor() {
|
||||
+ return this.monitor;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public MonitorLifecycleEventHandlerConfiguration<O> monitor() {
|
||||
+ this.monitor = true;
|
||||
+ return this;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfigurationImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfigurationImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfigurationImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.handler.configuration;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
+import java.util.OptionalInt;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class PrioritizedLifecycleEventHandlerConfigurationImpl<O extends LifecycleEventOwner, E extends LifecycleEvent> extends AbstractLifecycleEventHandlerConfiguration<O, E, PrioritizedLifecycleEventHandlerConfigurationImpl<O, E>> implements PrioritizedLifecycleEventHandlerConfiguration<O> {
|
||||
+
|
||||
+ private static final OptionalInt DEFAULT_PRIORITY = OptionalInt.of(0);
|
||||
+ private static final OptionalInt MONITOR_PRIORITY = OptionalInt.empty();
|
||||
+
|
||||
+ private OptionalInt priority = DEFAULT_PRIORITY;
|
||||
+
|
||||
+ public PrioritizedLifecycleEventHandlerConfigurationImpl(final LifecycleEventHandler<? super E> handler, final AbstractLifecycleEventType<O, E, ?, PrioritizedLifecycleEventHandlerConfigurationImpl<O, E>> eventType) {
|
||||
+ super(handler, eventType);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PrioritizedLifecycleEventHandlerConfigurationImpl<O, E> config() {
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ public OptionalInt priority() {
|
||||
+ return this.priority;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PrioritizedLifecycleEventHandlerConfiguration<O> priority(final int priority) {
|
||||
+ this.priority = OptionalInt.of(priority);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PrioritizedLifecycleEventHandlerConfiguration<O> monitor() {
|
||||
+ this.priority = MONITOR_PRIORITY;
|
||||
+ return this;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/PaperRegistrar.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/PaperRegistrar.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/PaperRegistrar.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.registrar;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public interface PaperRegistrar<O extends LifecycleEventOwner> extends Registrar {
|
||||
+
|
||||
+ void setCurrentContext(@Nullable O owner);
|
||||
+
|
||||
+ default void invalidate() {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEventImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEventImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEventImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.registrar;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.OwnerAwareLifecycleEvent;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class RegistrarEventImpl<R extends PaperRegistrar<? super O>, O extends LifecycleEventOwner> implements PaperLifecycleEvent, OwnerAwareLifecycleEvent<O>, RegistrarEvent<R> {
|
||||
+
|
||||
+ private final R registrar;
|
||||
+ private final Class<? extends O> ownerClass;
|
||||
+
|
||||
+ public RegistrarEventImpl(final R registrar, final Class<? extends O> ownerClass) {
|
||||
+ this.registrar = registrar;
|
||||
+ this.ownerClass = ownerClass;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public R registrar() {
|
||||
+ return this.registrar;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public final void setOwner(final @Nullable O owner) {
|
||||
+ this.registrar.setCurrentContext(owner);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public final @Nullable O castOwner(final LifecycleEventOwner owner) {
|
||||
+ return this.ownerClass.isInstance(owner) ? this.ownerClass.cast(owner) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void invalidate() {
|
||||
+ this.registrar.invalidate();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "RegistrarEventImpl{" +
|
||||
+ "registrar=" + this.registrar +
|
||||
+ ", ownerClass=" + this.ownerClass +
|
||||
+ '}';
|
||||
+ }
|
||||
+
|
||||
+ public static class ReloadableImpl<R extends PaperRegistrar<? super O>, O extends LifecycleEventOwner> extends RegistrarEventImpl<R, O> implements ReloadableRegistrarEvent<R> {
|
||||
+
|
||||
+ private final ReloadableRegistrarEvent.Cause cause;
|
||||
+
|
||||
+ public ReloadableImpl(final R registrar, final Class<? extends O> ownerClass, final Cause cause) {
|
||||
+ super(registrar, ownerClass);
|
||||
+ this.cause = cause;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Cause cause() {
|
||||
+ return this.cause;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "ReloadableImpl{" +
|
||||
+ "cause=" + this.cause +
|
||||
+ "} " + super.toString();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/AbstractLifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/AbstractLifecycleEventType.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/AbstractLifecycleEventType.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.AbstractLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration;
|
||||
+import java.util.function.Consumer;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public abstract class AbstractLifecycleEventType<O extends LifecycleEventOwner, E extends LifecycleEvent, C extends LifecycleEventHandlerConfiguration<O>, CI extends AbstractLifecycleEventHandlerConfiguration<O, E, CI>> implements LifecycleEventType<O, E, C> {
|
||||
+
|
||||
+ private final String name;
|
||||
+ private final Class<? extends O> ownerType;
|
||||
+
|
||||
+ protected AbstractLifecycleEventType(final String name, final Class<? extends O> ownerType) {
|
||||
+ this.name = name;
|
||||
+ this.ownerType = ownerType;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String name() {
|
||||
+ return this.name;
|
||||
+ }
|
||||
+
|
||||
+ private void verifyOwner(final O owner) {
|
||||
+ if (!this.ownerType.isInstance(owner)) {
|
||||
+ throw new IllegalArgumentException("You cannot register the lifecycle event '" + this.name + "' on " + owner);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public abstract void forEachHandler(Consumer<? super RegisteredHandler<O, E>> consumer, Predicate<? super RegisteredHandler<O, E>> predicate);
|
||||
+
|
||||
+ public abstract void removeMatching(Predicate<? super RegisteredHandler<O, E>> predicate);
|
||||
+
|
||||
+ protected abstract void register(O owner, LifecycleEventHandler<? super E> handler, CI config);
|
||||
+
|
||||
+ public final void tryRegister(final O owner, final LifecycleEventHandler<? super E> handler, final CI config) {
|
||||
+ this.verifyOwner(owner);
|
||||
+ LifecycleEventRunner.INSTANCE.checkRegisteredHandler(owner, this);
|
||||
+ this.register(owner, handler, config);
|
||||
+ }
|
||||
+
|
||||
+ public record RegisteredHandler<O, E extends LifecycleEvent>(O owner, LifecycleEventHandler<? super E> lifecycleEventHandler) {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class LifecycleEventTypeProviderImpl implements LifecycleEventTypeProvider {
|
||||
+
|
||||
+ public static LifecycleEventTypeProviderImpl instance() {
|
||||
+ return (LifecycleEventTypeProviderImpl) LifecycleEventTypeProvider.PROVIDER;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public <O extends LifecycleEventOwner, E extends LifecycleEvent> LifecycleEventType.Monitorable<O, E> monitor(final String name, final Class<? extends O> ownerType) {
|
||||
+ return LifecycleEventRunner.INSTANCE.addEventType(new MonitorableLifecycleEventType<>(name, ownerType));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public <O extends LifecycleEventOwner, E extends LifecycleEvent> LifecycleEventType.Prioritizable<O, E> prioritized(final String name, final Class<? extends O> ownerType) {
|
||||
+ return LifecycleEventRunner.INSTANCE.addEventType(new PrioritizableLifecycleEventType<>(name, ownerType));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/MonitorableLifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/MonitorableLifecycleEventType.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/MonitorableLifecycleEventType.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfigurationImpl;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.function.Consumer;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class MonitorableLifecycleEventType<O extends LifecycleEventOwner, E extends LifecycleEvent> extends AbstractLifecycleEventType<O, E, MonitorLifecycleEventHandlerConfiguration<O>, MonitorLifecycleEventHandlerConfigurationImpl<O, E>> implements LifecycleEventType.Monitorable<O, E> {
|
||||
+
|
||||
+ final List<RegisteredHandler<O, E>> handlers = new ArrayList<>();
|
||||
+ int nonMonitorIdx = 0;
|
||||
+
|
||||
+ public MonitorableLifecycleEventType(final String name, final Class<? extends O> ownerType) {
|
||||
+ super(name, ownerType);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public MonitorLifecycleEventHandlerConfigurationImpl<O, E> newHandler(final LifecycleEventHandler<? super E> handler) {
|
||||
+ return new MonitorLifecycleEventHandlerConfigurationImpl<>(handler, this);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void register(final O owner, final LifecycleEventHandler<? super E> handler, final MonitorLifecycleEventHandlerConfigurationImpl<O, E> config) {
|
||||
+ final RegisteredHandler<O, E> registeredHandler = new RegisteredHandler<>(owner, handler);
|
||||
+ if (!config.isMonitor()) {
|
||||
+ this.handlers.add(this.nonMonitorIdx, registeredHandler);
|
||||
+ this.nonMonitorIdx++;
|
||||
+ } else {
|
||||
+ this.handlers.add(registeredHandler);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void forEachHandler(final Consumer<? super RegisteredHandler<O, E>> consumer, final Predicate<? super RegisteredHandler<O, E>> predicate) {
|
||||
+ for (final RegisteredHandler<O, E> handler : this.handlers) {
|
||||
+ if (predicate.test(handler)) {
|
||||
+ consumer.accept(handler);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeMatching(final Predicate<? super RegisteredHandler<O, E>> predicate) {
|
||||
+ this.handlers.removeIf(predicate);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/OwnerAwareLifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/OwnerAwareLifecycleEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/OwnerAwareLifecycleEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public interface OwnerAwareLifecycleEvent<O extends LifecycleEventOwner> extends LifecycleEvent {
|
||||
+
|
||||
+ void setOwner(@Nullable O owner);
|
||||
+
|
||||
+ @Nullable O castOwner(LifecycleEventOwner owner);
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PrioritizableLifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PrioritizableLifecycleEventType.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PrioritizableLifecycleEventType.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfigurationImpl;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Comparator;
|
||||
+import java.util.List;
|
||||
+import java.util.OptionalInt;
|
||||
+import java.util.function.Consumer;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class PrioritizableLifecycleEventType<O extends LifecycleEventOwner, E extends LifecycleEvent> extends AbstractLifecycleEventType<O, E, PrioritizedLifecycleEventHandlerConfiguration<O>, PrioritizedLifecycleEventHandlerConfigurationImpl<O, E>> implements LifecycleEventType.Prioritizable<O, E> {
|
||||
+
|
||||
+ private static final Comparator<PrioritizedHandler<?, ?>> COMPARATOR = Comparator.comparing(PrioritizedHandler::priority, (o1, o2) -> {
|
||||
+ if (o1.equals(o2)) {
|
||||
+ return 0;
|
||||
+ } else if (o1.isEmpty()) {
|
||||
+ return 1;
|
||||
+ } else if (o2.isEmpty()) {
|
||||
+ return -1;
|
||||
+ } else {
|
||||
+ return Integer.compare(o1.getAsInt(), o2.getAsInt());
|
||||
+ }
|
||||
+ });
|
||||
+
|
||||
+ private final List<PrioritizedHandler<O, E>> handlers = new ArrayList<>();
|
||||
+
|
||||
+ public PrioritizableLifecycleEventType(final String name, final Class<? extends O> ownerType) {
|
||||
+ super(name, ownerType);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PrioritizedLifecycleEventHandlerConfiguration<O> newHandler(final LifecycleEventHandler<? super E> handler) {
|
||||
+ return new PrioritizedLifecycleEventHandlerConfigurationImpl<>(handler, this);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void register(final O owner, final LifecycleEventHandler<? super E> handler, final PrioritizedLifecycleEventHandlerConfigurationImpl<O, E> config) {
|
||||
+ this.handlers.add(new PrioritizedHandler<>(new RegisteredHandler<>(owner, handler), config.priority()));
|
||||
+ this.handlers.sort(COMPARATOR);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void forEachHandler(final Consumer<? super RegisteredHandler<O, E>> consumer, final Predicate<? super RegisteredHandler<O, E>> predicate) {
|
||||
+ for (final PrioritizedHandler<O, E> handler : this.handlers) {
|
||||
+ if (predicate.test(handler.handler())) {
|
||||
+ consumer.accept(handler.handler());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeMatching(final Predicate<? super RegisteredHandler<O, E>> predicate) {
|
||||
+ this.handlers.removeIf(prioritizedHandler -> predicate.test(prioritizedHandler.handler()));
|
||||
+ }
|
||||
+
|
||||
+ private record PrioritizedHandler<O extends LifecycleEventOwner, E extends LifecycleEvent>(RegisteredHandler<O, E> handler, OptionalInt priority) {}
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java
|
||||
@@ -0,0 +0,0 @@ class PaperPluginInstanceManager {
|
||||
+ pluginName + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
+ // Paper start - lifecycle event system
|
||||
+ try {
|
||||
+ io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.unregisterAllEventHandlersFor(plugin);
|
||||
+ } catch (Throwable ex) {
|
||||
+ this.handlePluginException("Error occurred (in the plugin loader) while unregistering lifecycle event handlers for "
|
||||
+ + pluginName + " (Is it up to date?)", ex, plugin);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
try {
|
||||
this.server.getMessenger().unregisterIncomingPluginChannel(plugin);
|
||||
this.server.getMessenger().unregisterOutgoingPluginChannel(plugin);
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/storage/BootstrapProviderStorage.java b/src/main/java/io/papermc/paper/plugin/storage/BootstrapProviderStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/storage/BootstrapProviderStorage.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/storage/BootstrapProviderStorage.java
|
||||
@@ -0,0 +0,0 @@ public class BootstrapProviderStorage extends SimpleProviderStorage<PluginBootst
|
||||
@Override
|
||||
public boolean load(PluginProvider<PluginBootstrap> provider, PluginBootstrap provided) {
|
||||
try {
|
||||
- BootstrapContext context = PluginBootstrapContextImpl.create(provider, PluginInitializerManager.instance().pluginDirectoryPath());
|
||||
+ PluginBootstrapContextImpl context = PluginBootstrapContextImpl.create(provider, PluginInitializerManager.instance().pluginDirectoryPath()); // Paper - lifecycle events
|
||||
provided.bootstrap(context);
|
||||
+ context.lockLifecycleEventRegistration(); // Paper - lifecycle events
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Failed to run bootstrapper for %s. This plugin will not be loaded.".formatted(provider.getSource()), e);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
+ // Paper start - lifecycle events
|
||||
+ if (io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.blocksPluginReloading()) {
|
||||
+ throw new IllegalStateException("A lifecycle event handler has been registered which makes reloading plugins not possible");
|
||||
+ }
|
||||
+ // Paper end - lifecycle events
|
||||
org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
|
||||
this.reloadCount++;
|
||||
this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java b/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java
|
||||
@@ -0,0 +0,0 @@ public class MinecraftInternalPlugin 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 @NotNull io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.plugin.Plugin> getLifecycleManager() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+ // Paper end - lifecycle events
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
}
|
||||
// Paper end - spawn egg color visibility
|
||||
|
||||
+ // Paper start - lifecycle event API
|
||||
+ @Override
|
||||
+ public 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) {
|
||||
+ return new io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEventManager<>(plugin, registrationCheck);
|
||||
+ }
|
||||
+ // Paper end - lifecycle event API
|
||||
+
|
||||
/**
|
||||
* This helper class represents the different NBT Tags.
|
||||
* <p>
|
||||
diff --git a/src/main/resources/META-INF/services/io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventTypeProvider b/src/main/resources/META-INF/services/io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventTypeProvider
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/resources/META-INF/services/io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventTypeProvider
|
||||
@@ -0,0 +1 @@
|
||||
+io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventTypeProviderImpl
|
||||
diff --git a/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java b/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java
|
||||
+++ b/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java
|
||||
@@ -0,0 +0,0 @@ public class PaperTestPlugin 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<org.bukkit.plugin.Plugin> getLifecycleManager() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+ // Paper end - lifecycle events
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren