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
|
||||
initializeClasses();
|
||||
|
||||
// Initialize events
|
||||
initializeEvents();
|
||||
|
||||
// Populate crash content
|
||||
populateCrashContent();
|
||||
|
||||
|
@ -119,14 +116,6 @@ public final class Engine {
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -20,15 +20,29 @@
|
|||
package de.staropensource.sosengine.base.annotations;
|
||||
|
||||
import de.staropensource.sosengine.base.classes.Event;
|
||||
import de.staropensource.sosengine.base.classes.EventPriority;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Annotation for registering events on methods.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Documented
|
||||
public @interface EventListener {
|
||||
/**
|
||||
* The event to listen for.
|
||||
*
|
||||
* @return the event the method listens for
|
||||
*/
|
||||
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;
|
||||
|
||||
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.
|
||||
*
|
||||
* @since 1-alpha0
|
||||
*/
|
||||
@Getter
|
||||
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
|
||||
public abstract class Event {
|
||||
@SuppressWarnings({ "unused" })
|
||||
public interface Event {
|
||||
/**
|
||||
* Instance.
|
||||
*
|
||||
* @since 1-alpha0
|
||||
*
|
||||
* -- GETTER --
|
||||
* Returns the extending {@link Event} instance.
|
||||
*
|
||||
* @return extending {@link Event} instance
|
||||
* @since 1-alpha0
|
||||
* Calls the event.
|
||||
*/
|
||||
@Getter()
|
||||
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();
|
||||
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;
|
||||
|
||||
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.
|
||||
|
@ -27,10 +28,10 @@ import de.staropensource.sosengine.base.classes.Event;
|
|||
* @since 1-alpha0
|
||||
*/
|
||||
@SuppressWarnings({ "unused" })
|
||||
public final class EngineCrashEvent extends Event {
|
||||
public final class EngineCrashEvent implements Event {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
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.types.LogIssuer;
|
||||
import de.staropensource.sosengine.base.types.LogLevel;
|
||||
import de.staropensource.sosengine.base.utility.EventHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -33,16 +34,16 @@ import java.lang.reflect.Method;
|
|||
* @since 1-alpha0
|
||||
*/
|
||||
@SuppressWarnings({ "unused" })
|
||||
public final class LogEvent extends Event {
|
||||
public final class LogEvent implements Event {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @deprecated use the {@code callEvent} method with arguments
|
||||
* @see LogEvent#callEventNew(LogLevel, LogIssuer, String)
|
||||
* @see LogEvent#callEvent(LogLevel, LogIssuer, String)
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void callEvent() {
|
||||
invokeAnnotatedMethods();
|
||||
EventHelper.invokeAnnotatedMethods(getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,8 +51,8 @@ public final class LogEvent extends Event {
|
|||
*
|
||||
* @since 1-alpha0
|
||||
*/
|
||||
public void callEventNew(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
|
||||
for (Method method : getAnnotatedMethods()) {
|
||||
public void callEvent(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
|
||||
for (Method method : EventHelper.getAnnotatedMethods(getClass())) {
|
||||
try {
|
||||
method.invoke(null, level, logIssuer, message);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NullPointerException | ExceptionInInitializerError ignored) {}
|
||||
|
|
|
@ -144,7 +144,7 @@ public final class CrashHandler {
|
|||
Logger.getLoggerImplementation().print(LogLevel.CRASH, logIssuer, base);
|
||||
|
||||
// Send EngineCrash event
|
||||
EngineCrashEvent.getInstance().callEvent();
|
||||
new EngineCrashEvent().callEvent();
|
||||
|
||||
// Shutdown JVM
|
||||
if (EngineConfiguration.getInstance().isLoggerImmediateShutdown())
|
||||
|
|
|
@ -115,7 +115,7 @@ public final class Logger {
|
|||
base = loggerImplementation.postPlaceholder(level, logIssuer, base);
|
||||
|
||||
// Call event
|
||||
((LogEvent) LogEvent.getInstance()).callEventNew(level, logIssuer, message);
|
||||
new LogEvent().callEvent(level, logIssuer, message);
|
||||
|
||||
// Print log message
|
||||
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