generated from xpdustry/template-plugin
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
392 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
...ributor-common/src/main/java/com/xpdustry/distributor/common/annotation/EventHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Distributor, a feature-rich framework for Mindustry plugins. | ||
* | ||
* Copyright (C) 2024 Xpdustry | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
package com.xpdustry.distributor.common.annotation; | ||
|
||
import com.xpdustry.distributor.common.util.Priority; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Marks a method as an event handler, meaning it will be called by a {@link com.xpdustry.distributor.common.event.EventManager} when its corresponding event is | ||
* posted. | ||
* <br> | ||
* The annotated method must have exactly one parameter, which is the event class. | ||
*/ | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.METHOD) | ||
public @interface EventHandler { | ||
|
||
/** | ||
* The priority of the event handler. | ||
*/ | ||
Priority priority() default Priority.NORMAL; | ||
} |
4 changes: 4 additions & 0 deletions
4
...ributor-common/src/main/java/com/xpdustry/distributor/common/annotation/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
@NullMarked | ||
package com.xpdustry.distributor.common.annotation; | ||
|
||
import org.jspecify.annotations.NullMarked; |
126 changes: 126 additions & 0 deletions
126
distributor-common/src/main/java/com/xpdustry/distributor/common/event/EventManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/* | ||
* Distributor, a feature-rich framework for Mindustry plugins. | ||
* | ||
* Copyright (C) 2024 Xpdustry | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
package com.xpdustry.distributor.common.event; | ||
|
||
import com.xpdustry.distributor.common.plugin.MindustryPlugin; | ||
import com.xpdustry.distributor.common.util.Priority; | ||
import java.util.function.Consumer; | ||
|
||
/** | ||
* The event bus of this server. A better alternative to {@link arc.Events}. | ||
* <br> | ||
* Event subscribers registered with this class will not crash the server if an exception is thrown but be logged instead. | ||
* Subscribers also come with {@link EventSubscription} objects to dynamically unsubscribe them. And also | ||
* {@link Priority} to make sure your subscribers are called in a specific order. | ||
* <pre> {@code | ||
* final EventBus bus = DistributorProvider.get().getEventBus(); | ||
* final MindustryPlugin plugin = ...; | ||
* final EventSubscription subscription = bus.subscribe(EventType.PlayerJoin.class, plugin, event -> { | ||
* event.player.sendMessage("Hello " + event.player.name() + "!"); | ||
* }); | ||
* // When no longer needed, you can unsubscribe the listener | ||
* subscription.unsubscribe(); | ||
* } </pre> | ||
* <br> | ||
*/ | ||
public interface EventManager { | ||
|
||
static EventManager create() { | ||
return new EventManagerImpl(); | ||
} | ||
|
||
/** | ||
* Subscribe to an event. | ||
* | ||
* @param event the event class to subscribe to | ||
* @param priority the priority of the listener | ||
* @param plugin the plugin that owns the listener | ||
* @param listener the listener to subscribe | ||
* @param <E> the type of the event | ||
* @return the subscription of the subscribed listener | ||
*/ | ||
<E> EventSubscription subscribe( | ||
final Class<E> event, final Priority priority, final MindustryPlugin plugin, final Consumer<E> listener); | ||
|
||
/** | ||
* Subscribe to an event. | ||
* | ||
* @param event the event class to subscribe to | ||
* @param plugin the plugin that owns the listener | ||
* @param listener the listener to subscribe | ||
* @param <E> the type of the event | ||
* @return the subscription of the subscribed listener | ||
*/ | ||
default <E> EventSubscription subscribe( | ||
final Class<E> event, final MindustryPlugin plugin, final Consumer<E> listener) { | ||
return this.subscribe(event, Priority.NORMAL, plugin, listener); | ||
} | ||
|
||
/** | ||
* Subscribe to an event. | ||
* | ||
* @param event the event enum to subscribe to | ||
* @param priority the priority of the listener | ||
* @param plugin the plugin that owns the listener | ||
* @param listener the listener to subscribe | ||
* @param <E> the type of the enum event | ||
* @return the subscription of the subscribed listener | ||
*/ | ||
<E extends Enum<E>> EventSubscription subscribe( | ||
final E event, final Priority priority, final MindustryPlugin plugin, final Runnable listener); | ||
|
||
/** | ||
* Subscribe to an event. | ||
* | ||
* @param event the event enum to subscribe to | ||
* @param plugin the plugin that owns the listener | ||
* @param listener the listener to subscribe | ||
* @param <E> the type of the enum event | ||
* @return the subscription of the subscribed listener | ||
*/ | ||
default <E extends Enum<E>> EventSubscription subscribe( | ||
final E event, final MindustryPlugin plugin, final Runnable listener) { | ||
return this.subscribe(event, Priority.NORMAL, plugin, listener); | ||
} | ||
|
||
/** | ||
* Posts the event to the arc event bus. | ||
* | ||
* @param event the event to post | ||
* @param <E> the type of the event | ||
*/ | ||
<E> void post(final E event); | ||
|
||
/** | ||
* Posts the event to the arc event bus to the listeners of the given super class. | ||
* | ||
* @param clazz the class of the event | ||
* @param event the event to post | ||
* @param <E> the type of the event | ||
*/ | ||
<E> void post(final Class<? super E> clazz, final E event); | ||
|
||
/** | ||
* Posts the enum event to the arc event bus. | ||
* | ||
* @param event the enum event to post | ||
* @param <E> the type of the enum event | ||
*/ | ||
<E extends Enum<E>> void post(final E event); | ||
} |
126 changes: 126 additions & 0 deletions
126
distributor-common/src/main/java/com/xpdustry/distributor/common/event/EventManagerImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/* | ||
* Distributor, a feature-rich framework for Mindustry plugins. | ||
* | ||
* Copyright (C) 2024 Xpdustry | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
package com.xpdustry.distributor.common.event; | ||
|
||
import arc.Events; | ||
import arc.func.Cons; | ||
import arc.struct.ObjectMap; | ||
import arc.struct.Seq; | ||
import com.xpdustry.distributor.common.plugin.MindustryPlugin; | ||
import com.xpdustry.distributor.common.plugin.PluginAware; | ||
import com.xpdustry.distributor.common.util.Priority; | ||
import java.util.Comparator; | ||
import java.util.function.Consumer; | ||
|
||
final class EventManagerImpl implements EventManager { | ||
|
||
private static final Comparator<Cons<?>> COMPARATOR = (a, b) -> { | ||
final var priorityA = a instanceof ConsumerCons<?> m ? m.priority : Priority.NORMAL; | ||
final var priorityB = b instanceof ConsumerCons<?> m ? m.priority : Priority.NORMAL; | ||
return priorityA.compareTo(priorityB); | ||
}; | ||
|
||
final ObjectMap<Object, Seq<Cons<?>>> events; | ||
|
||
@SuppressWarnings("unchecked") | ||
EventManagerImpl() { | ||
try { | ||
final var field = Events.class.getDeclaredField("events"); | ||
field.setAccessible(true); | ||
this.events = (ObjectMap<Object, Seq<Cons<?>>>) field.get(null); | ||
} catch (final ReflectiveOperationException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public <E> EventSubscription subscribe( | ||
final Class<E> event, final Priority priority, final MindustryPlugin plugin, final Consumer<E> listener) { | ||
return this.subscribe(event, new ConsumerCons<>(listener, priority, plugin)); | ||
} | ||
|
||
@Override | ||
public <E extends Enum<E>> EventSubscription subscribe( | ||
final E event, final Priority priority, final MindustryPlugin plugin, final Runnable listener) { | ||
return this.subscribe(event, new ConsumerCons<>(e -> listener.run(), priority, plugin)); | ||
} | ||
|
||
@SuppressWarnings("ConstantValue") // <- intellij thinks ObjectMap.get never return null, cringe... | ||
private <E> EventSubscription subscribe(final Object event, final ConsumerCons<E> subscriber) { | ||
this.events.get(event, () -> new Seq<>(Cons.class)).add(subscriber).sort(COMPARATOR); | ||
return () -> { | ||
final var subscribers = this.events.get(event); | ||
if (subscribers != null) { | ||
subscribers.remove(subscriber); | ||
if (subscribers.isEmpty()) { | ||
this.events.remove(event); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
@Override | ||
public <E> void post(final E event) { | ||
Events.fire(event.getClass(), event); | ||
} | ||
|
||
@Override | ||
public <E> void post(final Class<? super E> clazz, final E event) { | ||
Events.fire(clazz, event); | ||
} | ||
|
||
@Override | ||
public <E extends Enum<E>> void post(final E event) { | ||
Events.fire(event); | ||
} | ||
|
||
@SuppressWarnings("ClassCanBeRecord") | ||
private static final class ConsumerCons<T> implements Cons<T>, PluginAware { | ||
|
||
private final Consumer<T> consumer; | ||
private final Priority priority; | ||
private final MindustryPlugin plugin; | ||
|
||
private ConsumerCons(final Consumer<T> consumer, final Priority priority, final MindustryPlugin plugin) { | ||
this.consumer = consumer; | ||
this.priority = priority; | ||
this.plugin = plugin; | ||
} | ||
|
||
@Override | ||
public void get(final T event) { | ||
try { | ||
this.consumer.accept(event); | ||
} catch (final Throwable e) { | ||
this.plugin | ||
.getLogger() | ||
.atError() | ||
.setMessage("An error occurred while handling a {} event.") | ||
.addArgument(event.getClass().getSimpleName()) | ||
.setCause(e) | ||
.log(); | ||
} | ||
} | ||
|
||
@Override | ||
public MindustryPlugin getPlugin() { | ||
return this.plugin; | ||
} | ||
} | ||
} |
Oops, something went wrong.