diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventSubscription.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventSubscription.java index 8603dac37..9a04b697c 100644 --- a/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventSubscription.java +++ b/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventSubscription.java @@ -28,8 +28,6 @@ package org.geysermc.geyser.api.event; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.api.extension.Extension; -import java.util.function.Consumer; - /** * Represents a subscribed listener to a {@link Event}. Wraps around * the event and is capable of unsubscribing from the event or give @@ -47,15 +45,6 @@ public interface EventSubscription { @NonNull Class eventClass(); - /** - * Gets the consumer responsible for handling - * this event. - * - * @return the consumer responsible for this event - */ - @NonNull - Consumer eventConsumer(); - /** * Gets the {@link Extension} that owns this * event subscription. diff --git a/core/src/main/java/org/geysermc/geyser/event/GeyserEventSubscription.java b/core/src/main/java/org/geysermc/geyser/event/AbstractEventSubscription.java similarity index 72% rename from core/src/main/java/org/geysermc/geyser/event/GeyserEventSubscription.java rename to core/src/main/java/org/geysermc/geyser/event/AbstractEventSubscription.java index 33fe5a9e1..69dc74935 100644 --- a/core/src/main/java/org/geysermc/geyser/event/GeyserEventSubscription.java +++ b/core/src/main/java/org/geysermc/geyser/event/AbstractEventSubscription.java @@ -30,24 +30,20 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.experimental.Accessors; import net.kyori.event.EventSubscriber; -import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.api.event.Event; import org.geysermc.geyser.api.event.EventBus; import org.geysermc.geyser.api.event.EventSubscription; import org.geysermc.geyser.api.event.Subscribe; import org.geysermc.geyser.api.extension.Extension; -import java.util.function.Consumer; - @Getter @Accessors(fluent = true) @RequiredArgsConstructor -public class GeyserEventSubscription implements EventSubscription, EventSubscriber { - private final EventBus eventBus; - private final Class eventClass; - private final Consumer eventConsumer; - private final Extension owner; - private final Subscribe.PostOrder order; +public abstract class AbstractEventSubscription implements EventSubscription, EventSubscriber { + protected final EventBus eventBus; + protected final Class eventClass; + protected final Extension owner; + protected final Subscribe.PostOrder order; @Getter(AccessLevel.NONE) private boolean active; @Override @@ -65,16 +61,6 @@ public class GeyserEventSubscription implements EventSubscripti this.eventBus.unsubscribe(this); } - @Override - public void invoke(@NonNull T event) throws Throwable { - try { - this.eventConsumer.accept(event); - } catch (Throwable ex) { - this.owner.logger().warning("Unable to fire event " + event.getClass().getSimpleName() + " with subscription " + this.eventConsumer.getClass().getSimpleName()); - ex.printStackTrace(); - } - } - @Override public int postOrder() { return this.order.postOrder(); diff --git a/core/src/main/java/org/geysermc/geyser/event/BaseEventSubscription.java b/core/src/main/java/org/geysermc/geyser/event/BaseEventSubscription.java new file mode 100644 index 000000000..79df94e5d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/event/BaseEventSubscription.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.event; + +import lombok.Getter; +import lombok.experimental.Accessors; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.api.event.Event; +import org.geysermc.geyser.api.event.EventBus; +import org.geysermc.geyser.api.event.Subscribe; +import org.geysermc.geyser.api.extension.Extension; + +import java.util.function.Consumer; + +@Getter +@Accessors(fluent = true) +public class BaseEventSubscription extends AbstractEventSubscription { + private final Consumer eventConsumer; + + public BaseEventSubscription(EventBus eventBus, Class eventClass, Extension owner, Subscribe.PostOrder order, Consumer eventConsumer) { + super(eventBus, eventClass, owner, order); + + this.eventConsumer = eventConsumer; + } + + @Override + public void invoke(@NonNull T event) throws Throwable { + try { + this.eventConsumer.accept(event); + } catch (Throwable ex) { + this.owner.logger().warning("Unable to fire event " + event.getClass().getSimpleName() + " with subscription " + this.eventConsumer.getClass().getSimpleName()); + ex.printStackTrace(); + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/event/GeneratedEventSubscription.java b/core/src/main/java/org/geysermc/geyser/event/GeneratedEventSubscription.java new file mode 100644 index 000000000..b1ba7bf8b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/event/GeneratedEventSubscription.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.event; + +import lombok.Getter; +import lombok.experimental.Accessors; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.api.event.Event; +import org.geysermc.geyser.api.event.EventBus; +import org.geysermc.geyser.api.event.Subscribe; +import org.geysermc.geyser.api.extension.Extension; + +import java.util.function.BiConsumer; + +@Getter +@Accessors(fluent = true) +public class GeneratedEventSubscription extends AbstractEventSubscription { + private final Object eventHolder; + private final BiConsumer eventConsumer; + + public GeneratedEventSubscription(EventBus eventBus, Class eventClass, Extension owner, Subscribe.PostOrder order, Object eventHolder, BiConsumer eventConsumer) { + super(eventBus, eventClass, owner, order); + + this.eventHolder = eventHolder; + this.eventConsumer = eventConsumer; + } + + @Override + public void invoke(@NonNull T event) throws Throwable { + try { + this.eventConsumer.accept(this.eventHolder, event); + } catch (Throwable ex) { + this.owner.logger().warning("Unable to fire event " + event.getClass().getSimpleName() + " with subscription " + this.eventConsumer.getClass().getSimpleName()); + ex.printStackTrace(); + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/event/GeyserEventBus.java b/core/src/main/java/org/geysermc/geyser/event/GeyserEventBus.java index edda59e95..60e354ac9 100644 --- a/core/src/main/java/org/geysermc/geyser/event/GeyserEventBus.java +++ b/core/src/main/java/org/geysermc/geyser/event/GeyserEventBus.java @@ -33,15 +33,19 @@ import org.geysermc.geyser.api.event.EventBus; import org.geysermc.geyser.api.event.EventSubscription; import org.geysermc.geyser.api.event.Subscribe; import org.geysermc.geyser.api.extension.Extension; +import org.lanternpowered.lmbda.LambdaFactory; -import java.lang.reflect.InvocationTargetException; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import java.util.Set; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; public class GeyserEventBus implements EventBus { + private static final MethodHandles.Lookup CALLER = MethodHandles.lookup(); + private final SimpleEventBus bus = new SimpleEventBus<>(Event.class); @NonNull @@ -52,7 +56,7 @@ public class GeyserEventBus implements EventBus { @Override public void unsubscribe(@NonNull EventSubscription subscription) { - this.bus.unregister((GeyserEventSubscription) subscription); + this.bus.unregister((AbstractEventSubscription) subscription); } @SuppressWarnings("unchecked") @@ -72,19 +76,19 @@ public class GeyserEventBus implements EventBus { } Subscribe subscribe = method.getAnnotation(Subscribe.class); - this.subscribe((Class) method.getParameters()[0].getType(), (event) -> { - try { - method.invoke(eventHolder, event); - } catch (IllegalAccessException | InvocationTargetException ex) { - ex.printStackTrace(); - } - }, extension, subscribe.postOrder()); + + try { + Class type = (Class) method.getParameters()[0].getType(); + this.subscribe(type, eventHolder, LambdaFactory.createBiConsumer(CALLER.unreflect(method)), extension, subscribe.postOrder()); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } } } @Override public void unregisterAll(@NonNull Extension extension) { - this.bus.unregister((Predicate>) subscriber -> extension.equals(((GeyserEventSubscription) subscriber).owner())); + this.bus.unregister((Predicate>) subscriber -> extension.equals(((AbstractEventSubscription) subscriber).owner())); } @Override @@ -104,7 +108,13 @@ public class GeyserEventBus implements EventBus { } private EventSubscription subscribe(Class eventClass, Consumer handler, Extension extension, Subscribe.PostOrder postOrder) { - GeyserEventSubscription eventSubscription = new GeyserEventSubscription<>(this, eventClass, handler, extension, postOrder); + BaseEventSubscription eventSubscription = new BaseEventSubscription<>(this, eventClass, extension, postOrder, handler); + this.bus.register(eventClass, eventSubscription); + return eventSubscription; + } + + private EventSubscription subscribe(Class eventClass, Object eventHolder, BiConsumer handler, Extension extension, Subscribe.PostOrder postOrder) { + GeneratedEventSubscription eventSubscription = new GeneratedEventSubscription<>(this, eventClass, extension, postOrder, eventHolder, handler); this.bus.register(eventClass, eventSubscription); return eventSubscription; } diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionClassLoader.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionClassLoader.java index 426cd1de7..28b9930b4 100644 --- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionClassLoader.java +++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionClassLoader.java @@ -35,7 +35,6 @@ import java.net.URLClassLoader; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import java.util.Set; public class GeyserExtensionClassLoader extends URLClassLoader { private final GeyserExtensionLoader loader; diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java index 00e0e6701..7092d1fc2 100644 --- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java +++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java @@ -110,14 +110,14 @@ public class GeyserExtensionLoader extends ExtensionLoader { public Class classByName(final String name) throws ClassNotFoundException{ Class clazz = this.classes.get(name); try { - for(GeyserExtensionClassLoader loader : this.classLoaders.values()) { + for (GeyserExtensionClassLoader loader : this.classLoaders.values()) { try { clazz = loader.findClass(name,false); } catch(NullPointerException ignored) { } } return clazz; - } catch(NullPointerException s) { + } catch (NullPointerException s) { return null; } }