-
Notifications
You must be signed in to change notification settings - Fork 0
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
0 parents
commit 4dc2bbc
Showing
11 changed files
with
434 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
target/ | ||
!.mvn/wrapper/maven-wrapper.jar | ||
!**/src/main/**/target/ | ||
!**/src/test/**/target/ | ||
|
||
### IntelliJ IDEA ### | ||
.idea/modules.xml | ||
.idea/jarRepositories.xml | ||
.idea/compiler.xml | ||
.idea/libraries/ | ||
*.iws | ||
*.iml | ||
*.ipr | ||
|
||
### Eclipse ### | ||
.apt_generated | ||
.classpath | ||
.factorypath | ||
.project | ||
.settings | ||
.springBeans | ||
.sts4-cache | ||
|
||
### NetBeans ### | ||
/nbproject/private/ | ||
/nbbuild/ | ||
/dist/ | ||
/nbdist/ | ||
/.nb-gradle/ | ||
build/ | ||
!**/src/main/**/build/ | ||
!**/src/test/**/build/ | ||
|
||
### VS Code ### | ||
.vscode/ | ||
|
||
### Mac OS ### | ||
.DS_Store |
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,25 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>de.cyklon</groupId> | ||
<artifactId>JEvent</artifactId> | ||
<version>1.0</version> | ||
|
||
<properties> | ||
<maven.compiler.source>17</maven.compiler.source> | ||
<maven.compiler.target>17</maven.compiler.target> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.jetbrains</groupId> | ||
<artifactId>annotations</artifactId> | ||
<version>22.0.0</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
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,23 @@ | ||
package de.cyklon.jevent; | ||
|
||
/** | ||
* This interface can be implemented to make an event cancelable | ||
* <p> | ||
* If the event is marked as canceld, all listeners that would be executed afterwards will not be executed unless ignoreCancelled is set to true in the @{@link EventHandler} annotation. | ||
* @author <a href="https://github.com/cyklon73">Cyklon73</a> | ||
*/ | ||
public interface Cancellable { | ||
|
||
/** | ||
* returns true if the event was marked as canceled | ||
* @return true if event was canceled | ||
*/ | ||
boolean isCancelled(); | ||
|
||
/** | ||
* sets the canceled status of the event to the specified value | ||
* @param cancelled the new status | ||
*/ | ||
void setCancelled(boolean cancelled); | ||
|
||
} |
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,25 @@ | ||
package de.cyklon.jevent; | ||
|
||
import org.jetbrains.annotations.Nullable; | ||
|
||
public abstract class CancellableEvent extends Event implements Cancellable { | ||
|
||
private boolean cancelled = false; | ||
|
||
protected CancellableEvent() { | ||
} | ||
|
||
protected CancellableEvent(@Nullable String name) { | ||
super(name); | ||
} | ||
|
||
@Override | ||
public boolean isCancelled() { | ||
return cancelled; | ||
} | ||
|
||
@Override | ||
public void setCancelled(boolean cancelled) { | ||
this.cancelled = cancelled; | ||
} | ||
} |
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,57 @@ | ||
package de.cyklon.jevent; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
/** | ||
* the event base class. | ||
* Extend this class to create your own event | ||
* @author <a href="https://github.com/cyklon73">Cyklon73</a> | ||
*/ | ||
public abstract class Event { | ||
|
||
/** | ||
* the event name | ||
*/ | ||
private final String name; | ||
|
||
|
||
/** | ||
* constructs the event, with the class name as the event name | ||
*/ | ||
protected Event() { | ||
this(null); | ||
} | ||
|
||
/** | ||
* constructs the event with a specific name | ||
* @param name the event name. If it is null, it is set to the class name | ||
*/ | ||
protected Event(@Nullable String name) { | ||
this.name = name==null ? this.getClass().getSimpleName() : name; | ||
} | ||
|
||
/** | ||
* call all listeners for this event | ||
* @see EventManager#callEvent(Event) | ||
* @return true if the event was canceled | ||
*/ | ||
public boolean callEvent() { | ||
JEvent.MANAGER.callEvent(this); | ||
if (this instanceof Cancellable) return ((Cancellable)this).isCancelled(); | ||
return false; | ||
} | ||
|
||
/** | ||
* @return the name of the Event | ||
*/ | ||
@NotNull | ||
public String getEventName() { | ||
return name; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return Event.class + "(" + getEventName() + ")"; | ||
} | ||
} |
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,59 @@ | ||
package de.cyklon.jevent; | ||
|
||
|
||
/** | ||
* is called when an error occurs in the event system | ||
* @author <a href="https://github.com/cyklon73">Cyklon73</a> | ||
*/ | ||
public class EventException extends RuntimeException { | ||
|
||
private final Throwable cause; | ||
|
||
/** | ||
* Constructs a new EventException based on the given Exception | ||
* | ||
* @param throwable Exception that triggered this Exception | ||
*/ | ||
public EventException(Throwable throwable) { | ||
cause = throwable; | ||
} | ||
|
||
/** | ||
* Constructs a new EventException | ||
*/ | ||
public EventException() { | ||
cause = null; | ||
} | ||
|
||
/** | ||
* Constructs a new EventException with the given message | ||
* | ||
* @param cause The exception that caused this | ||
* @param message The message | ||
*/ | ||
public EventException(Throwable cause, String message) { | ||
super(message); | ||
this.cause = cause; | ||
} | ||
|
||
/** | ||
* Constructs a new EventException with the given message | ||
* | ||
* @param message The message | ||
*/ | ||
public EventException(String message) { | ||
super(message); | ||
cause = null; | ||
} | ||
|
||
/** | ||
* If applicable, returns the Exception that triggered this Exception | ||
* | ||
* @return Inner exception, or null if one does not exist | ||
*/ | ||
@Override | ||
public Throwable getCause() { | ||
return cause; | ||
} | ||
|
||
} |
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,43 @@ | ||
package de.cyklon.jevent; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* An annotation to mark methods as being event handler methods | ||
* @author <a href="https://github.com/cyklon73">Cyklon73</a> | ||
*/ | ||
@Target({ElementType.METHOD}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface EventHandler { | ||
|
||
byte LOWEST = -2; | ||
byte LOW = -1; | ||
byte NORMAL = 0; | ||
byte HIGH = 1; | ||
byte HIGHEST = 2; | ||
byte MONITOR = 3; | ||
|
||
|
||
/** | ||
* Define the priority of the event. | ||
* <p> | ||
* Lowest priority to the Highest priority executed. | ||
* @return the priority | ||
*/ | ||
byte priority() default NORMAL; | ||
|
||
/** | ||
* Define if the handler ignores a cancelled event. | ||
* <p> | ||
* If ignoreCancelled is true and the event is cancelled, the method is | ||
* not called. Otherwise, the method is always called. | ||
* | ||
* @return whether cancelled events should be ignored | ||
*/ | ||
boolean ignoreCancelled() default false; | ||
|
||
|
||
} |
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,35 @@ | ||
package de.cyklon.jevent; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
|
||
/** | ||
* The EventManager to manage and execute events | ||
* @author <a href="https://github.com/cyklon73">Cyklon73</a> | ||
*/ | ||
public sealed interface EventManager permits JEvent { | ||
|
||
/** | ||
* registers all methods annotated with @{@link EventHandler} | ||
* @param obj the object from which events are to be registered | ||
*/ | ||
void registerListener(@NotNull Object obj); | ||
|
||
/** | ||
* removes all listeners that have the type of the specified class | ||
* @param clazz The type of listener Object to be removed | ||
*/ | ||
void unregisterListener(@NotNull Class<?> clazz); | ||
|
||
/** | ||
* removes all listeners | ||
*/ | ||
void unregisterAll(); | ||
|
||
|
||
/** | ||
* calls the passed event and executes all registered listeners, as well as all listeners that were registered for a superclass of the event | ||
* @param event the event to be executed | ||
*/ | ||
void callEvent(@NotNull Event event); | ||
|
||
} |
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,73 @@ | ||
package de.cyklon.jevent; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.util.Collection; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
|
||
/** | ||
* The handler object represents a single event listener method | ||
* @author <a href="https://github.com/cyklon73">Cyklon73</a> | ||
*/ | ||
class Handler implements Comparable<Handler> { | ||
|
||
private final Object listener; | ||
private final Method handler; | ||
private Class<? extends Event> eventType = null; | ||
private final byte priority; | ||
private final boolean ignoreCancelled; | ||
|
||
@SuppressWarnings("unchecked") | ||
private Handler(Object listener, Method handler, byte priority, boolean ignoreCancelled) { | ||
this.listener = listener; | ||
this.handler = handler; | ||
this.handler.setAccessible(true); | ||
for (Class<?> parameterType : handler.getParameterTypes()) { | ||
if (Event.class.isAssignableFrom(parameterType)) { | ||
this.eventType = (Class<? extends Event>) parameterType; | ||
break; | ||
} | ||
} | ||
if (eventType==null) throw new EventException("the method must have an event as a parameter!"); | ||
this.priority = priority; | ||
this.ignoreCancelled = ignoreCancelled; | ||
} | ||
|
||
public Object getListener() { | ||
return listener; | ||
} | ||
|
||
public boolean isSuitableHandler(Class<? extends Event> event) { | ||
return eventType.isAssignableFrom(event); | ||
} | ||
|
||
public void invoke(Event event) { | ||
if (event instanceof Cancellable && ((Cancellable)event).isCancelled() && !ignoreCancelled) return; | ||
if (isSuitableHandler(event.getClass())) { | ||
try { | ||
handler.invoke(listener, event); | ||
} catch (IllegalAccessException | InvocationTargetException e) { | ||
throw new EventException(e); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public int compareTo(@NotNull Handler o) { | ||
return Byte.compare(o.priority, this.priority); | ||
} | ||
|
||
public static Collection<Handler> getHandlers(Object listener) { | ||
Method[] methods = listener.getClass().getDeclaredMethods(); | ||
List<Handler> handlers = new LinkedList<>(); | ||
for (Method handler : methods) { | ||
EventHandler annotation = handler.getAnnotation(EventHandler.class); | ||
if (annotation==null) continue; | ||
handlers.add(new Handler(listener, handler, annotation.priority(), annotation.ignoreCancelled())); | ||
} | ||
return handlers; | ||
} | ||
} |
Oops, something went wrong.