forked from StarOpenSource/Engine
Improve and fix events
This commit is contained in:
parent
5a98722520
commit
3256224329
9 changed files with 150 additions and 141 deletions
|
@ -91,9 +91,6 @@ public final class Engine {
|
||||||
// Initialize classes
|
// Initialize classes
|
||||||
initializeClasses();
|
initializeClasses();
|
||||||
|
|
||||||
// Initialize events
|
|
||||||
initializeEvents();
|
|
||||||
|
|
||||||
// Populate crash content
|
// Populate crash content
|
||||||
populateCrashContent();
|
populateCrashContent();
|
||||||
|
|
||||||
|
@ -119,14 +116,6 @@ public final class Engine {
|
||||||
new ShortcodeConverter();
|
new ShortcodeConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes all events.
|
|
||||||
*
|
|
||||||
* @since 1-alpha0
|
|
||||||
*/
|
|
||||||
private void initializeEvents() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method populates the Crash Handler's content with the default set of content.
|
* This method populates the Crash Handler's content with the default set of content.
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,15 +20,29 @@
|
||||||
package de.staropensource.sosengine.base.annotations;
|
package de.staropensource.sosengine.base.annotations;
|
||||||
|
|
||||||
import de.staropensource.sosengine.base.classes.Event;
|
import de.staropensource.sosengine.base.classes.Event;
|
||||||
|
import de.staropensource.sosengine.base.classes.EventPriority;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation for registering events on methods.
|
* Annotation for registering events on methods.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface EventListener {
|
public @interface EventListener {
|
||||||
|
/**
|
||||||
|
* The event to listen for.
|
||||||
|
*
|
||||||
|
* @return the event the method listens for
|
||||||
|
*/
|
||||||
Class<? extends Event> event();
|
Class<? extends Event> event();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The priority of the event.
|
||||||
|
*
|
||||||
|
* @return the event priority
|
||||||
|
*/
|
||||||
|
EventPriority priority();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,131 +1,14 @@
|
||||||
/*
|
|
||||||
STAROPENSOURCE ENGINE SOURCE FILE
|
|
||||||
Copyright (c) 2024 The StarOpenSource Engine Contributors
|
|
||||||
Licensed under the GNU Affero General Public License v3
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.staropensource.sosengine.base.classes;
|
package de.staropensource.sosengine.base.classes;
|
||||||
|
|
||||||
import de.staropensource.sosengine.base.annotations.EventListener;
|
|
||||||
import de.staropensource.sosengine.base.logging.Logger;
|
|
||||||
import de.staropensource.sosengine.base.types.CodePart;
|
|
||||||
import de.staropensource.sosengine.base.types.LogIssuer;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.reflections.Reflections;
|
|
||||||
import org.reflections.scanners.Scanners;
|
|
||||||
import org.reflections.util.ClasspathHelper;
|
|
||||||
import org.reflections.util.ConfigurationBuilder;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an event.
|
* Represents an event.
|
||||||
*
|
*
|
||||||
* @since 1-alpha0
|
* @since 1-alpha0
|
||||||
*/
|
*/
|
||||||
@Getter
|
@SuppressWarnings({ "unused" })
|
||||||
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
|
public interface Event {
|
||||||
public abstract class Event {
|
|
||||||
/**
|
/**
|
||||||
* Instance.
|
* Calls the event.
|
||||||
*
|
|
||||||
* @since 1-alpha0
|
|
||||||
*
|
|
||||||
* -- GETTER --
|
|
||||||
* Returns the extending {@link Event} instance.
|
|
||||||
*
|
|
||||||
* @return extending {@link Event} instance
|
|
||||||
* @since 1-alpha0
|
|
||||||
*/
|
*/
|
||||||
@Getter()
|
void callEvent();
|
||||||
protected static Event instance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the event.
|
|
||||||
*
|
|
||||||
* @since 1-alpha0
|
|
||||||
*
|
|
||||||
* -- GETTER --
|
|
||||||
* Returns the name of the event.
|
|
||||||
*
|
|
||||||
* @return the event name
|
|
||||||
* @since 1-alpha0
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
private final String eventName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @since 1-alpha0
|
|
||||||
*/
|
|
||||||
public Event() {
|
|
||||||
this.eventName = this.getClass().getName().replace(this.getClass().getPackage() + ".", "");
|
|
||||||
|
|
||||||
// Only allow one instance
|
|
||||||
if (instance == null)
|
|
||||||
instance = this;
|
|
||||||
else
|
|
||||||
Logger.crash(new LogIssuer(getClass(), CodePart.ENGINE), "Tried reinitializing " + getClass().getName() + " twice");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all annotated methods.
|
|
||||||
*
|
|
||||||
* @return list of annotated methods
|
|
||||||
* @since 1-alpha0
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
protected List<Method> getAnnotatedMethods() {
|
|
||||||
List<Method> methods = new ArrayList<>();
|
|
||||||
|
|
||||||
Reflections reflections = new Reflections(
|
|
||||||
new ConfigurationBuilder()
|
|
||||||
.setUrls(ClasspathHelper.forJavaClassPath())
|
|
||||||
.setScanners(Scanners.MethodsAnnotated)
|
|
||||||
);
|
|
||||||
Set<Method> annotatedMethods = reflections.getMethodsAnnotatedWith(EventListener.class);
|
|
||||||
|
|
||||||
for (Method method : annotatedMethods)
|
|
||||||
if (method.getAnnotation(EventListener.class).event() == this.getClass())
|
|
||||||
methods.add(method);
|
|
||||||
|
|
||||||
return methods;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invokes all annotated methods without any arguments.
|
|
||||||
*/
|
|
||||||
protected void invokeAnnotatedMethods() {
|
|
||||||
for (Method method : getAnnotatedMethods()) {
|
|
||||||
try {
|
|
||||||
method.invoke(null);
|
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NullPointerException | ExceptionInInitializerError ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the event and notifies all annotated methods about it.
|
|
||||||
*
|
|
||||||
* @since 1-alpha0
|
|
||||||
*/
|
|
||||||
public abstract void callEvent();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package de.staropensource.sosengine.base.classes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines in which order events are processed.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public enum EventPriority {
|
||||||
|
/**
|
||||||
|
* Events with this priority are processed first.
|
||||||
|
* This event is exclusive to subsystems and should not be used by applications.
|
||||||
|
*/
|
||||||
|
EXTREMELY_IMPORTANT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events with this priority are processed after {@code EXTREMELY_IMPORTANT}.
|
||||||
|
*/
|
||||||
|
VERY_IMPORTANT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events with this priority are processed after {@code VERY_IMPORTANT}.
|
||||||
|
*/
|
||||||
|
IMPORTANT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events with this priority are processed after {@code IMPORTANT}.
|
||||||
|
*/
|
||||||
|
UNIMPORTANT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events with this priority are processed after {@code UNIMPORTANT}.
|
||||||
|
*/
|
||||||
|
VERY_UNIMPORTANT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events with this priority are processed last.
|
||||||
|
* This event is exclusive to subsystems and should not be used by applications.
|
||||||
|
*/
|
||||||
|
EXTREMELY_UNIMPORTANT,
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
package de.staropensource.sosengine.base.events;
|
package de.staropensource.sosengine.base.events;
|
||||||
|
|
||||||
import de.staropensource.sosengine.base.classes.Event;
|
import de.staropensource.sosengine.base.classes.Event;
|
||||||
|
import de.staropensource.sosengine.base.utility.EventHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in the event of an engine crash, just before the JVM exists.
|
* Called in the event of an engine crash, just before the JVM exists.
|
||||||
|
@ -27,10 +28,10 @@ import de.staropensource.sosengine.base.classes.Event;
|
||||||
* @since 1-alpha0
|
* @since 1-alpha0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "unused" })
|
@SuppressWarnings({ "unused" })
|
||||||
public final class EngineCrashEvent extends Event {
|
public final class EngineCrashEvent implements Event {
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public void callEvent() {
|
public void callEvent() {
|
||||||
invokeAnnotatedMethods();
|
EventHelper.invokeAnnotatedMethods(getClass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package de.staropensource.sosengine.base.events;
|
||||||
import de.staropensource.sosengine.base.classes.Event;
|
import de.staropensource.sosengine.base.classes.Event;
|
||||||
import de.staropensource.sosengine.base.types.LogIssuer;
|
import de.staropensource.sosengine.base.types.LogIssuer;
|
||||||
import de.staropensource.sosengine.base.types.LogLevel;
|
import de.staropensource.sosengine.base.types.LogLevel;
|
||||||
|
import de.staropensource.sosengine.base.utility.EventHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
@ -33,16 +34,16 @@ import java.lang.reflect.Method;
|
||||||
* @since 1-alpha0
|
* @since 1-alpha0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "unused" })
|
@SuppressWarnings({ "unused" })
|
||||||
public final class LogEvent extends Event {
|
public final class LogEvent implements Event {
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @deprecated use the {@code callEvent} method with arguments
|
* @deprecated use the {@code callEvent} method with arguments
|
||||||
* @see LogEvent#callEventNew(LogLevel, LogIssuer, String)
|
* @see LogEvent#callEvent(LogLevel, LogIssuer, String)
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public void callEvent() {
|
public void callEvent() {
|
||||||
invokeAnnotatedMethods();
|
EventHelper.invokeAnnotatedMethods(getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,8 +51,8 @@ public final class LogEvent extends Event {
|
||||||
*
|
*
|
||||||
* @since 1-alpha0
|
* @since 1-alpha0
|
||||||
*/
|
*/
|
||||||
public void callEventNew(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
|
public void callEvent(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
|
||||||
for (Method method : getAnnotatedMethods()) {
|
for (Method method : EventHelper.getAnnotatedMethods(getClass())) {
|
||||||
try {
|
try {
|
||||||
method.invoke(null, level, logIssuer, message);
|
method.invoke(null, level, logIssuer, message);
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NullPointerException | ExceptionInInitializerError ignored) {}
|
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NullPointerException | ExceptionInInitializerError ignored) {}
|
||||||
|
|
|
@ -144,7 +144,7 @@ public final class CrashHandler {
|
||||||
Logger.getLoggerImplementation().print(LogLevel.CRASH, logIssuer, base);
|
Logger.getLoggerImplementation().print(LogLevel.CRASH, logIssuer, base);
|
||||||
|
|
||||||
// Send EngineCrash event
|
// Send EngineCrash event
|
||||||
EngineCrashEvent.getInstance().callEvent();
|
new EngineCrashEvent().callEvent();
|
||||||
|
|
||||||
// Shutdown JVM
|
// Shutdown JVM
|
||||||
if (EngineConfiguration.getInstance().isLoggerImmediateShutdown())
|
if (EngineConfiguration.getInstance().isLoggerImmediateShutdown())
|
||||||
|
|
|
@ -115,7 +115,7 @@ public final class Logger {
|
||||||
base = loggerImplementation.postPlaceholder(level, logIssuer, base);
|
base = loggerImplementation.postPlaceholder(level, logIssuer, base);
|
||||||
|
|
||||||
// Call event
|
// Call event
|
||||||
((LogEvent) LogEvent.getInstance()).callEventNew(level, logIssuer, message);
|
new LogEvent().callEvent(level, logIssuer, message);
|
||||||
|
|
||||||
// Print log message
|
// Print log message
|
||||||
loggerImplementation.print(level, logIssuer, base);
|
loggerImplementation.print(level, logIssuer, base);
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
STAROPENSOURCE ENGINE SOURCE FILE
|
||||||
|
Copyright (c) 2024 The StarOpenSource Engine Contributors
|
||||||
|
Licensed under the GNU Affero General Public License v3
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.staropensource.sosengine.base.utility;
|
||||||
|
|
||||||
|
import de.staropensource.sosengine.base.annotations.EventListener;
|
||||||
|
import de.staropensource.sosengine.base.classes.Event;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.reflections.Reflections;
|
||||||
|
import org.reflections.scanners.Scanners;
|
||||||
|
import org.reflections.util.ClasspathHelper;
|
||||||
|
import org.reflections.util.ConfigurationBuilder;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an event.
|
||||||
|
*
|
||||||
|
* @since 1-alpha0
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@SuppressWarnings({ "unused" })
|
||||||
|
public class EventHelper {
|
||||||
|
/**
|
||||||
|
* Returns all annotated methods.
|
||||||
|
*
|
||||||
|
* @return list of annotated methods
|
||||||
|
* @since 1-alpha0
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static LinkedList<Method> getAnnotatedMethods(Class<? extends Event> clazz) {
|
||||||
|
LinkedList<Method> methods = new LinkedList<>();
|
||||||
|
|
||||||
|
Reflections reflections = new Reflections(
|
||||||
|
new ConfigurationBuilder()
|
||||||
|
.setUrls(ClasspathHelper.forJavaClassPath())
|
||||||
|
.setScanners(Scanners.MethodsAnnotated)
|
||||||
|
);
|
||||||
|
Set<Method> annotatedMethods = reflections.getMethodsAnnotatedWith(EventListener.class);
|
||||||
|
|
||||||
|
for (Method method : annotatedMethods)
|
||||||
|
if (method.getAnnotation(EventListener.class).event() == clazz)
|
||||||
|
methods.add(method);
|
||||||
|
|
||||||
|
// Sort 'methods' linked list
|
||||||
|
methods.sort(Comparator.comparing(method0 -> method0.getAnnotation(EventListener.class).priority()));
|
||||||
|
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes all annotated methods without any arguments.
|
||||||
|
*
|
||||||
|
* @since 1-alpha0
|
||||||
|
*/
|
||||||
|
public static void invokeAnnotatedMethods(Class<? extends Event> clazz) {
|
||||||
|
for (Method method : getAnnotatedMethods(clazz)) {
|
||||||
|
try {
|
||||||
|
method.invoke(null);
|
||||||
|
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NullPointerException | ExceptionInInitializerError ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue