Use lambda metadata factory for events

stonks
This commit is contained in:
RednedEpic 2022-01-16 22:52:27 -06:00
parent ac134b84f2
commit 5abf989139
7 changed files with 146 additions and 44 deletions

View file

@ -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<T extends Event> {
@NonNull
Class<T> eventClass();
/**
* Gets the consumer responsible for handling
* this event.
*
* @return the consumer responsible for this event
*/
@NonNull
Consumer<? super T> eventConsumer();
/**
* Gets the {@link Extension} that owns this
* event subscription.

View file

@ -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<T extends Event> implements EventSubscription<T>, EventSubscriber<T> {
private final EventBus eventBus;
private final Class<T> eventClass;
private final Consumer<? super T> eventConsumer;
private final Extension owner;
private final Subscribe.PostOrder order;
public abstract class AbstractEventSubscription<T extends Event> implements EventSubscription<T>, EventSubscriber<T> {
protected final EventBus eventBus;
protected final Class<T> eventClass;
protected final Extension owner;
protected final Subscribe.PostOrder order;
@Getter(AccessLevel.NONE) private boolean active;
@Override
@ -65,16 +61,6 @@ public class GeyserEventSubscription<T extends Event> 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();

View file

@ -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<T extends Event> extends AbstractEventSubscription<T> {
private final Consumer<? super T> eventConsumer;
public BaseEventSubscription(EventBus eventBus, Class<T> eventClass, Extension owner, Subscribe.PostOrder order, Consumer<? super T> 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();
}
}
}

View file

@ -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<T extends Event> extends AbstractEventSubscription<T> {
private final Object eventHolder;
private final BiConsumer<Object, ? super T> eventConsumer;
public GeneratedEventSubscription(EventBus eventBus, Class<T> eventClass, Extension owner, Subscribe.PostOrder order, Object eventHolder, BiConsumer<Object, ? super T> 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();
}
}
}

View file

@ -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<Event> bus = new SimpleEventBus<>(Event.class);
@NonNull
@ -52,7 +56,7 @@ public class GeyserEventBus implements EventBus {
@Override
public <T extends Event> void unsubscribe(@NonNull EventSubscription<T> subscription) {
this.bus.unregister((GeyserEventSubscription<T>) subscription);
this.bus.unregister((AbstractEventSubscription<T>) subscription);
}
@SuppressWarnings("unchecked")
@ -72,19 +76,19 @@ public class GeyserEventBus implements EventBus {
}
Subscribe subscribe = method.getAnnotation(Subscribe.class);
this.subscribe((Class<? extends Event>) method.getParameters()[0].getType(), (event) -> {
try {
method.invoke(eventHolder, event);
} catch (IllegalAccessException | InvocationTargetException ex) {
Class<? extends Event> type = (Class<? extends Event>) method.getParameters()[0].getType();
this.subscribe(type, eventHolder, LambdaFactory.createBiConsumer(CALLER.unreflect(method)), extension, subscribe.postOrder());
} catch (IllegalAccessException ex) {
ex.printStackTrace();
}
}, extension, subscribe.postOrder());
}
}
@Override
public void unregisterAll(@NonNull Extension extension) {
this.bus.unregister((Predicate<EventSubscriber<?>>) subscriber -> extension.equals(((GeyserEventSubscription<?>) subscriber).owner()));
this.bus.unregister((Predicate<EventSubscriber<?>>) subscriber -> extension.equals(((AbstractEventSubscription<?>) subscriber).owner()));
}
@Override
@ -104,7 +108,13 @@ public class GeyserEventBus implements EventBus {
}
private <T extends Event> EventSubscription<T> subscribe(Class<T> eventClass, Consumer<? super T> handler, Extension extension, Subscribe.PostOrder postOrder) {
GeyserEventSubscription<T> eventSubscription = new GeyserEventSubscription<>(this, eventClass, handler, extension, postOrder);
BaseEventSubscription<T> eventSubscription = new BaseEventSubscription<>(this, eventClass, extension, postOrder, handler);
this.bus.register(eventClass, eventSubscription);
return eventSubscription;
}
private <T extends Event> EventSubscription<T> subscribe(Class<T> eventClass, Object eventHolder, BiConsumer<Object, ? super T> handler, Extension extension, Subscribe.PostOrder postOrder) {
GeneratedEventSubscription<T> eventSubscription = new GeneratedEventSubscription<>(this, eventClass, extension, postOrder, eventHolder, handler);
this.bus.register(eventClass, eventSubscription);
return eventSubscription;
}

View file

@ -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;

View file

@ -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;
}
}