mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-04 00:45:57 +00:00
Merge branch 'master' into ver/4.3.0
This commit is contained in:
commit
d670fc904f
@ -1,4 +0,0 @@
|
|||||||
package com.dfsek.terra.api.core.event;
|
|
||||||
|
|
||||||
public interface Event {
|
|
||||||
}
|
|
@ -1,7 +1,14 @@
|
|||||||
package com.dfsek.terra.api.core.event;
|
package com.dfsek.terra.api.core.event;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.core.event.events.Event;
|
||||||
|
|
||||||
public interface EventManager {
|
public interface EventManager {
|
||||||
void callEvent(Event event);
|
/**
|
||||||
|
* Call an event, and return the execution status.
|
||||||
|
* @param event Event to pass to all registered EventListeners.
|
||||||
|
* @return False if the event is cancellable and has been cancelled, otherwise true.
|
||||||
|
*/
|
||||||
|
boolean callEvent(Event event);
|
||||||
|
|
||||||
void registerListener(EventListener listener);
|
void registerListener(EventListener listener);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.dfsek.terra.api.core.event;
|
package com.dfsek.terra.api.core.event;
|
||||||
|
|
||||||
import com.dfsek.terra.api.core.TerraPlugin;
|
import com.dfsek.terra.api.core.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.core.event.annotations.Priority;
|
||||||
|
import com.dfsek.terra.api.core.event.events.Cancellable;
|
||||||
|
import com.dfsek.terra.api.core.event.events.Event;
|
||||||
import com.dfsek.terra.api.util.ReflectionUtil;
|
import com.dfsek.terra.api.util.ReflectionUtil;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@ -8,12 +11,14 @@ import java.io.StringWriter;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TerraEventManager implements EventManager {
|
public class TerraEventManager implements EventManager {
|
||||||
private final Map<Class<? extends Event>, Map<EventListener, List<Method>>> listeners = new HashMap<>();
|
private final Map<Class<? extends Event>, List<ListenerHolder>> listeners = new HashMap<>();
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
|
|
||||||
public TerraEventManager(TerraPlugin main) {
|
public TerraEventManager(TerraPlugin main) {
|
||||||
@ -21,26 +26,27 @@ public class TerraEventManager implements EventManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void callEvent(Event event) {
|
public boolean callEvent(Event event) {
|
||||||
if(!listeners.containsKey(event.getClass())) return;
|
listeners.getOrDefault(event.getClass(), Collections.emptyList()).forEach(listenerHolder -> {
|
||||||
listeners.get(event.getClass()).forEach((eventListener, methods) -> methods.forEach(method -> {
|
|
||||||
try {
|
try {
|
||||||
method.invoke(eventListener, event);
|
listenerHolder.method.invoke(listenerHolder.listener, event);
|
||||||
} catch(InvocationTargetException e) {
|
} catch(InvocationTargetException e) {
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
e.getTargetException().printStackTrace(new PrintWriter(writer));
|
e.getTargetException().printStackTrace(new PrintWriter(writer));
|
||||||
main.getLogger().warning("Exception occurred during event handling:");
|
main.getLogger().warning("Exception occurred during event handling:");
|
||||||
main.getLogger().warning(writer.toString());
|
main.getLogger().warning(writer.toString());
|
||||||
main.getLogger().warning("Report this to the maintainers of " + eventListener.getClass().getCanonicalName());
|
main.getLogger().warning("Report this to the maintainers of " + listenerHolder.method.getName());
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
e.printStackTrace(new PrintWriter(writer));
|
e.printStackTrace(new PrintWriter(writer));
|
||||||
main.getLogger().warning("Exception occurred during event handling:");
|
main.getLogger().warning("Exception occurred during event handling:");
|
||||||
main.getLogger().warning(writer.toString());
|
main.getLogger().warning(writer.toString());
|
||||||
main.getLogger().warning("Report this to the maintainers of " + eventListener.getClass().getCanonicalName());
|
main.getLogger().warning("Report this to the maintainers of " + listenerHolder.method.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
if(event instanceof Cancellable) return !((Cancellable) event).isCancelled();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -53,8 +59,34 @@ public class TerraEventManager implements EventManager {
|
|||||||
if(method.getParameterCount() != 1) continue; // Check that parameter count is only 1.
|
if(method.getParameterCount() != 1) continue; // Check that parameter count is only 1.
|
||||||
Class<?> eventParam = method.getParameterTypes()[0];
|
Class<?> eventParam = method.getParameterTypes()[0];
|
||||||
if(!Event.class.isAssignableFrom(eventParam)) continue; // Check that parameter is an Event.
|
if(!Event.class.isAssignableFrom(eventParam)) continue; // Check that parameter is an Event.
|
||||||
|
|
||||||
|
Priority p = method.getAnnotation(Priority.class);
|
||||||
|
|
||||||
|
int priority = p == null ? 0 : p.value();
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
listeners.computeIfAbsent((Class<? extends Event>) eventParam, e -> new HashMap<>()).computeIfAbsent(listener, l -> new ArrayList<>()).add(method);
|
|
||||||
|
List<ListenerHolder> holders = listeners.computeIfAbsent((Class<? extends Event>) eventParam, e -> new ArrayList<>());
|
||||||
|
|
||||||
|
holders.add(new ListenerHolder(method, listener, priority));
|
||||||
|
|
||||||
|
holders.sort(Comparator.comparingInt(ListenerHolder::getPriority)); // Sort priorities.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class ListenerHolder {
|
||||||
|
private final Method method;
|
||||||
|
private final EventListener listener;
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
|
private ListenerHolder(Method method, EventListener listener, int priority) {
|
||||||
|
this.method = method;
|
||||||
|
this.listener = listener;
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.dfsek.terra.api.core.event.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotated listener methods will have a specific priority set.
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface Priority {
|
||||||
|
/**
|
||||||
|
* Highest possible priority. Listeners with this priority will always be invoked first.
|
||||||
|
*/
|
||||||
|
int HIGHEST = Integer.MAX_VALUE;
|
||||||
|
/**
|
||||||
|
* Lowest possible priority. Listeners with this priority will always be invoked last.
|
||||||
|
*/
|
||||||
|
int LOWEST = Integer.MIN_VALUE;
|
||||||
|
/**
|
||||||
|
* Default priority.
|
||||||
|
*/
|
||||||
|
int NORMAL = 0;
|
||||||
|
/**
|
||||||
|
* High priority.
|
||||||
|
*/
|
||||||
|
int HIGH = 1;
|
||||||
|
/**
|
||||||
|
* Low Priority.
|
||||||
|
*/
|
||||||
|
int LOW = -1;
|
||||||
|
/**
|
||||||
|
* @return Priority of this event. Events are executed from lowest to highest priorities.
|
||||||
|
*/
|
||||||
|
int value();
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.dfsek.terra.api.core.event.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events that implement this interface may be cancelled.
|
||||||
|
*
|
||||||
|
* Cancelling an event is assumed to stop the execution of whatever action triggered the event.
|
||||||
|
*/
|
||||||
|
public interface Cancellable extends Event {
|
||||||
|
boolean isCancelled();
|
||||||
|
void setCancelled();
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package com.dfsek.terra.api.core.event.events;
|
||||||
|
|
||||||
|
public interface Event {
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package com.dfsek.terra.api.core.event.events.config;
|
package com.dfsek.terra.api.core.event.events.config;
|
||||||
|
|
||||||
import com.dfsek.terra.api.core.event.Event;
|
import com.dfsek.terra.api.core.event.events.Event;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
|
|
||||||
public abstract class ConfigPackLoadEvent implements Event {
|
public abstract class ConfigPackLoadEvent implements Event {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.dfsek.terra.api.core.event.events.world;
|
package com.dfsek.terra.api.core.event.events.world;
|
||||||
|
|
||||||
import com.dfsek.terra.api.core.event.Event;
|
import com.dfsek.terra.api.core.event.events.Event;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,7 +2,8 @@ package event;
|
|||||||
|
|
||||||
import com.dfsek.tectonic.loading.TypeRegistry;
|
import com.dfsek.tectonic.loading.TypeRegistry;
|
||||||
import com.dfsek.terra.api.core.TerraPlugin;
|
import com.dfsek.terra.api.core.TerraPlugin;
|
||||||
import com.dfsek.terra.api.core.event.Event;
|
import com.dfsek.terra.api.core.event.annotations.Priority;
|
||||||
|
import com.dfsek.terra.api.core.event.events.Event;
|
||||||
import com.dfsek.terra.api.core.event.EventListener;
|
import com.dfsek.terra.api.core.event.EventListener;
|
||||||
import com.dfsek.terra.api.core.event.EventManager;
|
import com.dfsek.terra.api.core.event.EventManager;
|
||||||
import com.dfsek.terra.api.core.event.TerraEventManager;
|
import com.dfsek.terra.api.core.event.TerraEventManager;
|
||||||
@ -127,6 +128,7 @@ public class EventTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class TestListener2 implements EventListener {
|
static class TestListener2 implements EventListener {
|
||||||
|
@Priority(Priority.LOWEST)
|
||||||
public void doThing(TestEvent event) {
|
public void doThing(TestEvent event) {
|
||||||
System.out.println("Event value 2: " + event.value);
|
System.out.println("Event value 2: " + event.value);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user