mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-29 13:17:21 +00:00
Optimize event calls
This commit is contained in:
parent
d8ad10e22d
commit
acf56fc432
@ -6,6 +6,7 @@ import emu.grasscutter.plugin.api.ServerHelper;
|
|||||||
import emu.grasscutter.plugin.api.ServerHook;
|
import emu.grasscutter.plugin.api.ServerHook;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
import emu.grasscutter.utils.FileUtils;
|
import emu.grasscutter.utils.FileUtils;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ import java.io.InputStream;
|
|||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
/** The base class for all plugins to extend. */
|
/** The base class for all plugins to extend. */
|
||||||
|
@EqualsAndHashCode
|
||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("removal")
|
||||||
public abstract class Plugin {
|
public abstract class Plugin {
|
||||||
private final ServerHelper server = ServerHook.getInstance();
|
private final ServerHelper server = ServerHook.getInstance();
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package emu.grasscutter.plugin;
|
package emu.grasscutter.plugin;
|
||||||
|
|
||||||
import static emu.grasscutter.utils.lang.Language.translate;
|
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.server.event.Event;
|
import emu.grasscutter.server.event.Event;
|
||||||
import emu.grasscutter.server.event.EventHandler;
|
import emu.grasscutter.server.event.EventHandler;
|
||||||
import emu.grasscutter.server.event.HandlerPriority;
|
|
||||||
import emu.grasscutter.utils.FileUtils;
|
import emu.grasscutter.utils.FileUtils;
|
||||||
import emu.grasscutter.utils.JsonUtils;
|
import emu.grasscutter.utils.JsonUtils;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@ -18,16 +19,15 @@ import java.net.URLClassLoader;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import lombok.AllArgsConstructor;
|
import static emu.grasscutter.utils.lang.Language.translate;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/** Manages the server's plugins and the event system. */
|
/** Manages the server's plugins and the event system. */
|
||||||
public final class PluginManager {
|
public final class PluginManager {
|
||||||
/* All loaded plugins. */
|
/* All loaded plugins. */
|
||||||
private final Map<String, Plugin> plugins = new LinkedHashMap<>();
|
private final Map<String, Plugin> plugins = new LinkedHashMap<>();
|
||||||
/* All currently registered listeners per plugin. */
|
/* All currently registered listeners per plugin. */
|
||||||
private final Map<Plugin, List<EventHandler<? extends Event>>> listeners = new LinkedHashMap<>();
|
private final Map<Class<? extends Event>, List<EventHandler<? extends Event>>> handlers = new LinkedHashMap<>();
|
||||||
|
|
||||||
public PluginManager() {
|
public PluginManager() {
|
||||||
this.loadPlugins(); // Load all plugins from the plugins directory.
|
this.loadPlugins(); // Load all plugins from the plugins directory.
|
||||||
@ -184,8 +184,6 @@ public final class PluginManager {
|
|||||||
|
|
||||||
// Add the plugin to the list of loaded plugins.
|
// Add the plugin to the list of loaded plugins.
|
||||||
this.plugins.put(identifier.name, plugin);
|
this.plugins.put(identifier.name, plugin);
|
||||||
// Create a collection for the plugin's listeners.
|
|
||||||
this.listeners.put(plugin, new ArrayList<>());
|
|
||||||
|
|
||||||
// Call the plugin's onLoad method.
|
// Call the plugin's onLoad method.
|
||||||
try {
|
try {
|
||||||
@ -221,11 +219,74 @@ public final class PluginManager {
|
|||||||
/**
|
/**
|
||||||
* Registers a plugin's event listener.
|
* Registers a plugin's event listener.
|
||||||
*
|
*
|
||||||
* @param plugin The plugin registering the listener.
|
|
||||||
* @param listener The event listener.
|
* @param listener The event listener.
|
||||||
*/
|
*/
|
||||||
public void registerListener(Plugin plugin, EventHandler<? extends Event> listener) {
|
public void registerListener(EventHandler<? extends Event> listener) {
|
||||||
this.listeners.get(plugin).add(listener);
|
// Check if the handlers map contains the event type.
|
||||||
|
if (!this.handlers.containsKey(listener.handles()))
|
||||||
|
this.handlers.put(listener.handles(), new LinkedList<>());
|
||||||
|
|
||||||
|
// Add the listener to the list of handlers.
|
||||||
|
this.handlers.get(listener.handles()).add(listener);
|
||||||
|
|
||||||
|
this.sortListeners(); // Sort the listeners by priority.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all event listeners registered by the specified plugin.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
*/
|
||||||
|
public void removeListeners(Plugin plugin) {
|
||||||
|
var newMap = new HashMap<
|
||||||
|
Class<? extends Event>,
|
||||||
|
List<EventHandler<? extends Event>>
|
||||||
|
>();
|
||||||
|
|
||||||
|
// Remove the plugin's listeners.
|
||||||
|
this.handlers.forEach((event, handlers) -> {
|
||||||
|
// Add the event to the new map.
|
||||||
|
newMap.put(event, new LinkedList<>());
|
||||||
|
|
||||||
|
// Remove the plugin's listeners.
|
||||||
|
handlers.forEach(handler -> {
|
||||||
|
if (!handler.registrar().equals(plugin))
|
||||||
|
newMap.get(event).add(handler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Replace the old map with the new one.
|
||||||
|
this.handlers.clear();
|
||||||
|
this.handlers.putAll(newMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts the event listeners by priority.
|
||||||
|
* This method should be called after a listener has been registered.
|
||||||
|
*/
|
||||||
|
private void sortListeners() {
|
||||||
|
// Create a new map to store the sorted listeners.
|
||||||
|
var newMap = new HashMap<
|
||||||
|
Class<? extends Event>,
|
||||||
|
List<EventHandler<? extends Event>>
|
||||||
|
>();
|
||||||
|
|
||||||
|
// Sort the listeners by priority.
|
||||||
|
this.handlers.forEach((event, handlers) -> {
|
||||||
|
// Add the event to the new map.
|
||||||
|
newMap.put(event, new LinkedList<>());
|
||||||
|
|
||||||
|
// Sort the handlers by priority.
|
||||||
|
var sorted = handlers.stream()
|
||||||
|
.sorted(Comparator.comparingInt(handler ->
|
||||||
|
handler.getPriority().ordinal()))
|
||||||
|
.toList();
|
||||||
|
newMap.get(event).addAll(sorted);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Replace the old map with the new one.
|
||||||
|
this.handlers.clear();
|
||||||
|
this.handlers.putAll(newMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -234,25 +295,8 @@ public final class PluginManager {
|
|||||||
* @param event The event to invoke.
|
* @param event The event to invoke.
|
||||||
*/
|
*/
|
||||||
public void invokeEvent(Event event) {
|
public void invokeEvent(Event event) {
|
||||||
EnumSet.allOf(HandlerPriority.class).forEach(priority -> this.checkAndFilter(event, priority));
|
this.handlers.get(event.getClass())
|
||||||
}
|
.forEach(handler -> this.invokeHandler(event, handler));
|
||||||
|
|
||||||
/**
|
|
||||||
* Check an event to handlers for the priority.
|
|
||||||
*
|
|
||||||
* @param event The event being called.
|
|
||||||
* @param priority The priority to call for.
|
|
||||||
*/
|
|
||||||
private void checkAndFilter(Event event, HandlerPriority priority) {
|
|
||||||
// Add all listeners from every plugin.
|
|
||||||
var listeners = new ArrayList<>(this.listeners.values());
|
|
||||||
listeners.stream()
|
|
||||||
.flatMap(Collection::stream)
|
|
||||||
// Filter the listeners by priority.
|
|
||||||
.filter(handler -> handler.handles().isInstance(event))
|
|
||||||
.filter(handler -> handler.getPriority() == priority)
|
|
||||||
// Invoke the event.
|
|
||||||
.forEach(handler -> this.invokeHandler(event, handler));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -295,7 +339,7 @@ public final class PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Un-register all listeners.
|
// Un-register all listeners.
|
||||||
this.listeners.remove(plugin);
|
this.removeListeners(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,6 +59,7 @@ public final class EventHandler<T extends Event> {
|
|||||||
private EventConsumer<T> listener;
|
private EventConsumer<T> listener;
|
||||||
private HandlerPriority priority;
|
private HandlerPriority priority;
|
||||||
private boolean handleCanceled;
|
private boolean handleCanceled;
|
||||||
|
private Plugin plugin;
|
||||||
|
|
||||||
public EventHandler(Class<T> eventClass) {
|
public EventHandler(Class<T> eventClass) {
|
||||||
this.eventClass = eventClass;
|
this.eventClass = eventClass;
|
||||||
@ -100,6 +101,15 @@ public final class EventHandler<T extends Event> {
|
|||||||
return this.handleCanceled;
|
return this.handleCanceled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the plugin that registered this handler.
|
||||||
|
*
|
||||||
|
* @return The plugin that registered this handler.
|
||||||
|
*/
|
||||||
|
public Plugin registrar() {
|
||||||
|
return this.plugin;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the callback method for when the event is invoked.
|
* Sets the callback method for when the event is invoked.
|
||||||
*
|
*
|
||||||
@ -135,6 +145,7 @@ public final class EventHandler<T extends Event> {
|
|||||||
|
|
||||||
/** Registers the handler into the PluginManager. */
|
/** Registers the handler into the PluginManager. */
|
||||||
public void register(Plugin plugin) {
|
public void register(Plugin plugin) {
|
||||||
Grasscutter.getPluginManager().registerListener(plugin, this);
|
this.plugin = plugin;
|
||||||
|
Grasscutter.getPluginManager().registerListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user