Manages event subscription, dispatching, and listener registration.
*
@@ -43,7 +43,7 @@
* @since 1.0.0
*/
@SuppressWarnings({"rawtypes", "unchecked"})
-public class EventBus implements TargetableEventBus, InvertableEventBus {
+public class EventBus implements IEventBus {
/**
* The amount of {@linkplain EventBus} instances that have been created
@@ -244,97 +244,6 @@ public boolean dispatch(Object event, Class> type, boolean invertPriority) {
return false;
}
- /**
- * Dispatches the given event to the target listener class
- *
- * @param event the {@linkplain IClassTargetingEvent} to be dispatched
- * @return {@code true} if the given event was {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
- * @throws NullPointerException if the given event is {@code null}
- * @throws UnsupportedOperationException if this event bus is {@link #shutdown}
- * @deprecated This method's functionality is now built into {@link #dispatch(Object)}.
- */
- @Deprecated(since = "3.3.0", forRemoval = true)
- @Override
- public boolean dispatchTargeted(IClassTargetingEvent event) {
- return dispatchTargeted(event, null);
- }
-
- /**
- * Dispatches the given {@link IClassTargetingEvent} to the target listener class.
- *
- *
The {@code type} parameter serves as a filtering mechanism for listeners, enabling you to selectively invoke
- * listeners based on their type, allowing for more targeted event handling.
- *
- * @param event the {@linkplain IClassTargetingEvent} to be dispatched
- * @param type the type of listener to invoke (can be {@code null})
- * @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
- * @throws NullPointerException if the given event is {@code null}
- * @throws UnsupportedOperationException if this event bus is {@link #shutdown}
- * @deprecated This method's functionality is now built into {@link #dispatch(Object, Class)}.
- */
- @Deprecated(since = "3.3.0", forRemoval = true)
- @Override
- public boolean dispatchTargeted(IClassTargetingEvent event, Class> type) {
- return dispatch(event, type);
- }
-
- /**
- * Dispatches an event to listeners in order of inverse-priority.
- * E.g., the lowest priority listeners will be invoked before the highest priority listeners.
- *
- * @param event the event to be dispatched
- * @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
- * @throws NullPointerException if the given event is {@code null}
- * @throws UnsupportedOperationException if this event bus is {@link #shutdown}
- * @deprecated This method's functionality is now built into {@link #dispatch(Object)}.
- */
- @Deprecated(since = "3.3.0", forRemoval = true)
- @Override
- public boolean dispatchInverted(Object event) {
- return dispatchInverted(event, null);
- }
-
- /**
- * Dispatches an event to listeners in order of inverse-priority.
- * E.g., the lowest priority listeners will be invoked before the highest priority listeners.
- *
- *
The {@code type} parameter serves as a filtering mechanism for listeners, enabling you to selectively invoke
- * listeners based on their type, allowing for more targeted event handling.
- *
- * @param event the event to be dispatched
- * @param type the type of listener to invoke (can be {@code null})
- * @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
- * @throws NullPointerException if the given event is {@code null}
- * @throws UnsupportedOperationException if this event bus is {@link #shutdown}
- * @deprecated This method's functionality is now built into {@link #dispatch(Object)}.
- */
- @Deprecated(since = "3.3.0", forRemoval = true)
- @Override
- public boolean dispatchInverted(Object event, Class> type) {
- Objects.requireNonNull(event, "Cannot dispatch a null event to event bus " + id + "!");
- if (isShutdown()) {
- throw new UnsupportedOperationException("Dispatcher " + id + " is shutdown!");
- } else {
- taskExecutor.onEvent(event);
-
- dispatchToEachListener(
- event,
- this.listeners.get(event.getClass()),
- listener -> listener.isAcceptableType(type) && IClassTargetingEvent.isListenerTargetedByEvent(listener, event),
- true
- );
-
- if (event instanceof IStatusEvent e) {
- return e.isSuppressed() || e.isTerminated();
- }
- }
- return false;
- }
-
/**
* Schedules a task to be executed.
*
diff --git a/src/main/java/me/tori/wraith/bus/InvertableEventBus.java b/src/main/java/me/tori/wraith/bus/InvertableEventBus.java
deleted file mode 100644
index a49ecbc..0000000
--- a/src/main/java/me/tori/wraith/bus/InvertableEventBus.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2021-2024 7orivorian.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package me.tori.wraith.bus;
-
-import me.tori.wraith.event.status.IStatusEvent;
-
-/**
- * @author 7orivorian
- * @since 3.0.0
- * @deprecated This event bus' functionality is now built into the {@linkplain IEventBus standard event bus}.
- */
-@Deprecated(since = "3.3.0", forRemoval = true)
-public interface InvertableEventBus extends IEventBus {
-
- /**
- * @param event the event to be dispatched
- * @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
- * @see EventBus#dispatchInverted(Object)
- * @deprecated This method's functionality is now handled by {@link #dispatch(Object, boolean)}.
- */
- @Deprecated(since = "3.3.0", forRemoval = true)
- boolean dispatchInverted(Object event);
-
- /**
- * @param event the event to be dispatched
- * @param type the type of listener to invoke (can be {@code null})
- * @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
- * @see EventBus#dispatchInverted(Object, Class)
- * @deprecated This method's functionality is now handled by {@link #dispatch(Object, Class, boolean)}.
- */
- @Deprecated(since = "3.3.0", forRemoval = true)
- boolean dispatchInverted(Object event, Class> type);
-}
\ No newline at end of file
diff --git a/src/main/java/me/tori/wraith/bus/TargetableEventBus.java b/src/main/java/me/tori/wraith/bus/TargetableEventBus.java
deleted file mode 100644
index 6bc6752..0000000
--- a/src/main/java/me/tori/wraith/bus/TargetableEventBus.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2021-2024 7orivorian.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package me.tori.wraith.bus;
-
-import me.tori.wraith.event.status.IStatusEvent;
-import me.tori.wraith.event.targeted.IClassTargetingEvent;
-
-/**
- * @author 7orivorian
- * @since 3.0.0
- * @deprecated This event bus' functionality is now built into the {@linkplain IEventBus standard event bus}.
- */
-@Deprecated(since = "3.3.0", forRemoval = true)
-public interface TargetableEventBus extends IEventBus {
-
- /**
- * @param event the {@linkplain IClassTargetingEvent} to dispatch
- * @return {@code true} if the given event was {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
- * @see EventBus#dispatchTargeted(IClassTargetingEvent)
- * @deprecated This method's functionality is now built into {@link #dispatch(Object)}
- */
- @Deprecated(since = "3.3.0", forRemoval = true)
- boolean dispatchTargeted(IClassTargetingEvent event);
-
- /**
- * @param event the {@linkplain IClassTargetingEvent} to dispatch
- * @param type the type of listener to invoke (can be {@code null})
- * @return {@code true} if the given event was {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
- * @see EventBus#dispatchTargeted(IClassTargetingEvent, Class)
- * @deprecated This method's functionality is now built into {@link #dispatch(Object)}
- */
- @Deprecated(since = "3.3.0", forRemoval = true)
- boolean dispatchTargeted(IClassTargetingEvent event, Class> type);
-}
\ No newline at end of file
diff --git a/src/main/test/me/tori/wraith/targetedevent/TargetedEventTest.java b/src/main/test/me/tori/wraith/targetedevent/TargetedEventTest.java
index b0186d8..e716b2d 100644
--- a/src/main/test/me/tori/wraith/targetedevent/TargetedEventTest.java
+++ b/src/main/test/me/tori/wraith/targetedevent/TargetedEventTest.java
@@ -42,36 +42,51 @@ public void testTargetedEvent() {
bus.subscribe(new Subscriber() {{
registerListeners(
- new MyListener(),
- new OtherListener()
+ new MyListener(0),
+ new OtherListener(1)
);
}});
TestEvent event = new TestEvent(MyListener.class);
- assertFalse(bus.dispatchTargeted(event));
+ assertFalse(bus.dispatch(event));
+ }
+
+ @Test
+ public void testTargetedEvent2() {
+ final EventBus bus = new EventBus();
+
+ bus.subscribe(new Subscriber() {{
+ registerListeners(
+ new MyListener(1),
+ new OtherListener(0)
+ );
+ }});
+
+ TestEvent event = new TestEvent(MyListener.class);
+ assertFalse(bus.dispatch(event));
}
static class MyListener extends EventListener {
- public MyListener() {
- super(TestEvent.class);
+ public MyListener(int priority) {
+ super(TestEvent.class, priority);
}
@Override
public void invoke(TestEvent event) {
-
+ event.setSuppressed(false);
}
}
static class OtherListener extends EventListener {
- public OtherListener() {
- super(TestEvent.class);
+ public OtherListener(int priority) {
+ super(TestEvent.class, priority);
}
@Override
public void invoke(TestEvent event) {
- event.terminate();
+ event.suppress();
}
}
From cef7b656cc3d978ac423d3ffde1a4770d0f34f30 Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Wed, 3 Jul 2024 22:58:44 -0400
Subject: [PATCH 03/30] Add IndexedHashSet
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
.../me/tori/wraith/util/IndexedHashSet.java | 119 ++++++++++++++++++
.../tori/wraith/util/IndexedHashSetTest.java | 90 +++++++++++++
2 files changed, 209 insertions(+)
create mode 100644 src/main/java/me/tori/wraith/util/IndexedHashSet.java
create mode 100644 src/main/test/me/tori/wraith/util/IndexedHashSetTest.java
diff --git a/src/main/java/me/tori/wraith/util/IndexedHashSet.java b/src/main/java/me/tori/wraith/util/IndexedHashSet.java
new file mode 100644
index 0000000..9d8206a
--- /dev/null
+++ b/src/main/java/me/tori/wraith/util/IndexedHashSet.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package me.tori.wraith.util;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.function.Predicate;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class IndexedHashSet {
+
+ private final ArrayList list;
+ private final HashSet set;
+
+ public IndexedHashSet() {
+ this.list = new ArrayList<>();
+ this.set = new HashSet<>();
+ }
+
+ public boolean add(E element) {
+ if (set.add(element)) {
+ list.add(element);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean add(int index, E element) {
+ if (set.add(element)) {
+ list.add(index, element);
+ return true;
+ }
+ return false;
+ }
+
+ public E get(int index) {
+ return list.get(index);
+ }
+
+ public E remove(int index) {
+ E element = list.remove(index);
+ set.remove(element);
+ return element;
+ }
+
+ @SuppressWarnings("SuspiciousMethodCalls")
+ public boolean remove(Object element) {
+ if (set.remove(element)) {
+ list.remove(element);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean removeIf(Predicate super E> filter) {
+ boolean removed = false;
+ Iterator it = list.iterator();
+ while (it.hasNext()) {
+ E element = it.next();
+ if (filter.test(element)) {
+ it.remove();
+ set.remove(element);
+ removed = true;
+ }
+ }
+ return removed;
+ }
+
+ public int size() {
+ return list.size();
+ }
+
+ @SuppressWarnings("SuspiciousMethodCalls")
+ public boolean contains(Object element) {
+ return set.contains(element);
+ }
+
+ public boolean isEmpty() {
+ return list.isEmpty();
+ }
+
+ public ListIterator listIterator(int index) {
+ return list.listIterator(index);
+ }
+
+ public void clear() {
+ list.clear();
+ set.clear();
+ }
+
+ @Override
+ public String toString() {
+ return list.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/main/test/me/tori/wraith/util/IndexedHashSetTest.java b/src/main/test/me/tori/wraith/util/IndexedHashSetTest.java
new file mode 100644
index 0000000..b33e6ae
--- /dev/null
+++ b/src/main/test/me/tori/wraith/util/IndexedHashSetTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package me.tori.wraith.util;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Objects;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class IndexedHashSetTest {
+
+ @Test
+ public void testNoDuplicatesAllowed() {
+ IndexedHashSet set = new IndexedHashSet<>();
+ set.add("A");
+ set.add("A");
+ set.add("B");
+
+ Assertions.assertEquals(2, set.size());
+ }
+
+ @Test
+ public void testInsert() {
+ IndexedHashSet set = new IndexedHashSet<>() {{
+ add("A");
+ add("B");
+ add("C");
+ }};
+ set.add(0, "Z");
+
+ Assertions.assertEquals("Z", set.get(0));
+ Assertions.assertEquals("A", set.get(1));
+ Assertions.assertEquals("B", set.get(2));
+ Assertions.assertEquals("C", set.get(3));
+ Assertions.assertThrows(IndexOutOfBoundsException.class, () -> set.get(4));
+ }
+
+ @Test
+ public void testIndexBounds() {
+ IndexedHashSet set = new IndexedHashSet<>() {{
+ add("A");
+ add("B");
+ add("C");
+ }};
+
+ Assertions.assertThrows(IndexOutOfBoundsException.class, () -> set.get(-1));
+ Assertions.assertThrows(IndexOutOfBoundsException.class, () -> set.get(3));
+ }
+
+ @Test
+ public void testRemoveIf() {
+ IndexedHashSet set = new IndexedHashSet<>() {{
+ add("A");
+ add("B");
+ add("C");
+ add("a");
+ add("b");
+ add("c");
+ }};
+ set.removeIf(s -> Objects.equals(s, s.toUpperCase()));
+
+ Assertions.assertEquals(3, set.size());
+ Assertions.assertEquals("a", set.get(0));
+ Assertions.assertEquals("b", set.get(1));
+ Assertions.assertEquals("c", set.get(2));
+ }
+}
\ No newline at end of file
From 7260ec1ed8305400f7eb8654151b8aff9672563c Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Wed, 3 Jul 2024 23:00:42 -0400
Subject: [PATCH 04/30] Refactor benchmarks
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
.../wraith/benchmarking/BenchmarkMain.java | 37 +++++++++++++++++++
.../tori/wraith/benchmarking/MyBenchmark.java | 6 ---
2 files changed, 37 insertions(+), 6 deletions(-)
create mode 100644 src/main/test/me/tori/wraith/benchmarking/BenchmarkMain.java
diff --git a/src/main/test/me/tori/wraith/benchmarking/BenchmarkMain.java b/src/main/test/me/tori/wraith/benchmarking/BenchmarkMain.java
new file mode 100644
index 0000000..9738e62
--- /dev/null
+++ b/src/main/test/me/tori/wraith/benchmarking/BenchmarkMain.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package me.tori.wraith.benchmarking;
+
+import org.openjdk.jmh.Main;
+
+import java.io.IOException;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class BenchmarkMain {
+
+ public static void main(String[] args) throws IOException {
+ Main.main(args);
+ }
+}
\ No newline at end of file
diff --git a/src/main/test/me/tori/wraith/benchmarking/MyBenchmark.java b/src/main/test/me/tori/wraith/benchmarking/MyBenchmark.java
index b7d3660..ce6c364 100644
--- a/src/main/test/me/tori/wraith/benchmarking/MyBenchmark.java
+++ b/src/main/test/me/tori/wraith/benchmarking/MyBenchmark.java
@@ -24,10 +24,8 @@
import me.tori.wraith.bus.EventBus;
import me.tori.wraith.listener.EventListener;
import me.tori.wraith.subscriber.Subscriber;
-import org.openjdk.jmh.Main;
import org.openjdk.jmh.annotations.*;
-import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
@@ -36,10 +34,6 @@
*/
public class MyBenchmark {
- public static void main(String[] args) throws IOException {
- Main.main(args);
- }
-
@State(Scope.Thread)
public static class BenchmarkState {
MyListener myListener;
From debe40d9cb05c7a93c1aa2fbb7728901aadea3f1 Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Wed, 3 Jul 2024 23:01:34 -0400
Subject: [PATCH 05/30] Fix broken PersistencyTest
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
src/main/test/me/tori/wraith/persistency/PersistencyTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/test/me/tori/wraith/persistency/PersistencyTest.java b/src/main/test/me/tori/wraith/persistency/PersistencyTest.java
index 56bec70..41519bb 100644
--- a/src/main/test/me/tori/wraith/persistency/PersistencyTest.java
+++ b/src/main/test/me/tori/wraith/persistency/PersistencyTest.java
@@ -70,7 +70,7 @@ public MyListener(int persists) {
@Override
public void invoke(MyEvent event) {
- event.terminate();
+ event.suppress();
}
}
From c2f5df054c5d737f6e6bf582147639739afb143f Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Wed, 3 Jul 2024 23:01:51 -0400
Subject: [PATCH 06/30] Reduce the amount of iterations in PersistencyTest
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
src/main/test/me/tori/wraith/persistency/PersistencyTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/test/me/tori/wraith/persistency/PersistencyTest.java b/src/main/test/me/tori/wraith/persistency/PersistencyTest.java
index 41519bb..06c2fb7 100644
--- a/src/main/test/me/tori/wraith/persistency/PersistencyTest.java
+++ b/src/main/test/me/tori/wraith/persistency/PersistencyTest.java
@@ -57,7 +57,7 @@ public void testIndefiniteEvent() {
registerListener(new MyListener(0)); // <= 0 means persist indefinitely
}});
- for (int i = 0; i < 1_000_000; i++) {
+ for (int i = 0; i < 1_000; i++) {
Assertions.assertTrue(bus.dispatch(new MyEvent()));
}
}
From ec1f30ffdd483d8060ddcc957410a84b6df71c01 Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Wed, 3 Jul 2024 23:02:50 -0400
Subject: [PATCH 07/30] Update IEventBus documentation
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
src/main/java/me/tori/wraith/bus/IEventBus.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/main/java/me/tori/wraith/bus/IEventBus.java b/src/main/java/me/tori/wraith/bus/IEventBus.java
index a2167af..041422d 100644
--- a/src/main/java/me/tori/wraith/bus/IEventBus.java
+++ b/src/main/java/me/tori/wraith/bus/IEventBus.java
@@ -27,13 +27,15 @@
import me.tori.wraith.subscriber.ISubscriber;
/**
+ * An event bus that allows for the subscription, registration, and dispatching of events to listeners.
+ *
* @author 7orivorian
* @since 1.0.0
*/
public interface IEventBus {
/**
- * Default priority that used when no other priority is specified
+ * Default priority used when no other priority is specified.
*
* @see EventListener#EventListener(Class)
* @see EventListener#EventListener(Class, Class)
From d0c921cf0d09594cfae9042e7085266fbab31725 Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Wed, 3 Jul 2024 23:04:26 -0400
Subject: [PATCH 08/30] Rearrange EventListener & LambdaEventListener
constructor parameters
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
.../java/me/tori/wraith/listener/EventListener.java | 12 ++++++------
.../me/tori/wraith/listener/LambdaEventListener.java | 4 ++--
src/main/java/me/tori/wraith/listener/Listener.java | 2 ++
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/main/java/me/tori/wraith/listener/EventListener.java b/src/main/java/me/tori/wraith/listener/EventListener.java
index 3b428a4..70992c5 100644
--- a/src/main/java/me/tori/wraith/listener/EventListener.java
+++ b/src/main/java/me/tori/wraith/listener/EventListener.java
@@ -52,7 +52,7 @@ public abstract class EventListener implements Listener {
* @throws NullPointerException if {@code target} is {@code null}.
*/
public EventListener(@NotNull Class super T> target) {
- this(target, IEventBus.DEFAULT_PRIORITY, null);
+ this(target, null, IEventBus.DEFAULT_PRIORITY, DEFAULT_PERSISTENCE);
}
/**
@@ -63,7 +63,7 @@ public EventListener(@NotNull Class super T> target) {
* @throws NullPointerException if {@code target} is {@code null}.
*/
public EventListener(@NotNull Class super T> target, int priority) {
- this(target, priority, null);
+ this(target, null, priority, DEFAULT_PERSISTENCE);
}
/**
@@ -74,7 +74,7 @@ public EventListener(@NotNull Class super T> target, int priority) {
* @throws NullPointerException if {@code target} is {@code null}.
*/
public EventListener(@NotNull Class super T> target, @Nullable Class> type) {
- this(target, IEventBus.DEFAULT_PRIORITY, type);
+ this(target, type, IEventBus.DEFAULT_PRIORITY, DEFAULT_PERSISTENCE);
}
/**
@@ -85,8 +85,8 @@ public EventListener(@NotNull Class super T> target, @Nullable Class> type)
* @param type The type of events that this listener can handle. Can be {@code null}.
* @throws NullPointerException if {@code target} is {@code null}.
*/
- public EventListener(@NotNull Class super T> target, int priority, @Nullable Class> type) {
- this(target, type, priority, 0);
+ public EventListener(@NotNull Class super T> target, @Nullable Class> type, int priority) {
+ this(target, type, priority, DEFAULT_PERSISTENCE);
}
/**
@@ -102,9 +102,9 @@ public EventListener(@NotNull Class super T> target, int priority, @Nullable C
*/
public EventListener(@NotNull Class super T> target, @Nullable Class> type, int priority, int persists) {
Objects.requireNonNull(target);
- this.priority = priority;
this.target = target;
this.type = type;
+ this.priority = priority;
this.persists = persists;
this.indefinitePersistence = persists <= 0;
}
diff --git a/src/main/java/me/tori/wraith/listener/LambdaEventListener.java b/src/main/java/me/tori/wraith/listener/LambdaEventListener.java
index a6b89ee..e344122 100644
--- a/src/main/java/me/tori/wraith/listener/LambdaEventListener.java
+++ b/src/main/java/me/tori/wraith/listener/LambdaEventListener.java
@@ -88,8 +88,8 @@ public LambdaEventListener(@NotNull Class super E> target, @Nullable Class>
* @param invokable The invokable action to be executed when the event is dispatched.
* @throws NullPointerException if {@code target} is {@code null}.
*/
- public LambdaEventListener(@NotNull Class super E> target, int priority, @Nullable Class> type, @NotNull Invokable invokable) {
- super(target, priority, type);
+ public LambdaEventListener(@NotNull Class super E> target, @Nullable Class> type, int priority, @NotNull Invokable invokable) {
+ super(target, type, priority);
Objects.requireNonNull(invokable);
this.invokable = invokable;
}
diff --git a/src/main/java/me/tori/wraith/listener/Listener.java b/src/main/java/me/tori/wraith/listener/Listener.java
index 5cf68d1..c1d5259 100644
--- a/src/main/java/me/tori/wraith/listener/Listener.java
+++ b/src/main/java/me/tori/wraith/listener/Listener.java
@@ -38,6 +38,8 @@
*/
public interface Listener extends Invokable {
+ int DEFAULT_PERSISTENCE = 0;
+
/**
* Gets the priority level of this listener for event handling.
*
From af935878049753355cd5f2aa295572623bbdfdb4 Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Thu, 4 Jul 2024 01:17:25 -0400
Subject: [PATCH 09/30] Rewrote IndexedHashSet
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
.../me/tori/wraith/util/IndexedHashSet.java | 79 +++++++++----------
1 file changed, 39 insertions(+), 40 deletions(-)
diff --git a/src/main/java/me/tori/wraith/util/IndexedHashSet.java b/src/main/java/me/tori/wraith/util/IndexedHashSet.java
index 9d8206a..02b1469 100644
--- a/src/main/java/me/tori/wraith/util/IndexedHashSet.java
+++ b/src/main/java/me/tori/wraith/util/IndexedHashSet.java
@@ -22,98 +22,97 @@
package me.tori.wraith.util;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.Iterator;
-import java.util.ListIterator;
+import java.util.Objects;
import java.util.function.Predicate;
/**
* @author 7orivorian
* @since 4.0.0
*/
-public class IndexedHashSet {
+public class IndexedHashSet extends ArrayList {
- private final ArrayList list;
- private final HashSet set;
+ private final HashMap map;
public IndexedHashSet() {
- this.list = new ArrayList<>();
- this.set = new HashSet<>();
+ this.map = new HashMap<>();
}
+ @Override
public boolean add(E element) {
- if (set.add(element)) {
- list.add(element);
+ Objects.requireNonNull(element);
+ if (map.put(element, true) == null) {
+ super.add(element);
return true;
}
return false;
}
- public boolean add(int index, E element) {
- if (set.add(element)) {
- list.add(index, element);
- return true;
+ @Override
+ public void add(int index, E element) {
+ Objects.requireNonNull(element);
+ rangeCheckForAdd(index);
+ if (map.put(element, true) == null) {
+ super.add(index, element);
}
- return false;
- }
-
- public E get(int index) {
- return list.get(index);
}
+ @Override
public E remove(int index) {
- E element = list.remove(index);
- set.remove(element);
+ E element = super.remove(index);
+ map.remove(element);
return element;
}
- @SuppressWarnings("SuspiciousMethodCalls")
+ @Override
public boolean remove(Object element) {
- if (set.remove(element)) {
- list.remove(element);
+ if (map.remove(element) != null) {
+ super.remove(element);
return true;
}
return false;
}
+ @Override
public boolean removeIf(Predicate super E> filter) {
+ Objects.requireNonNull(filter);
boolean removed = false;
- Iterator it = list.iterator();
+ Iterator it = iterator();
while (it.hasNext()) {
E element = it.next();
if (filter.test(element)) {
it.remove();
- set.remove(element);
+ map.remove(element);
removed = true;
}
}
return removed;
}
- public int size() {
- return list.size();
- }
-
+ @Override
@SuppressWarnings("SuspiciousMethodCalls")
public boolean contains(Object element) {
- return set.contains(element);
+ return map.containsKey(element);
}
- public boolean isEmpty() {
- return list.isEmpty();
+ @Override
+ public void clear() {
+ super.clear();
+ map.clear();
}
- public ListIterator listIterator(int index) {
- return list.listIterator(index);
+ public ArrayList asList() {
+ return new ArrayList<>(this);
}
- public void clear() {
- list.clear();
- set.clear();
+ private void rangeCheckForAdd(int index) {
+ if ((index > size()) || (index < 0)) {
+ throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+ }
}
- @Override
- public String toString() {
- return list.toString();
+ private String outOfBoundsMsg(int index) {
+ return "Index: " + index + ", Size: " + size();
}
}
\ No newline at end of file
From 8cde0b022749e9b12c5707226433dbd1c5dd4bd7 Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Thu, 4 Jul 2024 01:20:29 -0400
Subject: [PATCH 10/30] Minor documentation refactors
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
src/main/java/me/tori/wraith/bus/EventBus.java | 8 ++++----
src/main/java/me/tori/wraith/listener/EventListener.java | 4 ++--
src/main/java/me/tori/wraith/subscriber/ISubscriber.java | 7 ++++---
src/main/java/me/tori/wraith/subscriber/Subscriber.java | 7 ++++---
4 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/main/java/me/tori/wraith/bus/EventBus.java b/src/main/java/me/tori/wraith/bus/EventBus.java
index e22d11d..1b6c107 100644
--- a/src/main/java/me/tori/wraith/bus/EventBus.java
+++ b/src/main/java/me/tori/wraith/bus/EventBus.java
@@ -36,11 +36,11 @@
/**
* Default implementation of {@link IEventBus}.
+ *
Manages event subscription, dispatching, and listener registration.
- *
- * @author 7orivorian
- * @since 1.0.0
+ * @author 7orivorian
+ * @since 1.0.0
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class EventBus implements IEventBus {
diff --git a/src/main/java/me/tori/wraith/listener/EventListener.java b/src/main/java/me/tori/wraith/listener/EventListener.java
index 70992c5..f97555c 100644
--- a/src/main/java/me/tori/wraith/listener/EventListener.java
+++ b/src/main/java/me/tori/wraith/listener/EventListener.java
@@ -32,10 +32,10 @@
* Event listeners provide event handling logic with specified priorities, target classes, and types.
*
* @param The type of event this listener is designed to handle.
- * @author 7orivorian
+ * @author 7orivorian
* @see Listener
* @see Invokable
- * @since 1.0.0
+ * @since 1.0.0
*/
public abstract class EventListener implements Listener {
diff --git a/src/main/java/me/tori/wraith/subscriber/ISubscriber.java b/src/main/java/me/tori/wraith/subscriber/ISubscriber.java
index 1936bd6..fcaf39b 100644
--- a/src/main/java/me/tori/wraith/subscriber/ISubscriber.java
+++ b/src/main/java/me/tori/wraith/subscriber/ISubscriber.java
@@ -27,11 +27,12 @@
/**
* Represents a subscriber that can register and manage event listeners.
- *
An instance of a class implementing this interface can subscribe to an event bus by registering listeners.
+ *
+ * An instance of a class implementing this interface can subscribe to an event bus by registering listeners.
*
- * @author 7orivorian
+ * @author 7orivorian
* @see Subscriber
- * @since 1.0.0
+ * @since 1.0.0
*/
public interface ISubscriber {
diff --git a/src/main/java/me/tori/wraith/subscriber/Subscriber.java b/src/main/java/me/tori/wraith/subscriber/Subscriber.java
index a0faa12..b160461 100644
--- a/src/main/java/me/tori/wraith/subscriber/Subscriber.java
+++ b/src/main/java/me/tori/wraith/subscriber/Subscriber.java
@@ -30,12 +30,13 @@
import java.util.List;
/**
- * A concrete implementation of {@link ISubscriber} that manages event listeners and their registration.
+ * The default implementation of {@link ISubscriber} that manages event listeners and their registration.
+ *
* This class provides methods to register single or multiple event listeners and retrieve registered listeners.
*
- * @author 7orivorian
+ * @author 7orivorian
* @see ISubscriber
- * @since 1.0.0
+ * @since 1.0.0
*/
public class Subscriber implements ISubscriber {
From 62bc8a6894a4864f25d0448a9df88c7db0e669eb Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Thu, 4 Jul 2024 01:20:49 -0400
Subject: [PATCH 11/30] Add PriorityTest
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
.../me/tori/wraith/priority/PriorityTest.java | 73 +++++++++++++++++++
1 file changed, 73 insertions(+)
create mode 100644 src/main/test/me/tori/wraith/priority/PriorityTest.java
diff --git a/src/main/test/me/tori/wraith/priority/PriorityTest.java b/src/main/test/me/tori/wraith/priority/PriorityTest.java
new file mode 100644
index 0000000..6a0b90a
--- /dev/null
+++ b/src/main/test/me/tori/wraith/priority/PriorityTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package me.tori.wraith.priority;
+
+import me.tori.wraith.bus.EventBus;
+import me.tori.wraith.event.status.StatusEvent;
+import me.tori.wraith.listener.LambdaEventListener;
+import me.tori.wraith.subscriber.Subscriber;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class PriorityTest {
+
+ @Test
+ public void testPriority() {
+ final EventBus bus = new EventBus();
+ bus.subscribe(new Subscriber() {{
+ registerListener(new LambdaEventListener<>(MyEvent.class, 5, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener<>(MyEvent.class, 4, event -> {
+ event.setFlag(false);
+ event.terminate();
+ }));
+ registerListener(new LambdaEventListener<>(MyEvent.class, 3, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener<>(MyEvent.class, 2, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener<>(MyEvent.class, 1, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener<>(MyEvent.class, 0, event -> event.setFlag(true)));
+ }});
+
+ MyEvent event = new MyEvent();
+ Assertions.assertTrue(bus.dispatch(event));
+ Assertions.assertFalse(event.flag());
+ }
+
+ static class MyEvent extends StatusEvent {
+
+ private boolean flag;
+
+ MyEvent() {
+ this.flag = true;
+ }
+
+ public boolean flag() {
+ return flag;
+ }
+
+ public void setFlag(boolean flag) {
+ this.flag = flag;
+ }
+ }
+}
\ No newline at end of file
From 4e21120c9c7684280a138098904e00d1d5833324 Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Thu, 4 Jul 2024 01:21:50 -0400
Subject: [PATCH 12/30] Fix incorrect equals & hashCode methods in
EventListener
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
.../tori/wraith/listener/EventListener.java | 21 +++++++------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/src/main/java/me/tori/wraith/listener/EventListener.java b/src/main/java/me/tori/wraith/listener/EventListener.java
index f97555c..9a62c20 100644
--- a/src/main/java/me/tori/wraith/listener/EventListener.java
+++ b/src/main/java/me/tori/wraith/listener/EventListener.java
@@ -177,25 +177,18 @@ public boolean equals(Object o) {
}
EventListener> that = (EventListener>) o;
- if (priority != that.priority) {
- return false;
- }
- if (indefinitePersistence != that.indefinitePersistence) {
- return false;
- }
- if (!Objects.equals(type, that.type)) {
- return false;
- }
- return target.equals(that.target);
+ return (priority == that.priority)
+ && (indefinitePersistence == that.indefinitePersistence)
+ && target.equals(that.target)
+ && Objects.equals(type, that.type);
}
@Override
public int hashCode() {
int result = target.hashCode();
- result = 31 * result + Objects.hashCode(type);
- result = 31 * result + priority;
- result = 31 * result + Boolean.hashCode(indefinitePersistence);
- result = 31 * result + persists;
+ result = (31 * result) + Objects.hashCode(type);
+ result = (31 * result) + priority;
+ result = (31 * result) + Boolean.hashCode(indefinitePersistence);
return result;
}
From 5b6370f4dbd9108a7646a91142ed3e1786ca8f21 Mon Sep 17 00:00:00 2001
From: 7orivorian <7orivorian+github@gmail.com>
Date: Thu, 4 Jul 2024 01:23:48 -0400
Subject: [PATCH 13/30] Subscribers now link to event buses in order to
propagate listener registration
Signed-off-by: 7orivorian <7orivorian+github@gmail.com>
---
.../java/me/tori/wraith/bus/EventBus.java | 89 ++++++++++-------
.../tori/wraith/subscriber/ISubscriber.java | 36 +++++++
.../me/tori/wraith/subscriber/Subscriber.java | 75 ++++++++++++--
.../wraith/registration/RegistrationTest.java | 99 +++++++++++++++++++
4 files changed, 257 insertions(+), 42 deletions(-)
create mode 100644 src/main/test/me/tori/wraith/registration/RegistrationTest.java
diff --git a/src/main/java/me/tori/wraith/bus/EventBus.java b/src/main/java/me/tori/wraith/bus/EventBus.java
index 1b6c107..a54e436 100644
--- a/src/main/java/me/tori/wraith/bus/EventBus.java
+++ b/src/main/java/me/tori/wraith/bus/EventBus.java
@@ -27,12 +27,11 @@
import me.tori.wraith.subscriber.ISubscriber;
import me.tori.wraith.task.ScheduledTask;
import me.tori.wraith.task.TaskExecutor;
+import me.tori.wraith.util.IndexedHashSet;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;
-import java.util.function.Supplier;
/**
* Default implementation of {@link IEventBus}.
@@ -67,7 +66,7 @@ public class EventBus implements IEventBus {
/**
* A {@link ConcurrentHashMap} of this event bus' {@link Listener listeners}
*/
- private final ConcurrentHashMap, List> listeners;
+ private final ConcurrentHashMap, IndexedHashSet> listeners;
/**
* A {@link TaskExecutor} that manages the scheduling and execution of tasks associated with events. It provides
* a mechanism to associate event classes with queues of tasks and ensures their orderly execution when the
@@ -106,15 +105,20 @@ public static int getInstanceCount() {
@Override
public void subscribe(ISubscriber subscriber) {
Objects.requireNonNull(subscriber, "Cannot subscribe null to event bus " + id + "!");
+
+ subscribers.add(subscriber);
+ subscriber.linkToBus(this);
+
Collection> listeners = subscriber.getListeners();
- if (listeners.size() == 1) {
- register(listeners.iterator().next());
- } else {
- for (Listener> listener : listeners) {
- register(listener);
+ if (!listeners.isEmpty()) {
+ if (listeners.size() == 1) {
+ register(listeners.iterator().next());
+ } else {
+ for (Listener> listener : listeners) {
+ register(listener);
+ }
}
}
- subscribers.add(subscriber);
}
/**
@@ -128,15 +132,20 @@ public void subscribe(ISubscriber subscriber) {
@Override
public void unsubscribe(ISubscriber subscriber) {
Objects.requireNonNull(subscriber, "Cannot unsubscribe null from event bus " + id + "!");
+
+ subscribers.remove(subscriber);
+ subscriber.unlinkFromBus(this);
+
Collection> listeners = subscriber.getListeners();
- if (listeners.size() == 1) {
- unregister(listeners.iterator().next());
- } else {
- for (Listener> listener : listeners) {
- unregister(listener);
+ if (!listeners.isEmpty()) {
+ if (listeners.size() == 1) {
+ unregister(listeners.iterator().next());
+ } else {
+ for (Listener> listener : listeners) {
+ unregister(listener);
+ }
}
}
- subscribers.remove(subscriber);
}
/**
@@ -149,7 +158,7 @@ public void unsubscribe(ISubscriber subscriber) {
public void register(Listener> listener) {
Objects.requireNonNull(listener, "Cannot register null listener to event bus " + id + "!");
- List listeners = this.listeners.computeIfAbsent(listener.getTarget(), target -> new CopyOnWriteArrayList<>());
+ IndexedHashSet listeners = this.listeners.computeIfAbsent(listener.getTarget(), target -> new IndexedHashSet<>());
final int size = listeners.size();
int index = 0;
for (; index < size; index++) {
@@ -307,28 +316,36 @@ public int getId() {
* they are processed in normal order
* @since 3.2.0
*/
- private void dispatchToEachListener(Object event, List listeners, Predicate predicate, boolean invertPriority) {
- if (listeners != null && !listeners.isEmpty()) {
- ListIterator iterator;
- Supplier supplier;
+ @SuppressWarnings("DuplicatedCode")
+ private void dispatchToEachListener(Object event, IndexedHashSet listeners, Predicate predicate, boolean invertPriority) {
+ if ((listeners != null) && !listeners.isEmpty()) {
+ final ArrayList li = listeners.asList();
if (invertPriority) {
- iterator = listeners.listIterator(listeners.size());
- supplier = () -> (iterator.hasPrevious() ? iterator.previous() : null);
- } else {
- iterator = listeners.listIterator(0);
- supplier = () -> (iterator.hasNext() ? iterator.next() : null);
- }
- Listener listener;
- while ((listener = supplier.get()) != null) {
- if (!predicate.test(listener)) {
- continue;
+ for (int i = li.size() - 1; i >= 0; i--) {
+ Listener listener = li.get(i);
+ if (!predicate.test(listener)) {
+ continue;
+ }
+ listener.invoke(event);
+ if ((event instanceof IStatusEvent e) && e.isTerminated()) {
+ break;
+ }
+ if (!listener.shouldPersist()) {
+ listeners.remove(listener);
+ }
}
- listener.invoke(event);
- if ((event instanceof IStatusEvent e) && e.isTerminated()) {
- break;
- }
- if (!listener.shouldPersist()) {
- listeners.remove(listener);
+ } else {
+ for (Listener listener : li) {
+ if (!predicate.test(listener)) {
+ continue;
+ }
+ listener.invoke(event);
+ if ((event instanceof IStatusEvent e) && e.isTerminated()) {
+ break;
+ }
+ if (!listener.shouldPersist()) {
+ listeners.remove(listener);
+ }
}
}
}
diff --git a/src/main/java/me/tori/wraith/subscriber/ISubscriber.java b/src/main/java/me/tori/wraith/subscriber/ISubscriber.java
index fcaf39b..29638be 100644
--- a/src/main/java/me/tori/wraith/subscriber/ISubscriber.java
+++ b/src/main/java/me/tori/wraith/subscriber/ISubscriber.java
@@ -21,6 +21,7 @@
package me.tori.wraith.subscriber;
+import me.tori.wraith.bus.IEventBus;
import me.tori.wraith.listener.Listener;
import java.util.Collection;
@@ -55,10 +56,45 @@ public interface ISubscriber {
@SuppressWarnings("unchecked")
> T[] registerListeners(T... listeners);
+ /**
+ * Unregisters a single event listener from this subscriber.
+ *
+ * @param listener The event listener to unregister.
+ * @param The type of the listener.
+ * @return {@code true} if this subscriber contained the specified listener, {@code false} otherwise.
+ */
+ > boolean unregisterListener(T listener);
+
+ /**
+ * Unregisters multiple event listeners from this subscriber.
+ *
+ * @param listeners The event listeners to unregister.
+ * @param The type of the listeners.
+ * @return {@code true} if this subscriber was changed as a result of the call, {@code false} otherwise.
+ */
+ @SuppressWarnings("unchecked")
+ > boolean unregisterListeners(T... listeners);
+
/**
* Retrieves a collection of event listeners registered with this subscriber.
*
* @return A collection of registered event listeners.
*/
Collection> getListeners();
+
+ /**
+ * Links this subscriber to the specified event bus.
+ *
+ * @param eventBus The event bus to link to this subscriber. Must not be {@code null}.
+ * @throws NullPointerException If the {@code eventBus} is {@code null}.
+ */
+ void linkToBus(IEventBus eventBus);
+
+ /**
+ * Unlinks this subscriber from the specified event bus.
+ *
+ * @param eventBus The event bus to unlink from this subscriber. Must not be {@code null}.
+ * @throws NullPointerException If the {@code eventBus} is {@code null}.
+ */
+ void unlinkFromBus(IEventBus eventBus);
}
\ No newline at end of file
diff --git a/src/main/java/me/tori/wraith/subscriber/Subscriber.java b/src/main/java/me/tori/wraith/subscriber/Subscriber.java
index b160461..ce9f0c8 100644
--- a/src/main/java/me/tori/wraith/subscriber/Subscriber.java
+++ b/src/main/java/me/tori/wraith/subscriber/Subscriber.java
@@ -21,13 +21,12 @@
package me.tori.wraith.subscriber;
+import me.tori.wraith.bus.IEventBus;
import me.tori.wraith.listener.Listener;
import org.jetbrains.annotations.NotNull;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
/**
* The default implementation of {@link ISubscriber} that manages event listeners and their registration.
@@ -40,6 +39,7 @@
*/
public class Subscriber implements ISubscriber {
+ private final Set<@NotNull IEventBus> linkedBuses = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final List<@NotNull Listener>> listeners = new ArrayList<>();
/**
@@ -52,6 +52,9 @@ public class Subscriber implements ISubscriber {
@Override
public > T registerListener(@NotNull T listener) {
listeners.add(listener);
+ if (!linkedBuses.isEmpty()) {
+ linkedBuses.forEach(bus -> bus.register(listener));
+ }
return listener;
}
@@ -65,10 +68,39 @@ public > T registerListener(@NotNull T listener) {
@SafeVarargs
@Override
public final > T[] registerListeners(@NotNull T... listeners) {
- this.listeners.addAll(Arrays.asList(listeners));
+ final List<@NotNull T> list = Arrays.asList(listeners);
+ this.listeners.addAll(list);
+ if (!linkedBuses.isEmpty()) {
+ linkedBuses.forEach(bus -> list.forEach(bus::register));
+ }
return listeners;
}
+ /**
+ * Unregisters a single event listener from this subscriber.
+ *
+ * @param listener The event listener to unregister.
+ * @param The type of the listener.
+ * @return {@code true} if this subscriber contained the specified listener, {@code false} otherwise.
+ */
+ @Override
+ public > boolean unregisterListener(T listener) {
+ return listeners.remove(listener);
+ }
+
+ /**
+ * Unregisters multiple event listeners from this subscriber.
+ *
+ * @param listeners The event listeners to unregister.
+ * @param The type of the listeners.
+ * @return {@code true} if this subscriber was changed as a result of the call, {@code false} otherwise.
+ */
+ @SafeVarargs
+ @Override
+ public final > boolean unregisterListeners(T... listeners) {
+ return this.listeners.removeAll(Arrays.asList(listeners));
+ }
+
/**
* Retrieves a collection of event listeners registered with this subscriber.
*
@@ -79,10 +111,41 @@ public Collection> getListeners() {
return listeners;
}
+ /**
+ * Links this subscriber to the specified event bus.
+ *
+ * This method adds the given {@code eventBus} to the {@linkplain #linkedBuses set of event buses that this subscriber is linked to}.
+ * Once linked, the event bus can register the event listeners managed by this subscriber.
+ *
+ * @param eventBus The event bus to link to this subscriber. Must not be {@code null}.
+ * @throws NullPointerException If the {@code eventBus} is {@code null}.
+ */
+ @Override
+ public void linkToBus(IEventBus eventBus) {
+ Objects.requireNonNull(eventBus, "Cannot subscribe to a null event bus");
+ linkedBuses.add(eventBus);
+ }
+
+ /**
+ * Unlinks this subscriber from the specified event bus.
+ *
+ * This method removes the given {@code eventBus} from the {@linkplain #linkedBuses set of event buses that this subscriber is linked to}.
+ * Once unlinked, the event bus will no longer register the event listeners managed by this subscriber.
+ *
+ * @param eventBus The event bus to unlink from this subscriber. Must not be {@code null}.
+ * @throws NullPointerException If the {@code eventBus} is {@code null}.
+ */
+ @Override
+ public void unlinkFromBus(IEventBus eventBus) {
+ Objects.requireNonNull(eventBus, "Cannot unsubscribe from a null event bus");
+ linkedBuses.remove(eventBus);
+ }
+
@Override
public String toString() {
return "Subscriber{" +
- "listeners=" + listeners +
+ "busRefs=" + linkedBuses +
+ ", listeners=" + listeners +
'}';
}
}
\ No newline at end of file
diff --git a/src/main/test/me/tori/wraith/registration/RegistrationTest.java b/src/main/test/me/tori/wraith/registration/RegistrationTest.java
new file mode 100644
index 0000000..7afa6bf
--- /dev/null
+++ b/src/main/test/me/tori/wraith/registration/RegistrationTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package me.tori.wraith.registration;
+
+import me.tori.wraith.bus.EventBus;
+import me.tori.wraith.event.status.IStatusEvent;
+import me.tori.wraith.event.status.StatusEvent;
+import me.tori.wraith.listener.LambdaEventListener;
+import me.tori.wraith.subscriber.Subscriber;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class RegistrationTest {
+
+ @Test
+ public void testResistration() {
+ final EventBus bus = new EventBus();
+ final LambdaEventListener listener = new LambdaEventListener<>(
+ StatusEvent.class,
+ IStatusEvent::terminate
+ );
+
+ bus.register(listener);
+ Assertions.assertTrue(bus.dispatch(new StatusEvent()));
+
+ bus.unregister(listener);
+ Assertions.assertFalse(bus.dispatch(new StatusEvent()));
+ }
+
+ @Test
+ public void testSubscription() {
+ final EventBus bus = new EventBus();
+ final Subscriber subscriber = new Subscriber() {{
+ registerListener(new LambdaEventListener<>(StatusEvent.class, IStatusEvent::terminate));
+ }};
+
+ bus.subscribe(subscriber);
+ Assertions.assertTrue(bus.dispatch(new StatusEvent()));
+
+ bus.unsubscribe(subscriber);
+ Assertions.assertFalse(bus.dispatch(new StatusEvent()));
+ }
+
+ @Test
+ public void testLateSubscription() {
+ final String expectedMessage = "Hello world!";
+
+ final EventBus bus = new EventBus();
+ final Subscriber subscriber = new Subscriber();
+
+ bus.subscribe(subscriber);
+
+ subscriber.registerListener(new LambdaEventListener<>(MyEvent.class, event -> event.setMessage(expectedMessage)));
+
+ MyEvent event = new MyEvent(null);
+ bus.dispatch(event);
+
+ Assertions.assertEquals(expectedMessage, event.message());
+ }
+
+ static final class MyEvent {
+ private String message;
+
+ MyEvent(String message) {
+ this.message = message;
+ }
+
+ public String message() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ }
+}
\ No newline at end of file
From 00f6f8250045b8d256a397d05e65e048db37cccf Mon Sep 17 00:00:00 2001
From: Tori <7orivorian+github@gmail.com>
Date: Mon, 29 Jul 2024 02:38:11 -0400
Subject: [PATCH 14/30] Refactor path
Signed-off-by: Tori <7orivorian+github@gmail.com>
---
README.md | 4 +-
.../tori/example/expanded/ExampleEvent.java | 8 +-
.../example/expanded/ExampleListener.java | 6 +-
.../tori/example/expanded/ExampleMain.java | 8 +-
.../example/expanded/ExampleSubscriber.java | 8 +-
.../persistence/PersistenceExample.java | 10 +-
.../tori/example/simple/SimpleExample.java | 10 +-
.../statusevents/SupressionExample.java | 12 +-
.../statusevents/TerminationExample.java | 12 +-
.../taskexecutor/TaskExecutorExample.java | 8 +-
pom.xml | 12 +-
.../{me => dev}/tori/wraith/bus/EventBus.java | 21 ++--
.../tori/wraith/bus/IEventBus.java | 10 +-
.../tori/wraith/event/staged/EventStage.java | 2 +-
.../wraith/event/staged/IStagedEvent.java | 2 +-
.../tori/wraith/event/staged/StagedEvent.java | 4 +-
.../wraith/event/status/IStatusEvent.java | 7 +-
.../tori/wraith/event/status/StatusEvent.java | 2 +-
.../event/targeted/ClassTargetingEvent.java | 9 +-
.../event/targeted/IClassTargetingEvent.java | 9 +-
.../tori/wraith/listener/EventListener.java | 4 +-
.../tori/wraith/listener/Invokable.java | 2 +-
.../wraith/listener/LambdaEventListener.java | 2 +-
.../tori/wraith/listener/Listener.java | 4 +-
.../tori/wraith/listener/ListenerBuilder.java | 4 +-
.../tori/wraith/subscriber/ISubscriber.java | 6 +-
.../tori/wraith/subscriber/Subscriber.java | 6 +-
.../tori/wraith/task/ScheduledTask.java | 2 +-
.../tori/wraith/task/TaskExecutor.java | 2 +-
.../tori/wraith/util/IndexedHashSet.java | 2 +-
src/main/test/dev/tori/wraith/Main.java | 70 ++++++++++++
.../wraith/benchmarking/BenchmarkMain.java | 2 +-
.../tori/wraith/benchmarking/MyBenchmark.java | 8 +-
.../wraith/persistency/PersistencyTest.java | 10 +-
.../tori/wraith/priority/PriorityTest.java | 10 +-
.../wraith/registration/RegistrationTest.java | 12 +-
.../wraith/statusevent/StatusEventTest.java | 10 +-
.../targetedevent/TargetedEventTest.java | 107 ++++++++++++++++--
.../wraith/taskexecutor/TaskExecutorTest.java | 6 +-
.../tori/wraith/util/IndexedHashSetTest.java | 3 +-
40 files changed, 304 insertions(+), 132 deletions(-)
rename examples/java/{me => dev}/tori/example/expanded/ExampleEvent.java (90%)
rename examples/java/{me => dev}/tori/example/expanded/ExampleListener.java (92%)
rename examples/java/{me => dev}/tori/example/expanded/ExampleMain.java (92%)
rename examples/java/{me => dev}/tori/example/expanded/ExampleSubscriber.java (90%)
rename examples/java/{me => dev}/tori/example/persistence/PersistenceExample.java (91%)
rename examples/java/{me => dev}/tori/example/simple/SimpleExample.java (91%)
rename examples/java/{me => dev}/tori/example/statusevents/SupressionExample.java (90%)
rename examples/java/{me => dev}/tori/example/statusevents/TerminationExample.java (89%)
rename examples/java/{me => dev}/tori/example/taskexecutor/TaskExecutorExample.java (93%)
rename src/main/java/{me => dev}/tori/wraith/bus/EventBus.java (95%)
rename src/main/java/{me => dev}/tori/wraith/bus/IEventBus.java (95%)
rename src/main/java/{me => dev}/tori/wraith/event/staged/EventStage.java (97%)
rename src/main/java/{me => dev}/tori/wraith/event/staged/IStagedEvent.java (97%)
rename src/main/java/{me => dev}/tori/wraith/event/staged/StagedEvent.java (97%)
rename src/main/java/{me => dev}/tori/wraith/event/status/IStatusEvent.java (96%)
rename src/main/java/{me => dev}/tori/wraith/event/status/StatusEvent.java (98%)
rename src/main/java/{me => dev}/tori/wraith/event/targeted/ClassTargetingEvent.java (89%)
rename src/main/java/{me => dev}/tori/wraith/event/targeted/IClassTargetingEvent.java (91%)
rename src/main/java/{me => dev}/tori/wraith/listener/EventListener.java (99%)
rename src/main/java/{me => dev}/tori/wraith/listener/Invokable.java (98%)
rename src/main/java/{me => dev}/tori/wraith/listener/LambdaEventListener.java (99%)
rename src/main/java/{me => dev}/tori/wraith/listener/Listener.java (98%)
rename src/main/java/{me => dev}/tori/wraith/listener/ListenerBuilder.java (98%)
rename src/main/java/{me => dev}/tori/wraith/subscriber/ISubscriber.java (96%)
rename src/main/java/{me => dev}/tori/wraith/subscriber/Subscriber.java (98%)
rename src/main/java/{me => dev}/tori/wraith/task/ScheduledTask.java (99%)
rename src/main/java/{me => dev}/tori/wraith/task/TaskExecutor.java (99%)
rename src/main/java/{me => dev}/tori/wraith/util/IndexedHashSet.java (99%)
create mode 100644 src/main/test/dev/tori/wraith/Main.java
rename src/main/test/{me => dev}/tori/wraith/benchmarking/BenchmarkMain.java (97%)
rename src/main/test/{me => dev}/tori/wraith/benchmarking/MyBenchmark.java (94%)
rename src/main/test/{me => dev}/tori/wraith/persistency/PersistencyTest.java (91%)
rename src/main/test/{me => dev}/tori/wraith/priority/PriorityTest.java (92%)
rename src/main/test/{me => dev}/tori/wraith/registration/RegistrationTest.java (91%)
rename src/main/test/{me => dev}/tori/wraith/statusevent/StatusEventTest.java (92%)
rename src/main/test/{me => dev}/tori/wraith/targetedevent/TargetedEventTest.java (51%)
rename src/main/test/{me => dev}/tori/wraith/taskexecutor/TaskExecutorTest.java (96%)
rename src/main/test/{me => dev}/tori/wraith/util/IndexedHashSetTest.java (97%)
diff --git a/README.md b/README.md
index a7c8365..aa5030f 100644
--- a/README.md
+++ b/README.md
@@ -204,8 +204,6 @@ public class ExampleSubscriber extends Subscriber {
To dispatch an event, call one of the `dispatch` methods defined in `EventBus`, passing your event as a parameter:
```java
-import me.tori.wraith.event.staged.EventStage;
-
public class Example {
private static final IEventBus EVENT_BUS = new EventBus();
@@ -223,7 +221,7 @@ public class Example {
-Please explore the [example folder](./examples/java/me/tori/example) for _even more_ Wraith implementations!
+Please explore the [example folder](./examples/java/dev/tori/example) for _even more_ Wraith implementations!
# Contributing
diff --git a/examples/java/me/tori/example/expanded/ExampleEvent.java b/examples/java/dev/tori/example/expanded/ExampleEvent.java
similarity index 90%
rename from examples/java/me/tori/example/expanded/ExampleEvent.java
rename to examples/java/dev/tori/example/expanded/ExampleEvent.java
index 3b1a423..720637c 100644
--- a/examples/java/me/tori/example/expanded/ExampleEvent.java
+++ b/examples/java/dev/tori/example/expanded/ExampleEvent.java
@@ -19,11 +19,11 @@
* THE SOFTWARE.
*/
-package me.tori.example.expanded;
+package dev.tori.example.expanded;
-import me.tori.wraith.event.staged.EventStage;
-import me.tori.wraith.event.staged.IStagedEvent;
-import me.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.event.staged.EventStage;
+import dev.tori.wraith.event.staged.IStagedEvent;
+import dev.tori.wraith.event.status.StatusEvent;
/**
* Example event.
diff --git a/examples/java/me/tori/example/expanded/ExampleListener.java b/examples/java/dev/tori/example/expanded/ExampleListener.java
similarity index 92%
rename from examples/java/me/tori/example/expanded/ExampleListener.java
rename to examples/java/dev/tori/example/expanded/ExampleListener.java
index 7d0ebaf..327b2a1 100644
--- a/examples/java/me/tori/example/expanded/ExampleListener.java
+++ b/examples/java/dev/tori/example/expanded/ExampleListener.java
@@ -19,10 +19,10 @@
* THE SOFTWARE.
*/
-package me.tori.example.expanded;
+package dev.tori.example.expanded;
-import me.tori.wraith.event.staged.EventStage;
-import me.tori.wraith.listener.EventListener;
+import dev.tori.wraith.event.staged.EventStage;
+import dev.tori.wraith.listener.EventListener;
/**
* Example listener.
diff --git a/examples/java/me/tori/example/expanded/ExampleMain.java b/examples/java/dev/tori/example/expanded/ExampleMain.java
similarity index 92%
rename from examples/java/me/tori/example/expanded/ExampleMain.java
rename to examples/java/dev/tori/example/expanded/ExampleMain.java
index 25b663f..757d124 100644
--- a/examples/java/me/tori/example/expanded/ExampleMain.java
+++ b/examples/java/dev/tori/example/expanded/ExampleMain.java
@@ -19,11 +19,11 @@
* THE SOFTWARE.
*/
-package me.tori.example.expanded;
+package dev.tori.example.expanded;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.bus.IEventBus;
-import me.tori.wraith.event.staged.EventStage;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.event.staged.EventStage;
/**
* Example program.
diff --git a/examples/java/me/tori/example/expanded/ExampleSubscriber.java b/examples/java/dev/tori/example/expanded/ExampleSubscriber.java
similarity index 90%
rename from examples/java/me/tori/example/expanded/ExampleSubscriber.java
rename to examples/java/dev/tori/example/expanded/ExampleSubscriber.java
index f3cf156..4e3c8de 100644
--- a/examples/java/me/tori/example/expanded/ExampleSubscriber.java
+++ b/examples/java/dev/tori/example/expanded/ExampleSubscriber.java
@@ -19,11 +19,11 @@
* THE SOFTWARE.
*/
-package me.tori.example.expanded;
+package dev.tori.example.expanded;
-import me.tori.wraith.event.staged.EventStage;
-import me.tori.wraith.listener.LambdaEventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.event.staged.EventStage;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
/**
* Example subscriber.
diff --git a/examples/java/me/tori/example/persistence/PersistenceExample.java b/examples/java/dev/tori/example/persistence/PersistenceExample.java
similarity index 91%
rename from examples/java/me/tori/example/persistence/PersistenceExample.java
rename to examples/java/dev/tori/example/persistence/PersistenceExample.java
index b6cbc6f..cb194c5 100644
--- a/examples/java/me/tori/example/persistence/PersistenceExample.java
+++ b/examples/java/dev/tori/example/persistence/PersistenceExample.java
@@ -19,12 +19,12 @@
* THE SOFTWARE.
*/
-package me.tori.example.persistence;
+package dev.tori.example.persistence;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.bus.IEventBus;
-import me.tori.wraith.listener.LambdaEventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
/**
* A simple example of listener persistence.
diff --git a/examples/java/me/tori/example/simple/SimpleExample.java b/examples/java/dev/tori/example/simple/SimpleExample.java
similarity index 91%
rename from examples/java/me/tori/example/simple/SimpleExample.java
rename to examples/java/dev/tori/example/simple/SimpleExample.java
index 3d6fdfa..a887f4e 100644
--- a/examples/java/me/tori/example/simple/SimpleExample.java
+++ b/examples/java/dev/tori/example/simple/SimpleExample.java
@@ -19,12 +19,12 @@
* THE SOFTWARE.
*/
-package me.tori.example.simple;
+package dev.tori.example.simple;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.event.status.StatusEvent;
-import me.tori.wraith.listener.LambdaEventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
/**
* One-class example.
diff --git a/examples/java/me/tori/example/statusevents/SupressionExample.java b/examples/java/dev/tori/example/statusevents/SupressionExample.java
similarity index 90%
rename from examples/java/me/tori/example/statusevents/SupressionExample.java
rename to examples/java/dev/tori/example/statusevents/SupressionExample.java
index f62abf0..1ec766d 100644
--- a/examples/java/me/tori/example/statusevents/SupressionExample.java
+++ b/examples/java/dev/tori/example/statusevents/SupressionExample.java
@@ -19,13 +19,13 @@
* THE SOFTWARE.
*/
-package me.tori.example.statusevents;
+package dev.tori.example.statusevents;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.bus.IEventBus;
-import me.tori.wraith.event.status.StatusEvent;
-import me.tori.wraith.listener.LambdaEventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
/**
* @author 7orivorian
diff --git a/examples/java/me/tori/example/statusevents/TerminationExample.java b/examples/java/dev/tori/example/statusevents/TerminationExample.java
similarity index 89%
rename from examples/java/me/tori/example/statusevents/TerminationExample.java
rename to examples/java/dev/tori/example/statusevents/TerminationExample.java
index 5a2a4f1..64fe8e5 100644
--- a/examples/java/me/tori/example/statusevents/TerminationExample.java
+++ b/examples/java/dev/tori/example/statusevents/TerminationExample.java
@@ -19,13 +19,13 @@
* THE SOFTWARE.
*/
-package me.tori.example.statusevents;
+package dev.tori.example.statusevents;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.bus.IEventBus;
-import me.tori.wraith.event.status.StatusEvent;
-import me.tori.wraith.listener.LambdaEventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
/**
* @author 7orivorian
diff --git a/examples/java/me/tori/example/taskexecutor/TaskExecutorExample.java b/examples/java/dev/tori/example/taskexecutor/TaskExecutorExample.java
similarity index 93%
rename from examples/java/me/tori/example/taskexecutor/TaskExecutorExample.java
rename to examples/java/dev/tori/example/taskexecutor/TaskExecutorExample.java
index f94777c..435f040 100644
--- a/examples/java/me/tori/example/taskexecutor/TaskExecutorExample.java
+++ b/examples/java/dev/tori/example/taskexecutor/TaskExecutorExample.java
@@ -19,11 +19,11 @@
* THE SOFTWARE.
*/
-package me.tori.example.taskexecutor;
+package dev.tori.example.taskexecutor;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.task.ScheduledTask;
-import me.tori.wraith.task.TaskExecutor;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.task.ScheduledTask;
+import dev.tori.wraith.task.TaskExecutor;
/**
* A simple example showing how to use the {@link TaskExecutor}
diff --git a/pom.xml b/pom.xml
index 8bafb7e..792c511 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
Java event libraryhttps://github.com/7orivorian/Wraith
- me.tori
+ dev.toriWraithjar4.0.0
@@ -22,7 +22,7 @@
7orivorian
- Tori Vii
+ Torihttps://7ori.dev
@@ -60,6 +60,14 @@
UTF-8
+
+
+ github
+ GitHub 7orivorian Apache Maven Packages
+ https://maven.pkg.github.com/7orivorian/Wraith
+
+
+
diff --git a/src/main/java/me/tori/wraith/bus/EventBus.java b/src/main/java/dev/tori/wraith/bus/EventBus.java
similarity index 95%
rename from src/main/java/me/tori/wraith/bus/EventBus.java
rename to src/main/java/dev/tori/wraith/bus/EventBus.java
index a54e436..b3bbd62 100644
--- a/src/main/java/me/tori/wraith/bus/EventBus.java
+++ b/src/main/java/dev/tori/wraith/bus/EventBus.java
@@ -19,15 +19,15 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.bus;
+package dev.tori.wraith.bus;
-import me.tori.wraith.event.status.IStatusEvent;
-import me.tori.wraith.event.targeted.IClassTargetingEvent;
-import me.tori.wraith.listener.Listener;
-import me.tori.wraith.subscriber.ISubscriber;
-import me.tori.wraith.task.ScheduledTask;
-import me.tori.wraith.task.TaskExecutor;
-import me.tori.wraith.util.IndexedHashSet;
+import dev.tori.wraith.event.status.IStatusEvent;
+import dev.tori.wraith.event.targeted.IClassTargetingEvent;
+import dev.tori.wraith.listener.Listener;
+import dev.tori.wraith.subscriber.ISubscriber;
+import dev.tori.wraith.task.ScheduledTask;
+import dev.tori.wraith.task.TaskExecutor;
+import dev.tori.wraith.util.IndexedHashSet;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@@ -223,8 +223,9 @@ public boolean dispatch(Object event, boolean invertPriority) {
* The {@code type} parameter serves as a filtering mechanism for listeners, enabling you to selectively invoke
* listeners based on their type, allowing for more targeted event handling.
*
- * @param event the event to be dispatched
- * @param type the type of listener to invoke (can be {@code null})
+ * @param event the event to be dispatched
+ * @param type the type of listener to invoke (can be {@code null})
+ * @param invertPriority flag to dispatch the event in inverse listener priority
* @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
* {@code false} otherwise
* @throws NullPointerException if the given event is {@code null}
diff --git a/src/main/java/me/tori/wraith/bus/IEventBus.java b/src/main/java/dev/tori/wraith/bus/IEventBus.java
similarity index 95%
rename from src/main/java/me/tori/wraith/bus/IEventBus.java
rename to src/main/java/dev/tori/wraith/bus/IEventBus.java
index 041422d..c34e6e4 100644
--- a/src/main/java/me/tori/wraith/bus/IEventBus.java
+++ b/src/main/java/dev/tori/wraith/bus/IEventBus.java
@@ -19,12 +19,12 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.bus;
+package dev.tori.wraith.bus;
-import me.tori.wraith.event.status.IStatusEvent;
-import me.tori.wraith.listener.EventListener;
-import me.tori.wraith.listener.Listener;
-import me.tori.wraith.subscriber.ISubscriber;
+import dev.tori.wraith.subscriber.ISubscriber;
+import dev.tori.wraith.event.status.IStatusEvent;
+import dev.tori.wraith.listener.EventListener;
+import dev.tori.wraith.listener.Listener;
/**
* An event bus that allows for the subscription, registration, and dispatching of events to listeners.
diff --git a/src/main/java/me/tori/wraith/event/staged/EventStage.java b/src/main/java/dev/tori/wraith/event/staged/EventStage.java
similarity index 97%
rename from src/main/java/me/tori/wraith/event/staged/EventStage.java
rename to src/main/java/dev/tori/wraith/event/staged/EventStage.java
index 10cbdda..b9f76a9 100644
--- a/src/main/java/me/tori/wraith/event/staged/EventStage.java
+++ b/src/main/java/dev/tori/wraith/event/staged/EventStage.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.event.staged;
+package dev.tori.wraith.event.staged;
/**
* Represents the possible stages at which an event can occur.
diff --git a/src/main/java/me/tori/wraith/event/staged/IStagedEvent.java b/src/main/java/dev/tori/wraith/event/staged/IStagedEvent.java
similarity index 97%
rename from src/main/java/me/tori/wraith/event/staged/IStagedEvent.java
rename to src/main/java/dev/tori/wraith/event/staged/IStagedEvent.java
index 870843e..9462cb3 100644
--- a/src/main/java/me/tori/wraith/event/staged/IStagedEvent.java
+++ b/src/main/java/dev/tori/wraith/event/staged/IStagedEvent.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.event.staged;
+package dev.tori.wraith.event.staged;
/**
* An interface representing a staged event, indicating the stage at which the event is occurring.
diff --git a/src/main/java/me/tori/wraith/event/staged/StagedEvent.java b/src/main/java/dev/tori/wraith/event/staged/StagedEvent.java
similarity index 97%
rename from src/main/java/me/tori/wraith/event/staged/StagedEvent.java
rename to src/main/java/dev/tori/wraith/event/staged/StagedEvent.java
index bc332a4..111a5d4 100644
--- a/src/main/java/me/tori/wraith/event/staged/StagedEvent.java
+++ b/src/main/java/dev/tori/wraith/event/staged/StagedEvent.java
@@ -19,12 +19,10 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.event.staged;
+package dev.tori.wraith.event.staged;
import org.jetbrains.annotations.NotNull;
-import java.util.Objects;
-
/**
* Represents a staged event implementation that specifies the stage at which the event occurs.
*
diff --git a/src/main/java/me/tori/wraith/event/status/IStatusEvent.java b/src/main/java/dev/tori/wraith/event/status/IStatusEvent.java
similarity index 96%
rename from src/main/java/me/tori/wraith/event/status/IStatusEvent.java
rename to src/main/java/dev/tori/wraith/event/status/IStatusEvent.java
index 5d17741..d1a6282 100644
--- a/src/main/java/me/tori/wraith/event/status/IStatusEvent.java
+++ b/src/main/java/dev/tori/wraith/event/status/IStatusEvent.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.event.status;
+package dev.tori.wraith.event.status;
import org.jetbrains.annotations.NotNull;
@@ -45,8 +45,13 @@ public interface IStatusEvent {
/**
* Sets the status of this event.
+ *
+ * Note:
+ * This method should not be called directly.
*
* @param status the new {@link EventStatus} to set.
+ * @see #suppress()
+ * @see #terminate()
*/
void setEventStatus(@NotNull EventStatus status);
diff --git a/src/main/java/me/tori/wraith/event/status/StatusEvent.java b/src/main/java/dev/tori/wraith/event/status/StatusEvent.java
similarity index 98%
rename from src/main/java/me/tori/wraith/event/status/StatusEvent.java
rename to src/main/java/dev/tori/wraith/event/status/StatusEvent.java
index 86ff702..f0a3292 100644
--- a/src/main/java/me/tori/wraith/event/status/StatusEvent.java
+++ b/src/main/java/dev/tori/wraith/event/status/StatusEvent.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.event.status;
+package dev.tori.wraith.event.status;
import org.jetbrains.annotations.NotNull;
diff --git a/src/main/java/me/tori/wraith/event/targeted/ClassTargetingEvent.java b/src/main/java/dev/tori/wraith/event/targeted/ClassTargetingEvent.java
similarity index 89%
rename from src/main/java/me/tori/wraith/event/targeted/ClassTargetingEvent.java
rename to src/main/java/dev/tori/wraith/event/targeted/ClassTargetingEvent.java
index bff8530..4d16c3c 100644
--- a/src/main/java/me/tori/wraith/event/targeted/ClassTargetingEvent.java
+++ b/src/main/java/dev/tori/wraith/event/targeted/ClassTargetingEvent.java
@@ -19,9 +19,10 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.event.targeted;
+package dev.tori.wraith.event.targeted;
-import me.tori.wraith.listener.Listener;
+import dev.tori.wraith.listener.Listener;
+import org.jetbrains.annotations.Nullable;
/**
* A basic implementation of the {@link IClassTargetingEvent} interface.
@@ -34,6 +35,7 @@
@SuppressWarnings("ClassCanBeRecord")
public class ClassTargetingEvent implements IClassTargetingEvent {
+ @Nullable
private final Class extends Listener>> targetClass;
/**
@@ -41,7 +43,7 @@ public class ClassTargetingEvent implements IClassTargetingEvent {
*
* @param targetClass The class representing the type of listeners to be targeted by this event.
*/
- public ClassTargetingEvent(Class extends Listener>> targetClass) {
+ public ClassTargetingEvent(@Nullable Class extends Listener>> targetClass) {
this.targetClass = targetClass;
}
@@ -50,6 +52,7 @@ public ClassTargetingEvent(Class extends Listener>> targetClass) {
*
* @return The class that represents the type of listeners targeted by this event.
*/
+ @Nullable
@Override
public Class extends Listener>> getTargetClass() {
return targetClass;
diff --git a/src/main/java/me/tori/wraith/event/targeted/IClassTargetingEvent.java b/src/main/java/dev/tori/wraith/event/targeted/IClassTargetingEvent.java
similarity index 91%
rename from src/main/java/me/tori/wraith/event/targeted/IClassTargetingEvent.java
rename to src/main/java/dev/tori/wraith/event/targeted/IClassTargetingEvent.java
index 413e57a..f4d1f19 100644
--- a/src/main/java/me/tori/wraith/event/targeted/IClassTargetingEvent.java
+++ b/src/main/java/dev/tori/wraith/event/targeted/IClassTargetingEvent.java
@@ -19,9 +19,10 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.event.targeted;
+package dev.tori.wraith.event.targeted;
-import me.tori.wraith.listener.Listener;
+import dev.tori.wraith.listener.Listener;
+import org.jetbrains.annotations.Nullable;
/**
* An interface representing an event that targets a specific class of listeners.
@@ -55,6 +56,7 @@ static boolean isListenerTargetedByEvent(Listener> listener, Object event) {
*
* @return The class that represents the type of listeners targeted by this event.
*/
+ @Nullable
Class extends Listener>> getTargetClass();
/**
@@ -68,6 +70,7 @@ static boolean isListenerTargetedByEvent(Listener> listener, Object event) {
* @since 3.3.0
*/
default boolean isListenerTargeted(Listener> listener) {
- return getTargetClass().isInstance(listener);
+ Class extends Listener>> targetClass = getTargetClass();
+ return (targetClass == null) || targetClass.isInstance(listener);
}
}
\ No newline at end of file
diff --git a/src/main/java/me/tori/wraith/listener/EventListener.java b/src/main/java/dev/tori/wraith/listener/EventListener.java
similarity index 99%
rename from src/main/java/me/tori/wraith/listener/EventListener.java
rename to src/main/java/dev/tori/wraith/listener/EventListener.java
index 9a62c20..a6eab4e 100644
--- a/src/main/java/me/tori/wraith/listener/EventListener.java
+++ b/src/main/java/dev/tori/wraith/listener/EventListener.java
@@ -19,9 +19,9 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.listener;
+package dev.tori.wraith.listener;
-import me.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.bus.IEventBus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/src/main/java/me/tori/wraith/listener/Invokable.java b/src/main/java/dev/tori/wraith/listener/Invokable.java
similarity index 98%
rename from src/main/java/me/tori/wraith/listener/Invokable.java
rename to src/main/java/dev/tori/wraith/listener/Invokable.java
index d8594ff..685ceb1 100644
--- a/src/main/java/me/tori/wraith/listener/Invokable.java
+++ b/src/main/java/dev/tori/wraith/listener/Invokable.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.listener;
+package dev.tori.wraith.listener;
/**
* A functional interface representing a callable object that can handle or process an event.
diff --git a/src/main/java/me/tori/wraith/listener/LambdaEventListener.java b/src/main/java/dev/tori/wraith/listener/LambdaEventListener.java
similarity index 99%
rename from src/main/java/me/tori/wraith/listener/LambdaEventListener.java
rename to src/main/java/dev/tori/wraith/listener/LambdaEventListener.java
index e344122..174a32d 100644
--- a/src/main/java/me/tori/wraith/listener/LambdaEventListener.java
+++ b/src/main/java/dev/tori/wraith/listener/LambdaEventListener.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.listener;
+package dev.tori.wraith.listener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/src/main/java/me/tori/wraith/listener/Listener.java b/src/main/java/dev/tori/wraith/listener/Listener.java
similarity index 98%
rename from src/main/java/me/tori/wraith/listener/Listener.java
rename to src/main/java/dev/tori/wraith/listener/Listener.java
index c1d5259..3e418cc 100644
--- a/src/main/java/me/tori/wraith/listener/Listener.java
+++ b/src/main/java/dev/tori/wraith/listener/Listener.java
@@ -19,9 +19,9 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.listener;
+package dev.tori.wraith.listener;
-import me.tori.wraith.bus.EventBus;
+import dev.tori.wraith.bus.EventBus;
import java.util.List;
import java.util.function.Consumer;
diff --git a/src/main/java/me/tori/wraith/listener/ListenerBuilder.java b/src/main/java/dev/tori/wraith/listener/ListenerBuilder.java
similarity index 98%
rename from src/main/java/me/tori/wraith/listener/ListenerBuilder.java
rename to src/main/java/dev/tori/wraith/listener/ListenerBuilder.java
index 2c02670..edb7bf9 100644
--- a/src/main/java/me/tori/wraith/listener/ListenerBuilder.java
+++ b/src/main/java/dev/tori/wraith/listener/ListenerBuilder.java
@@ -19,9 +19,9 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.listener;
+package dev.tori.wraith.listener;
-import me.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.bus.IEventBus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/src/main/java/me/tori/wraith/subscriber/ISubscriber.java b/src/main/java/dev/tori/wraith/subscriber/ISubscriber.java
similarity index 96%
rename from src/main/java/me/tori/wraith/subscriber/ISubscriber.java
rename to src/main/java/dev/tori/wraith/subscriber/ISubscriber.java
index 29638be..7394dc3 100644
--- a/src/main/java/me/tori/wraith/subscriber/ISubscriber.java
+++ b/src/main/java/dev/tori/wraith/subscriber/ISubscriber.java
@@ -19,10 +19,10 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.subscriber;
+package dev.tori.wraith.subscriber;
-import me.tori.wraith.bus.IEventBus;
-import me.tori.wraith.listener.Listener;
+import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.listener.Listener;
import java.util.Collection;
diff --git a/src/main/java/me/tori/wraith/subscriber/Subscriber.java b/src/main/java/dev/tori/wraith/subscriber/Subscriber.java
similarity index 98%
rename from src/main/java/me/tori/wraith/subscriber/Subscriber.java
rename to src/main/java/dev/tori/wraith/subscriber/Subscriber.java
index ce9f0c8..619b417 100644
--- a/src/main/java/me/tori/wraith/subscriber/Subscriber.java
+++ b/src/main/java/dev/tori/wraith/subscriber/Subscriber.java
@@ -19,10 +19,10 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.subscriber;
+package dev.tori.wraith.subscriber;
-import me.tori.wraith.bus.IEventBus;
-import me.tori.wraith.listener.Listener;
+import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.listener.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.*;
diff --git a/src/main/java/me/tori/wraith/task/ScheduledTask.java b/src/main/java/dev/tori/wraith/task/ScheduledTask.java
similarity index 99%
rename from src/main/java/me/tori/wraith/task/ScheduledTask.java
rename to src/main/java/dev/tori/wraith/task/ScheduledTask.java
index 54e4041..907b9c6 100644
--- a/src/main/java/me/tori/wraith/task/ScheduledTask.java
+++ b/src/main/java/dev/tori/wraith/task/ScheduledTask.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.task;
+package dev.tori.wraith.task;
import org.jetbrains.annotations.NotNull;
diff --git a/src/main/java/me/tori/wraith/task/TaskExecutor.java b/src/main/java/dev/tori/wraith/task/TaskExecutor.java
similarity index 99%
rename from src/main/java/me/tori/wraith/task/TaskExecutor.java
rename to src/main/java/dev/tori/wraith/task/TaskExecutor.java
index e2beb99..1f3a3f3 100644
--- a/src/main/java/me/tori/wraith/task/TaskExecutor.java
+++ b/src/main/java/dev/tori/wraith/task/TaskExecutor.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.task;
+package dev.tori.wraith.task;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
diff --git a/src/main/java/me/tori/wraith/util/IndexedHashSet.java b/src/main/java/dev/tori/wraith/util/IndexedHashSet.java
similarity index 99%
rename from src/main/java/me/tori/wraith/util/IndexedHashSet.java
rename to src/main/java/dev/tori/wraith/util/IndexedHashSet.java
index 02b1469..d8a5c09 100644
--- a/src/main/java/me/tori/wraith/util/IndexedHashSet.java
+++ b/src/main/java/dev/tori/wraith/util/IndexedHashSet.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.util;
+package dev.tori.wraith.util;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/src/main/test/dev/tori/wraith/Main.java b/src/main/test/dev/tori/wraith/Main.java
new file mode 100644
index 0000000..99fcf5b
--- /dev/null
+++ b/src/main/test/dev/tori/wraith/Main.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package dev.tori.wraith;
+
+import dev.tori.wraith.event.targeted.IClassTargetingEvent;
+import dev.tori.wraith.listener.Listener;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class Main {
+
+ public static void main(String[] args) {
+
+ }
+
+ public class Event implements IClassTargetingEvent {
+
+ @Nullable
+ private final Class extends Listener>> target;
+
+ public Event(@Nullable Class extends Listener>> target) {
+ this.target = target;
+ }
+
+ @Nullable
+ @Override
+ public Class extends Listener>> getTargetClass() {
+ return target;
+ }
+ }
+
+ static final class MessageEvent {
+
+ private String message;
+
+ public MessageEvent() {
+ this.message = "nothing to say";
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/test/me/tori/wraith/benchmarking/BenchmarkMain.java b/src/main/test/dev/tori/wraith/benchmarking/BenchmarkMain.java
similarity index 97%
rename from src/main/test/me/tori/wraith/benchmarking/BenchmarkMain.java
rename to src/main/test/dev/tori/wraith/benchmarking/BenchmarkMain.java
index 9738e62..9d04611 100644
--- a/src/main/test/me/tori/wraith/benchmarking/BenchmarkMain.java
+++ b/src/main/test/dev/tori/wraith/benchmarking/BenchmarkMain.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.benchmarking;
+package dev.tori.wraith.benchmarking;
import org.openjdk.jmh.Main;
diff --git a/src/main/test/me/tori/wraith/benchmarking/MyBenchmark.java b/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
similarity index 94%
rename from src/main/test/me/tori/wraith/benchmarking/MyBenchmark.java
rename to src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
index ce6c364..9b2ccf0 100644
--- a/src/main/test/me/tori/wraith/benchmarking/MyBenchmark.java
+++ b/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
@@ -19,11 +19,11 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.benchmarking;
+package dev.tori.wraith.benchmarking;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.listener.EventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.listener.EventListener;
+import dev.tori.wraith.subscriber.Subscriber;
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;
diff --git a/src/main/test/me/tori/wraith/persistency/PersistencyTest.java b/src/main/test/dev/tori/wraith/persistency/PersistencyTest.java
similarity index 91%
rename from src/main/test/me/tori/wraith/persistency/PersistencyTest.java
rename to src/main/test/dev/tori/wraith/persistency/PersistencyTest.java
index 06c2fb7..13fefed 100644
--- a/src/main/test/me/tori/wraith/persistency/PersistencyTest.java
+++ b/src/main/test/dev/tori/wraith/persistency/PersistencyTest.java
@@ -19,12 +19,12 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.persistency;
+package dev.tori.wraith.persistency;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.event.status.StatusEvent;
-import me.tori.wraith.listener.EventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.EventListener;
+import dev.tori.wraith.subscriber.Subscriber;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/src/main/test/me/tori/wraith/priority/PriorityTest.java b/src/main/test/dev/tori/wraith/priority/PriorityTest.java
similarity index 92%
rename from src/main/test/me/tori/wraith/priority/PriorityTest.java
rename to src/main/test/dev/tori/wraith/priority/PriorityTest.java
index 6a0b90a..71efd95 100644
--- a/src/main/test/me/tori/wraith/priority/PriorityTest.java
+++ b/src/main/test/dev/tori/wraith/priority/PriorityTest.java
@@ -19,12 +19,12 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.priority;
+package dev.tori.wraith.priority;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.event.status.StatusEvent;
-import me.tori.wraith.listener.LambdaEventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/src/main/test/me/tori/wraith/registration/RegistrationTest.java b/src/main/test/dev/tori/wraith/registration/RegistrationTest.java
similarity index 91%
rename from src/main/test/me/tori/wraith/registration/RegistrationTest.java
rename to src/main/test/dev/tori/wraith/registration/RegistrationTest.java
index 7afa6bf..3f7bb1a 100644
--- a/src/main/test/me/tori/wraith/registration/RegistrationTest.java
+++ b/src/main/test/dev/tori/wraith/registration/RegistrationTest.java
@@ -19,13 +19,13 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.registration;
+package dev.tori.wraith.registration;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.event.status.IStatusEvent;
-import me.tori.wraith.event.status.StatusEvent;
-import me.tori.wraith.listener.LambdaEventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.status.IStatusEvent;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/src/main/test/me/tori/wraith/statusevent/StatusEventTest.java b/src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java
similarity index 92%
rename from src/main/test/me/tori/wraith/statusevent/StatusEventTest.java
rename to src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java
index 03cff8e..0c1bb6c 100644
--- a/src/main/test/me/tori/wraith/statusevent/StatusEventTest.java
+++ b/src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java
@@ -19,12 +19,12 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.statusevent;
+package dev.tori.wraith.statusevent;
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.event.status.StatusEvent;
-import me.tori.wraith.listener.LambdaEventListener;
-import me.tori.wraith.subscriber.Subscriber;
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/src/main/test/me/tori/wraith/targetedevent/TargetedEventTest.java b/src/main/test/dev/tori/wraith/targetedevent/TargetedEventTest.java
similarity index 51%
rename from src/main/test/me/tori/wraith/targetedevent/TargetedEventTest.java
rename to src/main/test/dev/tori/wraith/targetedevent/TargetedEventTest.java
index e716b2d..9dfe183 100644
--- a/src/main/test/me/tori/wraith/targetedevent/TargetedEventTest.java
+++ b/src/main/test/dev/tori/wraith/targetedevent/TargetedEventTest.java
@@ -19,17 +19,17 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.targetedevent;
-
-import me.tori.wraith.bus.EventBus;
-import me.tori.wraith.event.status.StatusEvent;
-import me.tori.wraith.event.targeted.IClassTargetingEvent;
-import me.tori.wraith.listener.EventListener;
-import me.tori.wraith.listener.Listener;
-import me.tori.wraith.subscriber.Subscriber;
+package dev.tori.wraith.targetedevent;
+
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.event.targeted.IClassTargetingEvent;
+import dev.tori.wraith.listener.EventListener;
+import dev.tori.wraith.listener.Listener;
+import dev.tori.wraith.subscriber.Subscriber;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.*;
/**
* @author 7orivorian
@@ -37,7 +37,7 @@
public class TargetedEventTest {
@Test
- public void testTargetedEvent() {
+ public void testTargetedEventWithLowerPriority() {
final EventBus bus = new EventBus();
bus.subscribe(new Subscriber() {{
@@ -52,7 +52,7 @@ public void testTargetedEvent() {
}
@Test
- public void testTargetedEvent2() {
+ public void testTargetedEventWithHigherPriority() {
final EventBus bus = new EventBus();
bus.subscribe(new Subscriber() {{
@@ -66,6 +66,57 @@ public void testTargetedEvent2() {
assertFalse(bus.dispatch(event));
}
+ @Test
+ public void testNestedClassTargetNestedListener() {
+ final EventBus bus = new EventBus();
+
+ bus.subscribe(new Subscriber() {{
+ registerListeners(
+ new MyParentListener.MyNestedListener(0)
+ );
+ }});
+
+ TestEvent event = new TestEvent(MyParentListener.MyNestedListener.class);
+ bus.dispatch(event);
+
+ // Dispatched to nested target
+ assertEquals(2, event.getValue());
+ }
+
+ @Test
+ public void parentListenerNestedTarget() {
+ final EventBus bus = new EventBus();
+
+ bus.subscribe(new Subscriber() {{
+ registerListeners(
+ new MyParentListener(0)
+ );
+ }});
+
+ TestEvent event = new TestEvent(MyParentListener.MyNestedListener.class);
+ bus.dispatch(event);
+
+ // Not dispatched to parent of nested target
+ assertEquals(0, event.getValue());
+ }
+
+ @Test
+ public void testParentOfNestedClassTarget() {
+ final EventBus bus = new EventBus();
+
+ bus.subscribe(new Subscriber() {{
+ registerListeners(
+ new MyParentListener.MyNestedListener(0)
+ );
+ }});
+
+ TestEvent event = new TestEvent(MyParentListener.class);
+ bus.dispatch(event);
+
+ // Dispatched to nested listener if the parent is targeted
+ assertEquals(2, event.getValue());
+ }
+
static class MyListener extends EventListener {
public MyListener(int priority) {
@@ -90,17 +141,51 @@ public void invoke(TestEvent event) {
}
}
+ static class MyParentListener extends EventListener {
+
+ public MyParentListener(int priority) {
+ super(TestEvent.class, priority);
+ }
+
+ @Override
+ public void invoke(TestEvent event) {
+ event.setValue(1);
+ }
+
+ static class MyNestedListener extends MyParentListener {
+
+ public MyNestedListener(int priority) {
+ super(priority);
+ }
+
+ @Override
+ public void invoke(TestEvent event) {
+ event.setValue(2);
+ }
+ }
+ }
+
static class TestEvent extends StatusEvent implements IClassTargetingEvent {
private final Class extends Listener>> targetClass;
+ private int value;
public TestEvent(Class extends Listener>> target) {
this.targetClass = target;
+ this.value = 0;
}
@Override
public Class extends Listener>> getTargetClass() {
return targetClass;
}
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
}
}
\ No newline at end of file
diff --git a/src/main/test/me/tori/wraith/taskexecutor/TaskExecutorTest.java b/src/main/test/dev/tori/wraith/taskexecutor/TaskExecutorTest.java
similarity index 96%
rename from src/main/test/me/tori/wraith/taskexecutor/TaskExecutorTest.java
rename to src/main/test/dev/tori/wraith/taskexecutor/TaskExecutorTest.java
index a735a2d..f2783ca 100644
--- a/src/main/test/me/tori/wraith/taskexecutor/TaskExecutorTest.java
+++ b/src/main/test/dev/tori/wraith/taskexecutor/TaskExecutorTest.java
@@ -19,10 +19,10 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.taskexecutor;
+package dev.tori.wraith.taskexecutor;
-import me.tori.wraith.task.ScheduledTask;
-import me.tori.wraith.task.TaskExecutor;
+import dev.tori.wraith.task.ScheduledTask;
+import dev.tori.wraith.task.TaskExecutor;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/src/main/test/me/tori/wraith/util/IndexedHashSetTest.java b/src/main/test/dev/tori/wraith/util/IndexedHashSetTest.java
similarity index 97%
rename from src/main/test/me/tori/wraith/util/IndexedHashSetTest.java
rename to src/main/test/dev/tori/wraith/util/IndexedHashSetTest.java
index b33e6ae..1882998 100644
--- a/src/main/test/me/tori/wraith/util/IndexedHashSetTest.java
+++ b/src/main/test/dev/tori/wraith/util/IndexedHashSetTest.java
@@ -19,8 +19,9 @@
* THE SOFTWARE.
*/
-package me.tori.wraith.util;
+package dev.tori.wraith.util;
+import dev.tori.wraith.util.IndexedHashSet;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
From b0bf305af8e159546a1dbfb3539c0942f4dc6d38 Mon Sep 17 00:00:00 2001
From: Tori <7orivorian+github@gmail.com>
Date: Mon, 29 Jul 2024 20:17:33 -0400
Subject: [PATCH 15/30] Impl new class targeting system (1/x)
Signed-off-by: Tori <7orivorian+github@gmail.com>
---
.../example/expanded/ExampleListener.java | 3 +-
.../example/expanded/ExampleSubscriber.java | 3 +-
.../persistence/PersistenceExample.java | 3 +-
.../tori/example/simple/SimpleExample.java | 9 +-
.../statusevents/SupressionExample.java | 5 +-
.../statusevents/TerminationExample.java | 5 +-
.../java/dev/tori/wraith/bus/EventBus.java | 50 ++---
.../java/dev/tori/wraith/bus/IEventBus.java | 41 ++--
.../java/dev/tori/wraith/event/Target.java | 174 ++++++++++++++++
.../tori/wraith/listener/EventListener.java | 96 +++------
.../wraith/listener/LambdaEventListener.java | 74 +++----
.../dev/tori/wraith/listener/Listener.java | 45 +----
.../tori/wraith/listener/ListenerBuilder.java | 49 ++---
src/main/test/dev/tori/wraith/Main.java | 103 ++++++++--
src/main/test/dev/tori/wraith/MainTwo.java | 94 +++++++++
.../tori/wraith/benchmarking/MyBenchmark.java | 3 +-
.../wraith/persistency/PersistencyTest.java | 3 +-
.../tori/wraith/priority/PriorityTest.java | 13 +-
.../wraith/registration/RegistrationTest.java | 10 +-
.../wraith/statusevent/StatusEventTest.java | 9 +-
.../targetedevent/TargetedEventTest.java | 191 ------------------
21 files changed, 522 insertions(+), 461 deletions(-)
create mode 100644 src/main/java/dev/tori/wraith/event/Target.java
create mode 100644 src/main/test/dev/tori/wraith/MainTwo.java
delete mode 100644 src/main/test/dev/tori/wraith/targetedevent/TargetedEventTest.java
diff --git a/examples/java/dev/tori/example/expanded/ExampleListener.java b/examples/java/dev/tori/example/expanded/ExampleListener.java
index 327b2a1..0942fc1 100644
--- a/examples/java/dev/tori/example/expanded/ExampleListener.java
+++ b/examples/java/dev/tori/example/expanded/ExampleListener.java
@@ -21,6 +21,7 @@
package dev.tori.example.expanded;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.staged.EventStage;
import dev.tori.wraith.listener.EventListener;
@@ -33,7 +34,7 @@
class ExampleListener extends EventListener {
public ExampleListener() {
- super(ExampleEvent.class);
+ super(Target.fine(ExampleEvent.class));
}
@Override
diff --git a/examples/java/dev/tori/example/expanded/ExampleSubscriber.java b/examples/java/dev/tori/example/expanded/ExampleSubscriber.java
index 4e3c8de..f7028fd 100644
--- a/examples/java/dev/tori/example/expanded/ExampleSubscriber.java
+++ b/examples/java/dev/tori/example/expanded/ExampleSubscriber.java
@@ -21,6 +21,7 @@
package dev.tori.example.expanded;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.staged.EventStage;
import dev.tori.wraith.listener.LambdaEventListener;
import dev.tori.wraith.subscriber.Subscriber;
@@ -35,7 +36,7 @@ class ExampleSubscriber extends Subscriber {
public ExampleSubscriber() {
registerListener(
- new LambdaEventListener<>(ExampleEvent.class, event -> {
+ new LambdaEventListener(Target.fine(ExampleEvent.class), event -> {
if (event.getStage() == EventStage.PRE) {
event.setMessage("Hello world!");
}
diff --git a/examples/java/dev/tori/example/persistence/PersistenceExample.java b/examples/java/dev/tori/example/persistence/PersistenceExample.java
index cb194c5..eec5f97 100644
--- a/examples/java/dev/tori/example/persistence/PersistenceExample.java
+++ b/examples/java/dev/tori/example/persistence/PersistenceExample.java
@@ -23,6 +23,7 @@
import dev.tori.wraith.bus.EventBus;
import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.listener.LambdaEventListener;
import dev.tori.wraith.subscriber.Subscriber;
@@ -40,7 +41,7 @@ class PersistenceExample {
private static final Subscriber SUBSCRIBER = new Subscriber() {{
// Register a listener that prints a single
// String event & is then removed from the event bus
- registerListener(new LambdaEventListener<>(String.class, null, IEventBus.DEFAULT_PRIORITY, 1, System.out::println));
+ registerListener(new LambdaEventListener(Target.fine(String.class), IEventBus.DEFAULT_PRIORITY, 1, System.out::println));
}};
public static void main(String[] args) {
diff --git a/examples/java/dev/tori/example/simple/SimpleExample.java b/examples/java/dev/tori/example/simple/SimpleExample.java
index a887f4e..7e7173c 100644
--- a/examples/java/dev/tori/example/simple/SimpleExample.java
+++ b/examples/java/dev/tori/example/simple/SimpleExample.java
@@ -22,6 +22,7 @@
package dev.tori.example.simple;
import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.StatusEvent;
import dev.tori.wraith.listener.LambdaEventListener;
import dev.tori.wraith.subscriber.Subscriber;
@@ -44,7 +45,7 @@ public static void main(String[] args) {
bus.subscribe(subscriber);
// Create a simple event
- SimpleEvent event = new SimpleEvent("Pie is delicious <3");
+ StringEvent event = new StringEvent("Pie is delicious <3");
// Dispatch our event
bus.dispatch(event);
@@ -54,16 +55,16 @@ private static final class SimpleSubscriber extends Subscriber {
public SimpleSubscriber() {
registerListener(
- new LambdaEventListener<>(SimpleEvent.class, event -> System.out.println(event.getMessage()))
+ new LambdaEventListener(Target.fine(StringEvent.class), event -> System.out.println(event.getMessage()))
);
}
}
- private static final class SimpleEvent extends StatusEvent {
+ private static final class StringEvent extends StatusEvent {
private final String message;
- public SimpleEvent(String message) {
+ public StringEvent(String message) {
this.message = message;
}
diff --git a/examples/java/dev/tori/example/statusevents/SupressionExample.java b/examples/java/dev/tori/example/statusevents/SupressionExample.java
index 1ec766d..512e313 100644
--- a/examples/java/dev/tori/example/statusevents/SupressionExample.java
+++ b/examples/java/dev/tori/example/statusevents/SupressionExample.java
@@ -23,6 +23,7 @@
import dev.tori.wraith.bus.EventBus;
import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.StatusEvent;
import dev.tori.wraith.listener.LambdaEventListener;
import dev.tori.wraith.subscriber.Subscriber;
@@ -36,11 +37,11 @@ public class SupressionExample {
private static final IEventBus EVENT_BUS = new EventBus();
private static final Subscriber SUBSCRIBER = new Subscriber() {{
registerListeners(
- new LambdaEventListener<>(StringEvent.class, 1, event -> {
+ new LambdaEventListener(Target.fine(StringEvent.class), 1, event -> {
event.message = "Hello world!";
event.suppress();
}),
- new LambdaEventListener<>(StringEvent.class, 0, event -> {
+ new LambdaEventListener(Target.fine(StringEvent.class), 0, event -> {
event.message = "I do not greet";
})
);
diff --git a/examples/java/dev/tori/example/statusevents/TerminationExample.java b/examples/java/dev/tori/example/statusevents/TerminationExample.java
index 64fe8e5..aaccd5a 100644
--- a/examples/java/dev/tori/example/statusevents/TerminationExample.java
+++ b/examples/java/dev/tori/example/statusevents/TerminationExample.java
@@ -23,6 +23,7 @@
import dev.tori.wraith.bus.EventBus;
import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.StatusEvent;
import dev.tori.wraith.listener.LambdaEventListener;
import dev.tori.wraith.subscriber.Subscriber;
@@ -36,11 +37,11 @@ public class TerminationExample {
private static final IEventBus EVENT_BUS = new EventBus();
private static final Subscriber SUBSCRIBER = new Subscriber() {{
registerListeners(
- new LambdaEventListener<>(StringEvent.class, 1, event -> {
+ new LambdaEventListener(Target.fine(StringEvent.class), 1, event -> {
event.message = "Hello world!";
event.terminate();
}),
- new LambdaEventListener<>(StringEvent.class, 0, event -> {
+ new LambdaEventListener(Target.fine(StringEvent.class), 0, event -> {
event.message = "I do not greet";
})
);
diff --git a/src/main/java/dev/tori/wraith/bus/EventBus.java b/src/main/java/dev/tori/wraith/bus/EventBus.java
index b3bbd62..3ff1cb5 100644
--- a/src/main/java/dev/tori/wraith/bus/EventBus.java
+++ b/src/main/java/dev/tori/wraith/bus/EventBus.java
@@ -21,13 +21,14 @@
package dev.tori.wraith.bus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.IStatusEvent;
-import dev.tori.wraith.event.targeted.IClassTargetingEvent;
import dev.tori.wraith.listener.Listener;
import dev.tori.wraith.subscriber.ISubscriber;
import dev.tori.wraith.task.ScheduledTask;
import dev.tori.wraith.task.TaskExecutor;
import dev.tori.wraith.util.IndexedHashSet;
+import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@@ -158,7 +159,7 @@ public void unsubscribe(ISubscriber subscriber) {
public void register(Listener> listener) {
Objects.requireNonNull(listener, "Cannot register null listener to event bus " + id + "!");
- IndexedHashSet listeners = this.listeners.computeIfAbsent(listener.getTarget(), target -> new IndexedHashSet<>());
+ IndexedHashSet listeners = this.listeners.computeIfAbsent(listener.getTarget().clazz(), target -> new IndexedHashSet<>());
final int size = listeners.size();
int index = 0;
for (; index < size; index++) {
@@ -178,43 +179,43 @@ public void register(Listener> listener) {
@Override
public void unregister(Listener> listener) {
Objects.requireNonNull(listener, "Cannot unregister null listener from event bus " + id + "!");
- listeners.get(listener.getTarget()).removeIf(l -> l.equals(listener));
+ listeners.get(listener.getTarget().clazz()).removeIf(l -> l.equals(listener));
}
/**
- * Convenience method to dispatch an event with no {@linkplain Listener#getType() listener type} restriction, and
+ * Convenience method to dispatch an event with no {@linkplain Target target listener}, and
* normal processing priority.
*
- * @see #dispatch(Object, Class, boolean)
+ * @see #dispatch(Object, Target, boolean)
* @since 3.3.0
*/
@Override
public boolean dispatch(Object event) {
- return dispatch(event, null, false);
+ return dispatch(event, Target.none(), false);
}
/**
- * Convenience method to dispatch an event with an optional {@linkplain Listener#getType() listener type} restriction, and
+ * Convenience method to dispatch an event with an optional {@linkplain Target target listener} and
* normal processing priority.
*
- * @see #dispatch(Object, Class, boolean)
- * @since 3.3.0
+ * @see #dispatch(Object, Target, boolean)
+ * @since 4.0.0
*/
@Override
- public boolean dispatch(Object event, Class> type) {
- return dispatch(event, type, false);
+ public boolean dispatch(Object event, Target target) {
+ return dispatch(event, target, false);
}
/**
- * Convenience method to dispatch an event with no {@linkplain Listener#getType() listener type} restriction, and
+ * Convenience method to dispatch an event with no {@linkplain Target target listener}, and
* optional inverted processing priority.
*
- * @see #dispatch(Object, Class, boolean)
- * @since 3.3.0
+ * @see #dispatch(Object, Target, boolean)
+ * @since 4.0.0
*/
@Override
public boolean dispatch(Object event, boolean invertPriority) {
- return dispatch(event, null, invertPriority);
+ return dispatch(event, Target.none(), invertPriority);
}
/**
@@ -223,27 +224,28 @@ public boolean dispatch(Object event, boolean invertPriority) {
* The {@code type} parameter serves as a filtering mechanism for listeners, enabling you to selectively invoke
* listeners based on their type, allowing for more targeted event handling.
*
- * @param event the event to be dispatched
- * @param type the type of listener to invoke (can be {@code null})
- * @param invertPriority flag to dispatch the event in inverse listener priority
+ * @param event the event to be dispatched.
+ * @param target the {@linkplain Target target listener} to invoke.
+ * @param invertPriority flag to dispatch the event in inverse listener priority.
* @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
- * {@code false} otherwise
+ * {@code false} otherwise.
* @throws NullPointerException if the given event is {@code null}
* @throws UnsupportedOperationException if this event bus is {@link #shutdown}
- * @since 3.3.0
+ * @since 4.0.0
*/
@Override
- public boolean dispatch(Object event, Class> type, boolean invertPriority) {
+ public boolean dispatch(Object event, Target target, boolean invertPriority) {
Objects.requireNonNull(event, "Cannot dispatch a null event to event bus " + id + "!");
+ Objects.requireNonNull(target, "Cannot dispatch an event with a null target to event bus " + id + "!");
if (isShutdown()) {
- throw new UnsupportedOperationException("Dispatcher " + id + " is shutdown!");
+ throw new UnsupportedOperationException("Event bus " + id + " is shutdown!");
} else {
taskExecutor.onEvent(event);
dispatchToEachListener(
event,
- this.listeners.get(event.getClass()),
- listener -> listener.isAcceptableType(type) && IClassTargetingEvent.isListenerTargetedByEvent(listener, event),
+ listeners.get(event.getClass()),
+ listener -> target.targets(listener.getClass()) && listener.getTarget().targets(event.getClass()),
invertPriority
);
diff --git a/src/main/java/dev/tori/wraith/bus/IEventBus.java b/src/main/java/dev/tori/wraith/bus/IEventBus.java
index c34e6e4..aafd5dd 100644
--- a/src/main/java/dev/tori/wraith/bus/IEventBus.java
+++ b/src/main/java/dev/tori/wraith/bus/IEventBus.java
@@ -21,31 +21,31 @@
package dev.tori.wraith.bus;
-import dev.tori.wraith.subscriber.ISubscriber;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.IStatusEvent;
import dev.tori.wraith.listener.EventListener;
import dev.tori.wraith.listener.Listener;
+import dev.tori.wraith.subscriber.ISubscriber;
/**
* An event bus that allows for the subscription, registration, and dispatching of events to listeners.
*
- * @author 7orivorian
- * @since 1.0.0
+ * @author 7orivorian
+ * @since 1.0.0
*/
public interface IEventBus {
/**
* Default priority used when no other priority is specified.
*
- * @see EventListener#EventListener(Class)
- * @see EventListener#EventListener(Class, Class)
+ * @see EventListener#EventListener(Target)
*/
int DEFAULT_PRIORITY = 0;
/**
* Subscribes the specified subscriber to this event bus.
*
- * @param subscriber the {@link ISubscriber} to be subscribed
+ * @param subscriber the {@link ISubscriber} to be subscribed.
* @see #register(Listener)
*/
void subscribe(ISubscriber subscriber);
@@ -53,7 +53,7 @@ public interface IEventBus {
/**
* Unsubscribes the specified subscriber from this event bus.
*
- * @param subscriber the {@link ISubscriber} to be unsubscribed
+ * @param subscriber the {@link ISubscriber} to be unsubscribed.
* @see #unregister(Listener)
*/
void unsubscribe(ISubscriber subscriber);
@@ -61,21 +61,21 @@ public interface IEventBus {
/**
* Registers the specified listener to this event bus.
*
- * @param listener the {@link Listener} to be registered
+ * @param listener the {@link Listener} to be registered.
*/
void register(Listener> listener);
/**
* Unregisters the specified listener from this event bus.
*
- * @param listener the {@link Listener} to be unregistered
+ * @param listener the {@link Listener} to be unregistered.
*/
void unregister(Listener> listener);
/**
* Dispatches the specified event to all registered listeners.
*
- * @param event the event to be dispatched
+ * @param event the event to be dispatched.
* @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
* {@code false} otherwise.
*/
@@ -84,35 +84,38 @@ public interface IEventBus {
/**
* Dispatches the specified event to all registered listeners of the specified type.
*
- * @param event the event to be dispatched
- * @param type the type of listener to invoke (can be {@code null})
+ * @param event the event to be dispatched.
+ * @param target the {@linkplain Target target class} of listener to invoke.
* @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
* {@code false} otherwise.
+ * @since 4.0.0
*/
- boolean dispatch(Object event, Class> type);
+ boolean dispatch(Object event, Target target);
/**
* Dispatches the specified event to all registered listeners, with the option to invert the processing priority.
*
- * @param event the event to be dispatched
+ * @param event the event to be dispatched.
* @param invertPriority if {@code true}, listeners are processed in order of inverse priority; otherwise,
- * they are processed in normal order
+ * they are processed in normal order.
* @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
* {@code false} otherwise.
+ * @since 3.3.0
*/
boolean dispatch(Object event, boolean invertPriority);
/**
* Dispatches the specified event to all registered listeners of the specified type, with the option to invert the processing priority.
*
- * @param event the event to be dispatched
- * @param type the type of listener to invoke (can be {@code null})
+ * @param event the event to be dispatched.
+ * @param target the {@linkplain Target target class} of listener to invoke.
* @param invertPriority if {@code true}, listeners are processed in order of inverse priority; otherwise,
- * they are processed in normal order
+ * they are processed in normal order.
* @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
* {@code false} otherwise.
+ * @since 4.0.0
*/
- boolean dispatch(Object event, Class> type, boolean invertPriority);
+ boolean dispatch(Object event, Target target, boolean invertPriority);
/**
* Shuts down this event bus, preventing future events from being dispatched.
diff --git a/src/main/java/dev/tori/wraith/event/Target.java b/src/main/java/dev/tori/wraith/event/Target.java
new file mode 100644
index 0000000..7daad3e
--- /dev/null
+++ b/src/main/java/dev/tori/wraith/event/Target.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package dev.tori.wraith.event;
+
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+
+/**
+ * Represents a class target with a specified targeting strategy.
+ * This class is used to determine if a given class matches the target class according to the targeting strategy.
+ *
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class Target {
+
+ @Nullable
+ private final Class> clazz;
+ @NotNull
+ private final TargetingRule rule;
+
+ /**
+ * Constructs a new {@link Target}.
+ *
+ * @param clazz the target class.
+ * @param rule the targeting rule.
+ */
+ @Contract(pure = true)
+ private Target(@Nullable Class> clazz, @NotNull TargetingRule rule) {
+ this.clazz = clazz;
+ this.rule = rule;
+ }
+
+ /**
+ * Returns a {@code ClassTarget} with no specific target.
+ *
+ * @return a {@code ClassTarget} with no specific target.
+ */
+ @NotNull
+ public static Target none() {
+ return new Target(null, TargetingRule.FINE);
+ }
+
+ /**
+ * Returns a {@code ClassTarget} with the specified target and {@link TargetingRule#FINE FINE} targeting.
+ *
+ * @param target the target class.
+ * @return a {@code ClassTarget} with the specified target and {@link TargetingRule#FINE FINE} targeting.
+ */
+ @NotNull
+ public static Target fine(@Nullable Class> target) {
+ return new Target(target, TargetingRule.FINE);
+ }
+
+ /**
+ * Returns a {@code ClassTarget} with the specified target and {@link TargetingRule#CASCADE CASCADE} targeting.
+ *
+ * @param target the target class.
+ * @return a {@code ClassTarget} with the specified target and {@link TargetingRule#CASCADE CASCADE} targeting.
+ */
+ @NotNull
+ public static Target cascade(@Nullable Class> target) {
+ return new Target(target, TargetingRule.CASCADE);
+ }
+
+ /**
+ * Returns a {@code ClassTarget} with the specified target and {@link TargetingRule#REVERSE_CASCADE REVERSE_CASCADE} targeting.
+ *
+ * @param target the target class.
+ * @return a {@code ClassTarget} with the specified target and {@link TargetingRule#REVERSE_CASCADE REVERSE_CASCADE} targeting.
+ */
+ @NotNull
+ public static Target reverseCascade(@Nullable Class> target) {
+ return new Target(target, TargetingRule.REVERSE_CASCADE);
+ }
+
+ /**
+ * Checks if the target class matches the given class according to the targeting rule.
+ *
+ * @param clazz the class to check.
+ * @return {@code true} if the class matches the target, {@code false} otherwise.
+ */
+ public boolean targets(@NotNull Class> clazz) {
+ if (this.clazz == null) {
+ return true; // Null target class will target anything
+ }
+ return rule.isMatch(clazz, this.clazz);
+ }
+
+ /**
+ * Returns the target class.
+ *
+ * @return the target class, {@code null} if no target is set.
+ */
+ @Nullable
+ public Class> clazz() {
+ return clazz;
+ }
+
+ /**
+ * Returns the targeting rule.
+ *
+ * @return the targeting rule.
+ */
+ @NotNull
+ public TargetingRule rule() {
+ return rule;
+ }
+
+ @Override
+ public String toString() {
+ return "ClassTarget{" +
+ "target=" + clazz +
+ ", matching=" + rule +
+ '}';
+ }
+
+ /**
+ * Enumeration of targeting rules.
+ */
+ public enum TargetingRule {
+ /**
+ * The class must exactly equal the target class.
+ */
+ FINE {
+ @Override
+ public boolean isMatch(Class> clazz, Class> target) {
+ return Objects.equals(clazz, target);
+ }
+ },
+ /**
+ * The class must be a subclass or implementation of the target class.
+ */
+ CASCADE {
+ @Override
+ public boolean isMatch(Class> clazz, Class> target) {
+ return target.isAssignableFrom(clazz);
+ }
+ },
+ /**
+ * The target class must be a subclass or implementation of the given class.
+ */
+ REVERSE_CASCADE {
+ @Override
+ public boolean isMatch(Class> clazz, Class> target) {
+ return clazz.isAssignableFrom(target);
+ }
+ };
+
+ public abstract boolean isMatch(Class> clazz, Class> target);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/dev/tori/wraith/listener/EventListener.java b/src/main/java/dev/tori/wraith/listener/EventListener.java
index a6eab4e..fa426e5 100644
--- a/src/main/java/dev/tori/wraith/listener/EventListener.java
+++ b/src/main/java/dev/tori/wraith/listener/EventListener.java
@@ -22,14 +22,15 @@
package dev.tori.wraith.listener;
import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.event.Target;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.Objects;
/**
* An abstract base class for event listeners that implements the {@link Listener} interface.
- * Event listeners provide event handling logic with specified priorities, target classes, and types.
+ * Event listeners provide event handling logic with specified targets and priorities.
*
* @param The type of event this listener is designed to handle.
* @author 7orivorian
@@ -39,71 +40,49 @@
*/
public abstract class EventListener implements Listener {
- protected final @NotNull Class super T> target;
- protected final @Nullable Class> type;
+ @NotNull
+ protected final Target target;
protected final int priority;
protected final boolean indefinitePersistence;
protected int persists;
/**
- * Constructs an event listener with default priority and no specified type.
- *
- * @param target The target class that this listener is designed to handle events for.
- * @throws NullPointerException if {@code target} is {@code null}.
- */
- public EventListener(@NotNull Class super T> target) {
- this(target, null, IEventBus.DEFAULT_PRIORITY, DEFAULT_PERSISTENCE);
- }
-
- /**
- * Constructs an event listener with a specified priority and no specified type.
- *
- * @param target The target class that this listener is designed to handle events for.
- * @param priority The priority level of this listener for event handling.
- * @throws NullPointerException if {@code target} is {@code null}.
- */
- public EventListener(@NotNull Class super T> target, int priority) {
- this(target, null, priority, DEFAULT_PERSISTENCE);
- }
-
- /**
- * Constructs an event listener with default priority and a specified type.
+ * Constructs an event listener with default {@linkplain IEventBus#DEFAULT_PRIORITY priority} and {@linkplain #DEFAULT_PERSISTENCE persistence}.
*
- * @param target The target class that this listener is designed to handle events for.
- * @param type The type of events that this listener can handle. Can be {@code null}.
+ * @param target This listener's {@linkplain Target target class}.
* @throws NullPointerException if {@code target} is {@code null}.
*/
- public EventListener(@NotNull Class super T> target, @Nullable Class> type) {
- this(target, type, IEventBus.DEFAULT_PRIORITY, DEFAULT_PERSISTENCE);
+ @Contract(pure = true)
+ public EventListener(@NotNull Target target) {
+ this(target, IEventBus.DEFAULT_PRIORITY, DEFAULT_PERSISTENCE);
}
/**
- * Constructs an event listener with a specified priority and type.
+ * Constructs an event listener with a specified {@code priority} and {@linkplain #DEFAULT_PERSISTENCE default persistence}.
*
- * @param target The target class that this listener is designed to handle events for.
+ * @param target This listener's {@link Target}.
* @param priority The priority level of this listener for event handling.
- * @param type The type of events that this listener can handle. Can be {@code null}.
* @throws NullPointerException if {@code target} is {@code null}.
*/
- public EventListener(@NotNull Class super T> target, @Nullable Class> type, int priority) {
- this(target, type, priority, DEFAULT_PERSISTENCE);
+ @Contract(pure = true)
+ public EventListener(@NotNull Target target, int priority) {
+ this(target, priority, DEFAULT_PERSISTENCE);
}
/**
- * Constructs an event listener with a specified priority and type.
+ * Constructs an event listener with a specified {@code priority} and {@code persists}.
*
- * @param target The target class that this listener is designed to handle events for.
- * @param type The type of events that this listener can handle. Can be {@code null}.
+ * @param target This listener's {@link Target}.
* @param priority The priority level of this listener for event handling.
* @param persists How many events this listener should handle before being killed.
- * A value {@code <= 0} will flag this listener to {@linkplain #indefinitePersistence persist indefinitely}.
+ * A value {@code <= 0} will {@linkplain #indefinitePersistence flag this listener to persist indefinitely}.
* @throws NullPointerException if {@code target} is {@code null}.
* @since 3.2.0
*/
- public EventListener(@NotNull Class super T> target, @Nullable Class> type, int priority, int persists) {
+ @Contract(pure = true)
+ public EventListener(@NotNull Target target, int priority, int persists) {
Objects.requireNonNull(target);
this.target = target;
- this.type = type;
this.priority = priority;
this.persists = persists;
this.indefinitePersistence = persists <= 0;
@@ -120,24 +99,13 @@ public int getPriority() {
}
/**
- * Gets the type of events that this listener can handle.
- *
- * @return The type of events that this listener can handle, or {@code null} if no type is specified.
- */
- @Nullable
- @Override
- public Class> getType() {
- return type;
- }
-
- /**
- * Gets the target class that this listener is designed to handle events for.
+ * Gets the {@link Target} of this listener.
*
- * @return The target class that this listener is designed to handle events for.
+ * @return The {@link Target} of this listener.
*/
@NotNull
@Override
- public Class super T> getTarget() {
+ public Target getTarget() {
return target;
}
@@ -147,7 +115,7 @@ public Class super T> getTarget() {
* or if the {@linkplain EventListener#persists internal persistence counter} is greater than zero
* after being decremented.
*
- * @return {@code true} if the listener should persist, {@code false} otherwise
+ * @return {@code true} if the listener should persist, {@code false} otherwise.
* @since 3.2.0
*/
@Override
@@ -159,7 +127,7 @@ public boolean shouldPersist() {
* Indicates whether this listener is inherently persistent.
* A listener is considered inherently persistent if the {@linkplain #indefinitePersistence} flag is set to {@code true}.
*
- * @return {@code true} if the listener is inherently persistent, {@code false} otherwise
+ * @return {@code true} if the listener is inherently persistent, {@code false} otherwise.
* @since 3.2.0
*/
@Override
@@ -168,25 +136,24 @@ public boolean hasIndefinitePersistence() {
}
@Override
- public boolean equals(Object o) {
- if (this == o) {
+ @Contract(value = "null -> false", pure = true)
+ public boolean equals(Object obj) {
+ if (this == obj) {
return true;
}
- if ((o == null) || (getClass() != o.getClass())) {
+ if ((obj == null) || (getClass() != obj.getClass())) {
return false;
}
- EventListener> that = (EventListener>) o;
+ EventListener> that = (EventListener>) obj;
return (priority == that.priority)
&& (indefinitePersistence == that.indefinitePersistence)
- && target.equals(that.target)
- && Objects.equals(type, that.type);
+ && target.equals(that.target);
}
@Override
public int hashCode() {
int result = target.hashCode();
- result = (31 * result) + Objects.hashCode(type);
result = (31 * result) + priority;
result = (31 * result) + Boolean.hashCode(indefinitePersistence);
return result;
@@ -196,7 +163,6 @@ public int hashCode() {
public String toString() {
return "EventListener{" +
"target=" + target +
- ", type=" + type +
", priority=" + priority +
", indefinitePersistence=" + indefinitePersistence +
", persists=" + persists +
diff --git a/src/main/java/dev/tori/wraith/listener/LambdaEventListener.java b/src/main/java/dev/tori/wraith/listener/LambdaEventListener.java
index 174a32d..0f1ce8a 100644
--- a/src/main/java/dev/tori/wraith/listener/LambdaEventListener.java
+++ b/src/main/java/dev/tori/wraith/listener/LambdaEventListener.java
@@ -21,8 +21,9 @@
package dev.tori.wraith.listener;
+import dev.tori.wraith.event.Target;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.Objects;
@@ -31,82 +32,53 @@
* This provides a convenient way to create event listeners using lambda expressions.
*
* @param The type of event handled by this listener.
- * @author 7orivorian
- * @since 1.3.0
+ * @author 7orivorian
+ * @since 1.3.0
*/
public class LambdaEventListener extends EventListener {
- protected final @NotNull Invokable invokable;
+ @NotNull
+ protected final Invokable invokable;
/**
- * Constructs a new `LambdaEventListener` with the given target class and invokable action.
+ * Constructs a new {@link LambdaEventListener} with the given target and invokable action.
*
- * @param target The target class of the event.
+ * @param target This listener's {@link Target}.
* @param invokable The invokable action to be executed when the event is dispatched.
* @throws NullPointerException if {@code target} is {@code null}.
*/
- public LambdaEventListener(@NotNull Class super E> target, @NotNull Invokable invokable) {
+ public LambdaEventListener(@NotNull Target target, @NotNull Invokable invokable) {
super(target);
Objects.requireNonNull(invokable);
this.invokable = invokable;
}
/**
- * Constructs a new `LambdaEventListener` with the given target class, priority, and invokable action.
+ * Constructs a new {@link LambdaEventListener} with the given target, priority, and invokable action.
*
- * @param target The target class of the event.
+ * @param target This listener's {@link Target}.
* @param priority The priority of this listener.
* @param invokable The invokable action to be executed when the event is dispatched.
* @throws NullPointerException if {@code target} is {@code null}.
*/
- public LambdaEventListener(@NotNull Class super E> target, int priority, @NotNull Invokable invokable) {
+ public LambdaEventListener(@NotNull Target target, int priority, @NotNull Invokable invokable) {
super(target, priority);
Objects.requireNonNull(invokable);
this.invokable = invokable;
}
/**
- * Constructs a new `LambdaEventListener` with the given target class, type, and invokable action.
+ * Constructs a new {@link LambdaEventListener} with the given target, priority, and invokable action.
*
- * @param target The target class of the event.
- * @param type The type of the event.
- * @param invokable The invokable action to be executed when the event is dispatched.
- * @throws NullPointerException if {@code target} is {@code null}.
- */
- public LambdaEventListener(@NotNull Class super E> target, @Nullable Class> type, @NotNull Invokable invokable) {
- super(target, type);
- Objects.requireNonNull(invokable);
- this.invokable = invokable;
- }
-
- /**
- * Constructs a new `LambdaEventListener` with the given target class, priority, type, and invokable action.
- *
- * @param target The target class of the event.
- * @param priority The priority of this listener.
- * @param type The type of the event.
- * @param invokable The invokable action to be executed when the event is dispatched.
- * @throws NullPointerException if {@code target} is {@code null}.
- */
- public LambdaEventListener(@NotNull Class super E> target, @Nullable Class> type, int priority, @NotNull Invokable invokable) {
- super(target, type, priority);
- Objects.requireNonNull(invokable);
- this.invokable = invokable;
- }
-
- /**
- * Constructs a new {@code LambdaEventListener} with the given target class, priority, type, and invokable action.
- *
- * @param target The target class of the event.
- * @param type The type of the event.
+ * @param target This listener's {@link Target}.
* @param priority The priority of this listener.
* @param persists How many events this listener should handle before being killed.
- * A value {@code <= 0} will flag this listener to {@linkplain #indefinitePersistence persist indefinitely}.
+ * A value of {@code <= 0} will flag this listener to {@linkplain #indefinitePersistence persist indefinitely}.
* @param invokable The invokable action to be executed when the event is dispatched.
* @throws NullPointerException if {@code target} is {@code null}.
*/
- public LambdaEventListener(@NotNull Class super E> target, @Nullable Class> type, int priority, int persists, @NotNull Invokable invokable) {
- super(target, type, priority, persists);
+ public LambdaEventListener(@NotNull Target target, int priority, int persists, @NotNull Invokable invokable) {
+ super(target, priority, persists);
Objects.requireNonNull(invokable);
this.invokable = invokable;
}
@@ -122,18 +94,19 @@ public void invoke(E event) {
}
@Override
- public boolean equals(Object o) {
- if (this == o) {
+ @Contract(value = "null -> false", pure = true)
+ public boolean equals(Object obj) {
+ if (this == obj) {
return true;
}
- if ((o == null) || (getClass() != o.getClass())) {
+ if ((obj == null) || (getClass() != obj.getClass())) {
return false;
}
- if (!super.equals(o)) {
+ if (!super.equals(obj)) {
return false;
}
- LambdaEventListener> that = (LambdaEventListener>) o;
+ LambdaEventListener> that = (LambdaEventListener>) obj;
return invokable.equals(that.invokable);
}
@@ -148,7 +121,6 @@ public int hashCode() {
public String toString() {
return "LambdaEventListener{" +
"target=" + target +
- ", type=" + type +
", priority=" + priority +
", indefinitePersistence=" + indefinitePersistence +
", persists=" + persists +
diff --git a/src/main/java/dev/tori/wraith/listener/Listener.java b/src/main/java/dev/tori/wraith/listener/Listener.java
index 3e418cc..c9b8fc8 100644
--- a/src/main/java/dev/tori/wraith/listener/Listener.java
+++ b/src/main/java/dev/tori/wraith/listener/Listener.java
@@ -22,19 +22,20 @@
package dev.tori.wraith.listener;
import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.Target;
+import dev.tori.wraith.util.IndexedHashSet;
+import org.jetbrains.annotations.NotNull;
-import java.util.List;
-import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* An interface representing an event listener with priority, type, and target class information.
*
* @param The type of event this listener is designed to handle.
- * @author 7orivorian
+ * @author 7orivorian
* @see EventListener
* @see Invokable
- * @since 1.0.0
+ * @since 1.0.0
*/
public interface Listener extends Invokable {
@@ -48,24 +49,19 @@ public interface Listener extends Invokable {
int getPriority();
/**
- * Gets the type of events that this listener can handle.
+ * Gets the {@linkplain Target target class} of this listener.
*
- * @return The type of events that this listener can handle, or {@code null} if no type is specified.
+ * @return the {@linkplain Target target class} of this listener.
+ * @since 4.0.0
*/
- Class> getType();
-
- /**
- * Gets the target class that this listener is designed to handle events for.
- *
- * @return The target class that this listener is designed to handle events for.
- */
- Class super T> getTarget();
+ @NotNull
+ Target getTarget();
/**
* Determines whether this listener should persist after being invoked.
*
* @return {@code true} if the listener should persist, {@code false} otherwise.
- * @see EventBus#forEachListener(List, Predicate, Consumer, boolean)
+ * @see EventBus#dispatchToEachListener(Object, IndexedHashSet, Predicate, boolean)
* @since 3.2.0
*/
@SuppressWarnings("JavadocReference")
@@ -82,23 +78,4 @@ default boolean shouldPersist() {
default boolean hasIndefinitePersistence() {
return true;
}
-
- /**
- * Checks if the provided type is acceptable for this listener.
- *
- * This default method evaluates whether the given type is acceptable by comparing it with
- * the type associated with this listener. It returns {@code true} if any of the following conditions are met:
- *
- *
The provided type is {@code null}.
- *
The listener's type is {@code null}.
- *
The provided type is equal to the listener's type.
- *
- *
- * @param type the class type to check for acceptability
- * @return {@code true} if the type is acceptable, {@code false} otherwise.
- * @since 3.3.0
- */
- default boolean isAcceptableType(Class> type) {
- return (type == null) || (getType() == null) || (getType() == type);
- }
}
\ No newline at end of file
diff --git a/src/main/java/dev/tori/wraith/listener/ListenerBuilder.java b/src/main/java/dev/tori/wraith/listener/ListenerBuilder.java
index edb7bf9..356dabd 100644
--- a/src/main/java/dev/tori/wraith/listener/ListenerBuilder.java
+++ b/src/main/java/dev/tori/wraith/listener/ListenerBuilder.java
@@ -22,8 +22,8 @@
package dev.tori.wraith.listener;
import dev.tori.wraith.bus.IEventBus;
+import dev.tori.wraith.event.Target;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.Objects;
@@ -37,8 +37,7 @@
*
* {@code
* EventListener listener = new ListenerBuilder<>()
- * .target(MyEvent.class)
- * .type(SomeSpecificType.class)
+ * .target(ClassTarget.fine(MyEvent.class))
* .priority(5)
* .persists(10)
* .invokable(event -> handleEvent(event))
@@ -53,40 +52,28 @@
*/
public class ListenerBuilder {
- private Class super T> target = null;
- private @Nullable Class> type = null;
+ private Target target = null;
private int priority = IEventBus.DEFAULT_PRIORITY;
private int persists = -1;
private boolean persistent = true;
private Invokable invokable = null;
/**
- * Sets the target class for this listener.
+ * Sets the {@link Target} for this listener.
*
- * @param target the class of the event this listener will handle
- * @return this {@code ListenerBuilder} instance
+ * @param target This listener's {@link Target}.
+ * @return this {@code ListenerBuilder} instance.
*/
- public ListenerBuilder target(@NotNull Class super T> target) {
+ public ListenerBuilder target(@NotNull Target target) {
this.target = target;
return this;
}
- /**
- * Sets the specific type for this listener.
- *
- * @param type the specific type of event this listener will handle
- * @return this {@code ListenerBuilder} instance
- */
- public ListenerBuilder type(@Nullable Class super T> type) {
- this.type = type;
- return this;
- }
-
/**
* Sets the priority for this listener.
*
- * @param priority the priority of the listener
- * @return this {@code ListenerBuilder} instance
+ * @param priority the priority of the listener.
+ * @return this {@code ListenerBuilder} instance.
*/
public ListenerBuilder priority(int priority) {
this.priority = priority;
@@ -98,8 +85,8 @@ public ListenerBuilder priority(int priority) {
*
* Overrides {@link #persistent}.
*
- * @param persists the number of events this listener should handle before being removed
- * @return this {@code ListenerBuilder} instance
+ * @param persists the number of events this listener should handle before being removed.
+ * @return this {@code ListenerBuilder} instance.
*/
public ListenerBuilder persists(int persists) {
this.persists = persists;
@@ -112,8 +99,8 @@ public ListenerBuilder persists(int persists) {
*
* Overrides {@link #persists}.
*
- * @param persistent {@code true} if the listener should be persistent, {@code false} otherwise
- * @return this {@code ListenerBuilder} instance
+ * @param persistent {@code true} if the listener should be persistent, {@code false} otherwise.
+ * @return this {@code ListenerBuilder} instance.
*/
public ListenerBuilder persistent(boolean persistent) {
this.persistent = persistent;
@@ -127,7 +114,7 @@ public ListenerBuilder persistent(boolean persistent) {
* Sets the invokable action for this listener.
*
* @param invokable the action to be invoked when an event is handled
- * @return this {@code ListenerBuilder} instance
+ * @return this {@code ListenerBuilder} instance.
*/
public ListenerBuilder invokable(@NotNull Invokable invokable) {
this.invokable = invokable;
@@ -137,9 +124,9 @@ public ListenerBuilder invokable(@NotNull Invokable invokable) {
/**
* Builds and returns an {@link EventListener} with the configured properties.
*
- * @return a new {@link EventListener} instance
- * @throws NullPointerException if the target or invokable is not set
- * @throws IllegalArgumentException if there is a mismatch between persistence settings
+ * @return a new {@link EventListener} instance.
+ * @throws NullPointerException if the target or invokable is not set.
+ * @throws IllegalArgumentException if there is a mismatch between persistence settings.
*/
@NotNull
public EventListener build() {
@@ -150,7 +137,7 @@ public EventListener build() {
"Persistency missmatch. persistent=" + persistent + " and persists=" + persists + " is not allowed."
);
}
- return new EventListener<>(target, type, priority, persists) {
+ return new EventListener<>(target, priority, persists) {
@Override
public void invoke(T event) {
invokable.invoke(event);
diff --git a/src/main/test/dev/tori/wraith/Main.java b/src/main/test/dev/tori/wraith/Main.java
index 99fcf5b..82f22b8 100644
--- a/src/main/test/dev/tori/wraith/Main.java
+++ b/src/main/test/dev/tori/wraith/Main.java
@@ -21,9 +21,8 @@
package dev.tori.wraith;
-import dev.tori.wraith.event.targeted.IClassTargetingEvent;
-import dev.tori.wraith.listener.Listener;
-import org.jetbrains.annotations.Nullable;
+import dev.tori.wraith.event.Target;
+import dev.tori.wraith.listener.EventListener;
/**
* @author 7orivorian
@@ -32,39 +31,105 @@
public class Main {
public static void main(String[] args) {
+ /*Target target = Target.reverseCascade(null);
+ System.out.println(target.targets(ParentListenerOne.class));
+ System.out.println(target.targets(ParentListenerOne.NestedListenerOne.class));
+ System.out.println(target.targets(ParentListenerOne.NestedListenerOther.class));
+ System.out.println(target.targets(ParentListenerOne.NestedListenerOne.DoubleNestedListenerOne.class));
+
+ System.out.println(target.targets(ParentListenerTwo.class));
+ System.out.println(target.targets(ParentListenerTwo.NestedListenerTwo.class));*/
+
+ Target target = Target.cascade(Object.class);
+ System.out.println(target.targets(Event.class));
+
+/* final EventBus bus = new EventBus();
+ bus.subscribe(new Subscriber() {{
+ registerListeners(
+ new ParentListenerOne(),
+ new ParentListenerOne.NestedListenerOne(),
+ new ParentListenerOne.NestedListenerOne.DoubleNestedListenerOne(),
+ new ParentListenerOne.NestedListenerOther(),
+ new ParentListenerTwo(),
+ new ParentListenerTwo.NestedListenerTwo()
+ );
+ }});
+
+ Event event = new Event();
+ bus.dispatch(event);
+ System.out.println(event);
+
+ Event.NestedEvent nestedEvent = new Event.NestedEvent();
+ bus.dispatch(nestedEvent);
+ System.out.println(nestedEvent);*/
}
- public class Event implements IClassTargetingEvent {
+ static class ParentListenerOne extends EventListener {
- @Nullable
- private final Class extends Listener>> target;
+ public ParentListenerOne() {
+ super(Target.cascade(Event.class));
+ }
- public Event(@Nullable Class extends Listener>> target) {
- this.target = target;
+ @Override
+ public void invoke(Event event) {
+ event.mod();
+ }
+
+ static class NestedListenerOne extends ParentListenerOne {
+
+ static class DoubleNestedListenerOne extends NestedListenerOne {
+
+ }
+ }
+
+ static class NestedListenerOther extends EventListener {
+
+ public NestedListenerOther() {
+ super(Target.fine(Event.class));
+ }
+
+ @Override
+ public void invoke(Event event) {
+ event.mod();
+ }
+ }
+ }
+
+ static class ParentListenerTwo extends EventListener {
+
+ public ParentListenerTwo() {
+ super(Target.fine(Event.class));
}
- @Nullable
@Override
- public Class extends Listener>> getTargetClass() {
- return target;
+ public void invoke(Event event) {
+ event.mod();
+ }
+
+ static class NestedListenerTwo extends ParentListenerTwo {
+
}
}
- static final class MessageEvent {
+ static class Event {
- private String message;
+ private int mods = 0;
- public MessageEvent() {
- this.message = "nothing to say";
+ public void mod() {
+ this.mods++;
}
- public String getMessage() {
- return message;
+ @Override
+ public String toString() {
+ return "mods=" + mods;
}
- public void setMessage(String message) {
- this.message = message;
+ static class NestedEvent extends Event {
+
+ static class DoubleNestedEvent extends NestedEvent {
+
+ }
}
}
}
\ No newline at end of file
diff --git a/src/main/test/dev/tori/wraith/MainTwo.java b/src/main/test/dev/tori/wraith/MainTwo.java
new file mode 100644
index 0000000..712f180
--- /dev/null
+++ b/src/main/test/dev/tori/wraith/MainTwo.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package dev.tori.wraith;
+
+import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.Target;
+import dev.tori.wraith.event.targeted.ClassTargetingEvent;
+import dev.tori.wraith.listener.EventListener;
+import dev.tori.wraith.listener.Listener;
+import dev.tori.wraith.subscriber.Subscriber;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class MainTwo {
+
+ public static void main(String[] args) {
+ final EventBus bus = new EventBus();
+ bus.subscribe(new Subscriber() {{
+ registerListeners(
+ new ListenerOne(),
+ new ListenerTwo()
+ );
+ }});
+
+ TestEvent event = new TestEvent(null);
+
+ bus.dispatch(event);
+
+ System.out.println(event);
+ }
+
+ static class ListenerOne extends EventListener {
+
+ public ListenerOne() {
+ super(Target.fine(TestEvent.class));
+ }
+
+ @Override
+ public void invoke(TestEvent event) {
+ event.mod();
+ }
+ }
+
+ static class ListenerTwo extends EventListener {
+
+ public ListenerTwo() {
+ super(Target.fine(TestEvent.class));
+ }
+
+ @Override
+ public void invoke(TestEvent event) {
+ event.mod();
+ }
+ }
+
+ static class TestEvent extends ClassTargetingEvent {
+
+ private int mods = 0;
+
+ public TestEvent(Class extends Listener>> target) {
+ super(target);
+ }
+
+ public void mod() {
+ this.mods++;
+ }
+
+ @Override
+ public String toString() {
+ return "mods=" + mods;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java b/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
index 9b2ccf0..0f2511e 100644
--- a/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
+++ b/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
@@ -22,6 +22,7 @@
package dev.tori.wraith.benchmarking;
import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.listener.EventListener;
import dev.tori.wraith.subscriber.Subscriber;
import org.openjdk.jmh.annotations.*;
@@ -72,7 +73,7 @@ public MySubscriber() {
public static class MyListener extends EventListener {
public MyListener() {
- super(MyEvent.class);
+ super(Target.fine(MyEvent.class));
}
@Override
diff --git a/src/main/test/dev/tori/wraith/persistency/PersistencyTest.java b/src/main/test/dev/tori/wraith/persistency/PersistencyTest.java
index 13fefed..2513c07 100644
--- a/src/main/test/dev/tori/wraith/persistency/PersistencyTest.java
+++ b/src/main/test/dev/tori/wraith/persistency/PersistencyTest.java
@@ -22,6 +22,7 @@
package dev.tori.wraith.persistency;
import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.StatusEvent;
import dev.tori.wraith.listener.EventListener;
import dev.tori.wraith.subscriber.Subscriber;
@@ -65,7 +66,7 @@ public void testIndefiniteEvent() {
static class MyListener extends EventListener {
public MyListener(int persists) {
- super(MyEvent.class, null, 0, persists);
+ super(Target.fine(MyEvent.class), 0, persists);
}
@Override
diff --git a/src/main/test/dev/tori/wraith/priority/PriorityTest.java b/src/main/test/dev/tori/wraith/priority/PriorityTest.java
index 71efd95..52d1588 100644
--- a/src/main/test/dev/tori/wraith/priority/PriorityTest.java
+++ b/src/main/test/dev/tori/wraith/priority/PriorityTest.java
@@ -22,6 +22,7 @@
package dev.tori.wraith.priority;
import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.StatusEvent;
import dev.tori.wraith.listener.LambdaEventListener;
import dev.tori.wraith.subscriber.Subscriber;
@@ -38,15 +39,15 @@ public class PriorityTest {
public void testPriority() {
final EventBus bus = new EventBus();
bus.subscribe(new Subscriber() {{
- registerListener(new LambdaEventListener<>(MyEvent.class, 5, event -> event.setFlag(true)));
- registerListener(new LambdaEventListener<>(MyEvent.class, 4, event -> {
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 5, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 4, event -> {
event.setFlag(false);
event.terminate();
}));
- registerListener(new LambdaEventListener<>(MyEvent.class, 3, event -> event.setFlag(true)));
- registerListener(new LambdaEventListener<>(MyEvent.class, 2, event -> event.setFlag(true)));
- registerListener(new LambdaEventListener<>(MyEvent.class, 1, event -> event.setFlag(true)));
- registerListener(new LambdaEventListener<>(MyEvent.class, 0, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 3, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 2, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 1, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 0, event -> event.setFlag(true)));
}});
MyEvent event = new MyEvent();
diff --git a/src/main/test/dev/tori/wraith/registration/RegistrationTest.java b/src/main/test/dev/tori/wraith/registration/RegistrationTest.java
index 3f7bb1a..219bf42 100644
--- a/src/main/test/dev/tori/wraith/registration/RegistrationTest.java
+++ b/src/main/test/dev/tori/wraith/registration/RegistrationTest.java
@@ -22,6 +22,7 @@
package dev.tori.wraith.registration;
import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.IStatusEvent;
import dev.tori.wraith.event.status.StatusEvent;
import dev.tori.wraith.listener.LambdaEventListener;
@@ -38,8 +39,8 @@ public class RegistrationTest {
@Test
public void testResistration() {
final EventBus bus = new EventBus();
- final LambdaEventListener listener = new LambdaEventListener<>(
- StatusEvent.class,
+ final LambdaEventListener listener = new LambdaEventListener(
+ Target.fine(StatusEvent.class),
IStatusEvent::terminate
);
@@ -54,7 +55,7 @@ public void testResistration() {
public void testSubscription() {
final EventBus bus = new EventBus();
final Subscriber subscriber = new Subscriber() {{
- registerListener(new LambdaEventListener<>(StatusEvent.class, IStatusEvent::terminate));
+ registerListener(new LambdaEventListener(Target.fine(StatusEvent.class), IStatusEvent::terminate));
}};
bus.subscribe(subscriber);
@@ -73,7 +74,7 @@ public void testLateSubscription() {
bus.subscribe(subscriber);
- subscriber.registerListener(new LambdaEventListener<>(MyEvent.class, event -> event.setMessage(expectedMessage)));
+ subscriber.registerListener(new LambdaEventListener(Target.fine(MyEvent.class), event -> event.setMessage(expectedMessage)));
MyEvent event = new MyEvent(null);
bus.dispatch(event);
@@ -82,6 +83,7 @@ public void testLateSubscription() {
}
static final class MyEvent {
+
private String message;
MyEvent(String message) {
diff --git a/src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java b/src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java
index 0c1bb6c..55b0533 100644
--- a/src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java
+++ b/src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java
@@ -22,6 +22,7 @@
package dev.tori.wraith.statusevent;
import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.StatusEvent;
import dev.tori.wraith.listener.LambdaEventListener;
import dev.tori.wraith.subscriber.Subscriber;
@@ -40,11 +41,11 @@ public void testSupression() {
MySubscriber subscriber = new MySubscriber() {{
registerListeners(
- new LambdaEventListener<>(StatusEvent.class, 1, event -> {
+ new LambdaEventListener(Target.fine(StatusEvent.class), 1, event -> {
this.counter = 1;
event.suppress();
}),
- new LambdaEventListener<>(StatusEvent.class, 0, event -> {
+ new LambdaEventListener(Target.fine(StatusEvent.class), 0, event -> {
this.counter++;
})
);
@@ -61,11 +62,11 @@ public void testTermination() {
MySubscriber subscriber = new MySubscriber() {{
registerListeners(
- new LambdaEventListener<>(StatusEvent.class, 1, event -> {
+ new LambdaEventListener(Target.fine(StatusEvent.class), 1, event -> {
this.counter = 1;
event.terminate();
}),
- new LambdaEventListener<>(StatusEvent.class, 0, event -> {
+ new LambdaEventListener(Target.fine(StatusEvent.class), 0, event -> {
this.counter = 1_000;
})
);
diff --git a/src/main/test/dev/tori/wraith/targetedevent/TargetedEventTest.java b/src/main/test/dev/tori/wraith/targetedevent/TargetedEventTest.java
deleted file mode 100644
index 9dfe183..0000000
--- a/src/main/test/dev/tori/wraith/targetedevent/TargetedEventTest.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2021-2024 7orivorian.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package dev.tori.wraith.targetedevent;
-
-import dev.tori.wraith.bus.EventBus;
-import dev.tori.wraith.event.status.StatusEvent;
-import dev.tori.wraith.event.targeted.IClassTargetingEvent;
-import dev.tori.wraith.listener.EventListener;
-import dev.tori.wraith.listener.Listener;
-import dev.tori.wraith.subscriber.Subscriber;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * @author 7orivorian
- */
-public class TargetedEventTest {
-
- @Test
- public void testTargetedEventWithLowerPriority() {
- final EventBus bus = new EventBus();
-
- bus.subscribe(new Subscriber() {{
- registerListeners(
- new MyListener(0),
- new OtherListener(1)
- );
- }});
-
- TestEvent event = new TestEvent(MyListener.class);
- assertFalse(bus.dispatch(event));
- }
-
- @Test
- public void testTargetedEventWithHigherPriority() {
- final EventBus bus = new EventBus();
-
- bus.subscribe(new Subscriber() {{
- registerListeners(
- new MyListener(1),
- new OtherListener(0)
- );
- }});
-
- TestEvent event = new TestEvent(MyListener.class);
- assertFalse(bus.dispatch(event));
- }
-
- @Test
- public void testNestedClassTargetNestedListener() {
- final EventBus bus = new EventBus();
-
- bus.subscribe(new Subscriber() {{
- registerListeners(
- new MyParentListener.MyNestedListener(0)
- );
- }});
-
- TestEvent event = new TestEvent(MyParentListener.MyNestedListener.class);
- bus.dispatch(event);
-
- // Dispatched to nested target
- assertEquals(2, event.getValue());
- }
-
- @Test
- public void parentListenerNestedTarget() {
- final EventBus bus = new EventBus();
-
- bus.subscribe(new Subscriber() {{
- registerListeners(
- new MyParentListener(0)
- );
- }});
-
- TestEvent event = new TestEvent(MyParentListener.MyNestedListener.class);
- bus.dispatch(event);
-
- // Not dispatched to parent of nested target
- assertEquals(0, event.getValue());
- }
-
- @Test
- public void testParentOfNestedClassTarget() {
- final EventBus bus = new EventBus();
-
- bus.subscribe(new Subscriber() {{
- registerListeners(
- new MyParentListener.MyNestedListener(0)
- );
- }});
-
- TestEvent event = new TestEvent(MyParentListener.class);
- bus.dispatch(event);
-
- // Dispatched to nested listener if the parent is targeted
- assertEquals(2, event.getValue());
- }
-
- static class MyListener extends EventListener {
-
- public MyListener(int priority) {
- super(TestEvent.class, priority);
- }
-
- @Override
- public void invoke(TestEvent event) {
- event.setSuppressed(false);
- }
- }
-
- static class OtherListener extends EventListener {
-
- public OtherListener(int priority) {
- super(TestEvent.class, priority);
- }
-
- @Override
- public void invoke(TestEvent event) {
- event.suppress();
- }
- }
-
- static class MyParentListener extends EventListener {
-
- public MyParentListener(int priority) {
- super(TestEvent.class, priority);
- }
-
- @Override
- public void invoke(TestEvent event) {
- event.setValue(1);
- }
-
- static class MyNestedListener extends MyParentListener {
-
- public MyNestedListener(int priority) {
- super(priority);
- }
-
- @Override
- public void invoke(TestEvent event) {
- event.setValue(2);
- }
- }
- }
-
- static class TestEvent extends StatusEvent implements IClassTargetingEvent {
-
- private final Class extends Listener>> targetClass;
- private int value;
-
- public TestEvent(Class extends Listener>> target) {
- this.targetClass = target;
- this.value = 0;
- }
-
- @Override
- public Class extends Listener>> getTargetClass() {
- return targetClass;
- }
-
- public int getValue() {
- return value;
- }
-
- public void setValue(int value) {
- this.value = value;
- }
- }
-}
\ No newline at end of file
From 148350aa2c5c8e13dbd3b8aabf0edc657475ba94 Mon Sep 17 00:00:00 2001
From: Tori <7orivorian+github@gmail.com>
Date: Tue, 30 Jul 2024 22:04:25 -0400
Subject: [PATCH 16/30] Update IndexedHashSet
Signed-off-by: Tori <7orivorian+github@gmail.com>
---
.../java/dev/tori/wraith/util/IndexedHashSet.java | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/main/java/dev/tori/wraith/util/IndexedHashSet.java b/src/main/java/dev/tori/wraith/util/IndexedHashSet.java
index d8a5c09..0b34ae8 100644
--- a/src/main/java/dev/tori/wraith/util/IndexedHashSet.java
+++ b/src/main/java/dev/tori/wraith/util/IndexedHashSet.java
@@ -21,10 +21,10 @@
package dev.tori.wraith.util;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Objects;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
import java.util.function.Predicate;
/**
@@ -91,6 +91,7 @@ public boolean removeIf(Predicate super E> filter) {
}
@Override
+ @Contract(pure = true)
@SuppressWarnings("SuspiciousMethodCalls")
public boolean contains(Object element) {
return map.containsKey(element);
@@ -102,8 +103,8 @@ public void clear() {
map.clear();
}
- public ArrayList asList() {
- return new ArrayList<>(this);
+ public List immutableList() {
+ return Collections.unmodifiableList(this);
}
private void rangeCheckForAdd(int index) {
@@ -112,6 +113,8 @@ private void rangeCheckForAdd(int index) {
}
}
+ @NotNull
+ @Contract(pure = true)
private String outOfBoundsMsg(int index) {
return "Index: " + index + ", Size: " + size();
}
From cd9bb35cdf786c61a2b0a9249b14218a6eb40429 Mon Sep 17 00:00:00 2001
From: Tori <7orivorian+github@gmail.com>
Date: Tue, 30 Jul 2024 22:48:32 -0400
Subject: [PATCH 17/30] Update PersistenceTest
Signed-off-by: Tori <7orivorian+github@gmail.com>
---
...rsistencyTest.java => PersistenceTest.java} | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
rename src/main/test/dev/tori/wraith/persistency/{PersistencyTest.java => PersistenceTest.java} (85%)
diff --git a/src/main/test/dev/tori/wraith/persistency/PersistencyTest.java b/src/main/test/dev/tori/wraith/persistency/PersistenceTest.java
similarity index 85%
rename from src/main/test/dev/tori/wraith/persistency/PersistencyTest.java
rename to src/main/test/dev/tori/wraith/persistency/PersistenceTest.java
index 2513c07..696dd57 100644
--- a/src/main/test/dev/tori/wraith/persistency/PersistencyTest.java
+++ b/src/main/test/dev/tori/wraith/persistency/PersistenceTest.java
@@ -29,29 +29,33 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.util.concurrent.ThreadLocalRandom;
+
/**
* @author 7orivorian
* @since 3.2.0
*/
-public class PersistencyTest {
+public class PersistenceTest {
@Test
- public void testEventPersistency() {
+ public void testRandomPersistence() {
final EventBus bus = new EventBus();
+ final int persists = ThreadLocalRandom.current().nextInt(1, 101);
+
bus.subscribe(new Subscriber() {{
- registerListener(new MyListener(3));
+ registerListener(new MyListener(persists));
}});
- Assertions.assertTrue(bus.dispatch(new MyEvent()));
- Assertions.assertTrue(bus.dispatch(new MyEvent()));
- Assertions.assertTrue(bus.dispatch(new MyEvent()));
+ for (int i = 0; i < persists; i++) {
+ Assertions.assertTrue(bus.dispatch(new MyEvent()));
+ }
Assertions.assertFalse(bus.dispatch(new MyEvent()));
}
@Test
- public void testIndefiniteEvent() {
+ public void testIndefinitePersistence() {
final EventBus bus = new EventBus();
bus.subscribe(new Subscriber() {{
From 786cdeae74e6d9abd1635c2920d79cb3b230b39e Mon Sep 17 00:00:00 2001
From: Tori <7orivorian+github@gmail.com>
Date: Wed, 31 Jul 2024 00:31:12 -0400
Subject: [PATCH 18/30] Abstracted event bus implementations
Signed-off-by: Tori <7orivorian+github@gmail.com>
---
.../dev/tori/wraith/bus/AbstractEventBus.java | 342 ++++++++++++++++++
.../java/dev/tori/wraith/bus/EventBus.java | 269 +-------------
.../dev/tori/wraith/bus/OpenEventBus.java | 133 +++++++
.../java/dev/tori/wraith/event/Target.java | 96 +++--
.../dev/tori/wraith/listener/Listener.java | 12 +-
5 files changed, 552 insertions(+), 300 deletions(-)
create mode 100644 src/main/java/dev/tori/wraith/bus/AbstractEventBus.java
create mode 100644 src/main/java/dev/tori/wraith/bus/OpenEventBus.java
diff --git a/src/main/java/dev/tori/wraith/bus/AbstractEventBus.java b/src/main/java/dev/tori/wraith/bus/AbstractEventBus.java
new file mode 100644
index 0000000..1a326d5
--- /dev/null
+++ b/src/main/java/dev/tori/wraith/bus/AbstractEventBus.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2021-2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package dev.tori.wraith.bus;
+
+import dev.tori.wraith.event.Target;
+import dev.tori.wraith.event.status.IStatusEvent;
+import dev.tori.wraith.listener.Listener;
+import dev.tori.wraith.subscriber.ISubscriber;
+import dev.tori.wraith.task.ScheduledTask;
+import dev.tori.wraith.task.TaskExecutor;
+import dev.tori.wraith.util.IndexedHashSet;
+import org.jetbrains.annotations.Contract;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
+
+/**
+ * Abstract implementation of {@link IEventBus}.
+ *
+ * Manages subscription and task scheduling.
+ *
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public abstract class AbstractEventBus implements IEventBus {
+
+ /**
+ * The amount of {@linkplain AbstractEventBus} instances that have been created
+ */
+ private static int instances = 0;
+
+ /**
+ * This event bus's id
+ */
+ protected final int id;
+ /**
+ * Indicates whether this event bus is shutdown.
+ *
Shut-down event dispatchers cannot dispatch events, and throw {@link UnsupportedOperationException} when
+ * attempting to do so
+ */
+ protected boolean shutdown;
+ /**
+ * A {@link Set} of this event bus' {@link ISubscriber subscribers}
+ */
+ protected final Set subscribers;
+ /**
+ * A {@link TaskExecutor} that manages the scheduling and execution of tasks associated with events. It provides
+ * a mechanism to associate event classes with queues of tasks and ensures their orderly execution when the
+ * corresponding events are dispatched.
+ *
+ * @see #scheduleTask(ScheduledTask)
+ */
+ protected final TaskExecutor taskExecutor;
+
+ /**
+ * Creates a new event bus instance
+ */
+ public AbstractEventBus() {
+ this.id = instances++;
+ this.shutdown = false;
+ this.subscribers = Collections.newSetFromMap(new ConcurrentHashMap<>());
+ this.taskExecutor = new TaskExecutor();
+ }
+
+ /**
+ * @return The amount of {@linkplain AbstractEventBus} instances that have been created.
+ */
+ @Contract(pure = true)
+ public static int getInstanceCount() {
+ return instances;
+ }
+
+ /**
+ * Subscribes a {@link ISubscriber subscriber} to this event bus and registers all the
+ * subscriber's {@link Listener listeners}
+ *
+ * @param subscriber the {@link ISubscriber} to be subscribed
+ * @throws NullPointerException if the given {@link ISubscriber} is {@code null}
+ * @see #register(Listener)
+ */
+ @Override
+ public void subscribe(ISubscriber subscriber) {
+ Objects.requireNonNull(subscriber, "Cannot subscribe null to event bus " + id + "!");
+
+ subscribers.add(subscriber);
+ subscriber.linkToBus(this);
+
+ Collection> listeners = subscriber.getListeners();
+ if (!listeners.isEmpty()) {
+ if (listeners.size() == 1) {
+ register(listeners.iterator().next());
+ } else {
+ for (Listener> listener : listeners) {
+ register(listener);
+ }
+ }
+ }
+ }
+
+ /**
+ * Unsubscribes a {@link ISubscriber subscriber} from this event bus and unregisters all the
+ * subscriber's {@link Listener listeners}
+ *
+ * @param subscriber the {@link ISubscriber} to be unsubscribed
+ * @throws NullPointerException if the given {@link ISubscriber} is {@code null}
+ * @see #unregister(Listener)
+ */
+ @Override
+ public void unsubscribe(ISubscriber subscriber) {
+ Objects.requireNonNull(subscriber, "Cannot unsubscribe null from event bus " + id + "!");
+
+ subscribers.remove(subscriber);
+ subscriber.unlinkFromBus(this);
+
+ Collection> listeners = subscriber.getListeners();
+ if (!listeners.isEmpty()) {
+ if (listeners.size() == 1) {
+ unregister(listeners.iterator().next());
+ } else {
+ for (Listener> listener : listeners) {
+ unregister(listener);
+ }
+ }
+ }
+ }
+
+ /**
+ * Registers a {@link Listener listener} to this event bus
+ *
+ * @param listener the {@link Listener} to be registered
+ * @throws NullPointerException if the given {@link Listener} is {@code null}
+ */
+ @Override
+ public abstract void register(Listener> listener);
+
+ /**
+ * Unregisters a {@link Listener listener} from this event bus. A listener will no longer be invoked by events dispatched by this event bus
+ *
+ * @param listener the {@link Listener} to be unregistered
+ * @throws NullPointerException if the given {@link Listener} is {@code null}
+ */
+ @Override
+ public abstract void unregister(Listener> listener);
+
+ /**
+ * Convenience method to dispatch an event with no {@linkplain Target target listener}, and
+ * normal processing priority.
+ *
+ * @see #dispatch(Object, Target, boolean)
+ */
+ @Override
+ public boolean dispatch(Object event) {
+ return dispatch(event, Target.all(), false);
+ }
+
+ /**
+ * Convenience method to dispatch an event with an optional {@linkplain Target target listener} and
+ * normal processing priority.
+ *
+ * @see #dispatch(Object, Target, boolean)
+ */
+ @Override
+ public boolean dispatch(Object event, Target target) {
+ return dispatch(event, target, false);
+ }
+
+ /**
+ * Convenience method to dispatch an event with a universal {@linkplain Target target listener} and
+ * optional inverted processing priority.
+ *
+ * @see #dispatch(Object, Target, boolean)
+ */
+ @Override
+ public boolean dispatch(Object event, boolean invertPriority) {
+ return dispatch(event, Target.all(), invertPriority);
+ }
+
+ /**
+ * Dispatches the given event to all valid registered listeners.
+ *
+ * The {@code type} parameter serves as a filtering mechanism for listeners, enabling you to selectively invoke
+ * listeners based on their type, allowing for more targeted event handling.
+ *
+ * @param event the event to be dispatched.
+ * @param target the {@linkplain Target target listener} to invoke.
+ * @param invertPriority flag to dispatch the event in inverse listener priority.
+ * @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
+ * {@code false} otherwise.
+ * @throws NullPointerException if the given event is {@code null}
+ * @throws UnsupportedOperationException if this event bus is {@link #shutdown}
+ */
+ @Override
+ public abstract boolean dispatch(Object event, Target target, boolean invertPriority);
+
+ /**
+ * Schedules a task to be executed.
+ *
+ * @param task The task to be executed.
+ * @see TaskExecutor#schedule(ScheduledTask)
+ * @see ScheduledTask
+ */
+ public void scheduleTask(ScheduledTask task) {
+ taskExecutor.schedule(task);
+ }
+
+ /**
+ * Clears all tasks associated with events from the underlying {@link #taskExecutor}, effectively
+ * resetting the task scheduling within this {@link AbstractEventBus}.
+ *
+ * @see TaskExecutor#clear()
+ */
+ public void clearTaskExecutor() {
+ taskExecutor.clear();
+ }
+
+ /**
+ * Logs a warning message and shuts down this event bus, preventing future events from being dispatched.
+ *
+ * @implNote Shut-down event dispatchers cannot dispatch events, and throw {@link UnsupportedOperationException}
+ * when attempting to do so.
+ */
+ @Override
+ public void shutdown() {
+ shutdown = true;
+ }
+
+ /**
+ * @return {@code true} if this event bus is shut down
+ * @implNote Shut-down event dispatchers cannot dispatch events, and throw {@link UnsupportedOperationException}
+ * when attempting to do so.
+ */
+ @Override
+ public boolean isShutdown() {
+ return shutdown;
+ }
+
+ /**
+ * @return the {@code id} of this event bus
+ */
+ public int getId() {
+ return id;
+ }
+
+ /**
+ * Applies a given action to each {@linkplain Listener} in a list that matches a specified predicate.
+ * Listeners are processed either in normal order or in reverse order based on the
+ * {@code invertPriority} flag.
+ * Listeners that should not persist are removed from the list after the action is applied.
+ *
+ * @param event the event to be handled by each listener that satisfies the predicate
+ * @param listeners the list of listeners to be processed
+ * @param predicate the condition that each listener must satisfy to have the action applied
+ * @param invertPriority if {@code true}, listeners are processed in order of inverse priority; otherwise,
+ * they are processed in normal order
+ */
+ @SuppressWarnings("DuplicatedCode")
+ protected final void dispatchToEachListener(Object event, IndexedHashSet listeners, Predicate predicate, boolean invertPriority) {
+ if ((listeners != null) && !listeners.isEmpty()) {
+ if (invertPriority) {
+ for (int i = listeners.size() - 1; i >= 0; i--) {
+ Listener listener = listeners.get(i);
+ if (!predicate.test(listener)) {
+ continue;
+ }
+ listener.invoke(event);
+ if ((event instanceof IStatusEvent e) && e.isTerminated()) {
+ break;
+ }
+ if (!listener.shouldPersist()) {
+ listeners.remove(listener);
+ }
+ }
+ } else {
+ for (int i = 0; i < listeners.size(); i++) {
+ Listener listener = listeners.get(i);
+ if (!predicate.test(listener)) {
+ continue;
+ }
+ listener.invoke(event);
+ if ((event instanceof IStatusEvent e) && e.isTerminated()) {
+ break;
+ }
+ if (!listener.shouldPersist()) {
+ listeners.remove(listener);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if this event bus is equal to another object.
+ *
+ * If the given object is an event bus, it is only considered equal if {@code this.id == that.id}.
+ *
+ * @param o the object to compare with
+ * @return {@code true} if the object is equal to this event bus, {@code false} otherwise
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if ((o == null) || (getClass() != o.getClass())) {
+ return false;
+ }
+ AbstractEventBus that = (AbstractEventBus) o;
+ return id == that.id;
+ }
+
+ @Override
+ public int hashCode() {
+ return id;
+ }
+
+ @Override
+ public abstract String toString();
+}
\ No newline at end of file
diff --git a/src/main/java/dev/tori/wraith/bus/EventBus.java b/src/main/java/dev/tori/wraith/bus/EventBus.java
index 3ff1cb5..fba09b6 100644
--- a/src/main/java/dev/tori/wraith/bus/EventBus.java
+++ b/src/main/java/dev/tori/wraith/bus/EventBus.java
@@ -24,129 +24,33 @@
import dev.tori.wraith.event.Target;
import dev.tori.wraith.event.status.IStatusEvent;
import dev.tori.wraith.listener.Listener;
-import dev.tori.wraith.subscriber.ISubscriber;
-import dev.tori.wraith.task.ScheduledTask;
-import dev.tori.wraith.task.TaskExecutor;
import dev.tori.wraith.util.IndexedHashSet;
-import org.jetbrains.annotations.NotNull;
-import java.util.*;
+import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Predicate;
/**
- * Default implementation of {@link IEventBus}.
+ * An implementation of {@link AbstractEventBus}.
*
- * Manages subscription, listener registration, and event dispatching.
+ * Manages listener registration, event dispatching, and task execution.
*
* @author 7orivorian
* @since 1.0.0
*/
-@SuppressWarnings({"rawtypes", "unchecked"})
-public class EventBus implements IEventBus {
+@SuppressWarnings("rawtypes")
+public class EventBus extends AbstractEventBus {
/**
- * The amount of {@linkplain EventBus} instances that have been created
- */
- private static int instances = 0;
-
- /**
- * This event bus's id
- */
- private final int id;
- /**
- * Indicates whether this event bus is shutdown.
- *
Shut-down event dispatchers cannot dispatch events, and throw {@link UnsupportedOperationException} when
- * attempting to do so
- */
- private boolean shutdown;
- /**
- * A {@link Set} of this event bus' {@link ISubscriber subscribers}
- */
- private final Set subscribers;
- /**
- * A {@link ConcurrentHashMap} of this event bus' {@link Listener listeners}
+ * A {@link ConcurrentHashMap} of {@link Listener listeners} registered to this event bus.
*/
private final ConcurrentHashMap, IndexedHashSet> listeners;
- /**
- * A {@link TaskExecutor} that manages the scheduling and execution of tasks associated with events. It provides
- * a mechanism to associate event classes with queues of tasks and ensures their orderly execution when the
- * corresponding events are dispatched.
- *
- * @see #scheduleTask(ScheduledTask)
- */
- private final TaskExecutor taskExecutor;
/**
* Creates a new event bus instance
*/
public EventBus() {
- this.id = instances++;
- this.shutdown = false;
- this.subscribers = Collections.newSetFromMap(new ConcurrentHashMap<>());
+ super();
this.listeners = new ConcurrentHashMap<>();
- this.taskExecutor = new TaskExecutor();
- }
-
- /**
- * @return The amount of {@linkplain EventBus} instances that have been created.
- */
- public static int getInstanceCount() {
- return instances;
- }
-
- /**
- * Subscribes a {@link ISubscriber subscriber} to this event bus and registers all the
- * subscriber's {@link Listener listeners}
- *
- * @param subscriber the {@link ISubscriber} to be subscribed
- * @throws NullPointerException if the given {@link ISubscriber} is {@code null}
- * @see #register(Listener)
- */
- @Override
- public void subscribe(ISubscriber subscriber) {
- Objects.requireNonNull(subscriber, "Cannot subscribe null to event bus " + id + "!");
-
- subscribers.add(subscriber);
- subscriber.linkToBus(this);
-
- Collection> listeners = subscriber.getListeners();
- if (!listeners.isEmpty()) {
- if (listeners.size() == 1) {
- register(listeners.iterator().next());
- } else {
- for (Listener> listener : listeners) {
- register(listener);
- }
- }
- }
- }
-
- /**
- * Unsubscribes a {@link ISubscriber subscriber} from this event bus and unregisters all the
- * subscriber's {@link Listener listeners}
- *
- * @param subscriber the {@link ISubscriber} to be unsubscribed
- * @throws NullPointerException if the given {@link ISubscriber} is {@code null}
- * @see #unregister(Listener)
- */
- @Override
- public void unsubscribe(ISubscriber subscriber) {
- Objects.requireNonNull(subscriber, "Cannot unsubscribe null from event bus " + id + "!");
-
- subscribers.remove(subscriber);
- subscriber.unlinkFromBus(this);
-
- Collection> listeners = subscriber.getListeners();
- if (!listeners.isEmpty()) {
- if (listeners.size() == 1) {
- unregister(listeners.iterator().next());
- } else {
- for (Listener> listener : listeners) {
- unregister(listener);
- }
- }
- }
}
/**
@@ -182,42 +86,6 @@ public void unregister(Listener> listener) {
listeners.get(listener.getTarget().clazz()).removeIf(l -> l.equals(listener));
}
- /**
- * Convenience method to dispatch an event with no {@linkplain Target target listener}, and
- * normal processing priority.
- *
- * @see #dispatch(Object, Target, boolean)
- * @since 3.3.0
- */
- @Override
- public boolean dispatch(Object event) {
- return dispatch(event, Target.none(), false);
- }
-
- /**
- * Convenience method to dispatch an event with an optional {@linkplain Target target listener} and
- * normal processing priority.
- *
- * @see #dispatch(Object, Target, boolean)
- * @since 4.0.0
- */
- @Override
- public boolean dispatch(Object event, Target target) {
- return dispatch(event, target, false);
- }
-
- /**
- * Convenience method to dispatch an event with no {@linkplain Target target listener}, and
- * optional inverted processing priority.
- *
- * @see #dispatch(Object, Target, boolean)
- * @since 4.0.0
- */
- @Override
- public boolean dispatch(Object event, boolean invertPriority) {
- return dispatch(event, Target.none(), invertPriority);
- }
-
/**
* Dispatches the given event to all valid registered listeners.
*
@@ -256,129 +124,6 @@ public boolean dispatch(Object event, Target target, boolean invertPriority) {
return false;
}
- /**
- * Schedules a task to be executed.
- *
- * @param task The task to be executed.
- * @see TaskExecutor#schedule(ScheduledTask)
- * @see ScheduledTask
- */
- public void scheduleTask(ScheduledTask task) {
- taskExecutor.schedule(task);
- }
-
- /**
- * Clears all tasks associated with events from the underlying {@link #taskExecutor}, effectively
- * resetting the task scheduling within this {@link EventBus}.
- *
- * @see TaskExecutor#clear()
- */
- public void clearTaskExecutor() {
- taskExecutor.clear();
- }
-
- /**
- * Logs a warning message and shuts down this event bus, preventing future events from being dispatched.
- *
- * @implNote Shut-down event dispatchers cannot dispatch events, and throw {@link UnsupportedOperationException}
- * when attempting to do so.
- */
- @Override
- public void shutdown() {
- shutdown = true;
- }
-
- /**
- * @return {@code true} if this event bus is shut down
- * @implNote Shut-down event dispatchers cannot dispatch events, and throw {@link UnsupportedOperationException}
- * when attempting to do so.
- */
- @Override
- public boolean isShutdown() {
- return shutdown;
- }
-
- /**
- * @return the {@code id} of this event bus
- * @since 3.1.0
- */
- public int getId() {
- return id;
- }
-
- /**
- * Applies a given action to each {@linkplain Listener} in a list that matches a specified predicate.
- * Listeners are processed either in normal order or in reverse order based on the
- * {@code invertPriority} flag.
- * Listeners that should not persist are removed from the list after the action is applied.
- *
- * @param event the event to be handled by each listener that satisfies the predicate
- * @param listeners the list of listeners to be processed
- * @param predicate the condition that each listener must satisfy to have the action applied
- * @param invertPriority if {@code true}, listeners are processed in order of inverse priority; otherwise,
- * they are processed in normal order
- * @since 3.2.0
- */
- @SuppressWarnings("DuplicatedCode")
- private void dispatchToEachListener(Object event, IndexedHashSet listeners, Predicate predicate, boolean invertPriority) {
- if ((listeners != null) && !listeners.isEmpty()) {
- final ArrayList li = listeners.asList();
- if (invertPriority) {
- for (int i = li.size() - 1; i >= 0; i--) {
- Listener listener = li.get(i);
- if (!predicate.test(listener)) {
- continue;
- }
- listener.invoke(event);
- if ((event instanceof IStatusEvent e) && e.isTerminated()) {
- break;
- }
- if (!listener.shouldPersist()) {
- listeners.remove(listener);
- }
- }
- } else {
- for (Listener listener : li) {
- if (!predicate.test(listener)) {
- continue;
- }
- listener.invoke(event);
- if ((event instanceof IStatusEvent e) && e.isTerminated()) {
- break;
- }
- if (!listener.shouldPersist()) {
- listeners.remove(listener);
- }
- }
- }
- }
- }
-
- /**
- * Checks if this event bus is equal to another object.
- *
- * If the given object is an event bus, it is only considered equal if {@code this.id == that.id}.
- *
- * @param o the object to compare with
- * @return {@code true} if the object is equal to this event bus, {@code false} otherwise
- */
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if ((o == null) || (getClass() != o.getClass())) {
- return false;
- }
- EventBus that = (EventBus) o;
- return id == that.id;
- }
-
- @Override
- public int hashCode() {
- return id;
- }
-
@Override
public String toString() {
return "EventBus{" +
diff --git a/src/main/java/dev/tori/wraith/bus/OpenEventBus.java b/src/main/java/dev/tori/wraith/bus/OpenEventBus.java
new file mode 100644
index 0000000..c1bfd8e
--- /dev/null
+++ b/src/main/java/dev/tori/wraith/bus/OpenEventBus.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2021-2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package dev.tori.wraith.bus;
+
+import dev.tori.wraith.event.Target;
+import dev.tori.wraith.event.status.IStatusEvent;
+import dev.tori.wraith.listener.Listener;
+import dev.tori.wraith.util.IndexedHashSet;
+
+import java.util.Comparator;
+import java.util.Objects;
+
+/**
+ * An implementation of {@link AbstractEventBus}.
+ *
+ * Manages listener registration, event dispatching, and task execution.
+ *
+ * @author 7orivorian
+ * @since 1.0.0
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class OpenEventBus extends AbstractEventBus {
+
+ /**
+ * An {@link IndexedHashSet} of {@link Listener listeners} registered to this event bus.
+ */
+ private final IndexedHashSet listeners;
+
+ /**
+ * Creates a new event bus instance
+ */
+ public OpenEventBus() {
+ super();
+ this.listeners = new IndexedHashSet<>();
+ }
+
+ /**
+ * Registers a {@link Listener listener} to this event bus
+ *
+ * @param listener the {@link Listener} to be registered
+ * @throws NullPointerException if the given {@link Listener} is {@code null}
+ */
+ @Override
+ public void register(Listener> listener) {
+ Objects.requireNonNull(listener, "Cannot register null listener to event bus " + id + "!");
+
+ listeners.add(listener);
+ listeners.sort(Comparator.naturalOrder());
+ }
+
+ /**
+ * Unregisters a {@link Listener listener} from this event bus. A listener will no longer be invoked by events dispatched by this event bus
+ *
+ * @param listener the {@link Listener} to be unregistered
+ * @throws NullPointerException if the given {@link Listener} is {@code null}
+ */
+ @Override
+ public void unregister(Listener> listener) {
+ Objects.requireNonNull(listener, "Cannot unregister null listener from event bus " + id + "!");
+ listeners.removeIf(l -> l.equals(listener));
+ }
+
+ /**
+ * Dispatches the given event to all valid registered listeners.
+ *
+ * The {@code type} parameter serves as a filtering mechanism for listeners, enabling you to selectively invoke
+ * listeners based on their type, allowing for more targeted event handling.
+ *
+ * @param event the event to be dispatched.
+ * @param target the {@linkplain Target target listener} to invoke.
+ * @param invertPriority flag to dispatch the event in inverse listener priority.
+ * @return {@code true} if the given event is {@linkplain IStatusEvent suppressed or terminated} by any listener,
+ * {@code false} otherwise.
+ * @throws NullPointerException if the given event is {@code null}
+ * @throws UnsupportedOperationException if this event bus is {@link #shutdown}
+ * @since 4.0.0
+ */
+ @Override
+ public boolean dispatch(Object event, Target target, boolean invertPriority) {
+ Objects.requireNonNull(event, "Cannot dispatch a null event to event bus " + id + "!");
+ Objects.requireNonNull(target, "Cannot dispatch an event with a null target to event bus " + id + "!");
+ if (isShutdown()) {
+ throw new UnsupportedOperationException("Event bus " + id + " is shutdown!");
+ } else {
+ taskExecutor.onEvent(event);
+
+ dispatchToEachListener(
+ event,
+ listeners,
+ listener -> target.targets(listener.getClass()) && listener.getTarget().targets(event.getClass()),
+ invertPriority
+ );
+
+ if (event instanceof IStatusEvent e) {
+ return e.isSuppressed() || e.isTerminated();
+ }
+ }
+ return false;
+ }
+
+ public IndexedHashSet getListeners() {
+ return listeners;
+ }
+
+ @Override
+ public String toString() {
+ return "EventBus{" +
+ "id=" + id +
+ ", shutdown=" + shutdown +
+ ", subscribers=" + subscribers +
+ ", listeners=" + listeners +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/dev/tori/wraith/event/Target.java b/src/main/java/dev/tori/wraith/event/Target.java
index 7daad3e..1c9a799 100644
--- a/src/main/java/dev/tori/wraith/event/Target.java
+++ b/src/main/java/dev/tori/wraith/event/Target.java
@@ -23,7 +23,6 @@
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.Objects;
@@ -36,7 +35,7 @@
*/
public class Target {
- @Nullable
+ @NotNull
private final Class> clazz;
@NotNull
private final TargetingRule rule;
@@ -48,52 +47,52 @@ public class Target {
* @param rule the targeting rule.
*/
@Contract(pure = true)
- private Target(@Nullable Class> clazz, @NotNull TargetingRule rule) {
+ private Target(@NotNull Class> clazz, @NotNull TargetingRule rule) {
this.clazz = clazz;
this.rule = rule;
}
/**
- * Returns a {@code ClassTarget} with no specific target.
+ * Returns a {@link Target} that matches any class.
*
- * @return a {@code ClassTarget} with no specific target.
+ * @return a {@link Target} that matches any class.
*/
@NotNull
- public static Target none() {
- return new Target(null, TargetingRule.FINE);
+ public static Target all() {
+ return new Target(Object.class, TargetingRule.CASCADE);
}
/**
- * Returns a {@code ClassTarget} with the specified target and {@link TargetingRule#FINE FINE} targeting.
+ * Returns a {@link Target} with the specified target and {@link TargetingRule#FINE FINE} targeting.
*
- * @param target the target class.
- * @return a {@code ClassTarget} with the specified target and {@link TargetingRule#FINE FINE} targeting.
+ * @param clazz the target class.
+ * @return a {@link Target} with the specified target and {@link TargetingRule#FINE FINE} targeting.
*/
@NotNull
- public static Target fine(@Nullable Class> target) {
- return new Target(target, TargetingRule.FINE);
+ public static Target fine(@NotNull Class> clazz) {
+ return new Target(clazz, TargetingRule.FINE);
}
/**
- * Returns a {@code ClassTarget} with the specified target and {@link TargetingRule#CASCADE CASCADE} targeting.
+ * Returns a {@link Target} with the specified target and {@link TargetingRule#CASCADE CASCADE} targeting.
*
- * @param target the target class.
- * @return a {@code ClassTarget} with the specified target and {@link TargetingRule#CASCADE CASCADE} targeting.
+ * @param clazz the target class.
+ * @return a {@link Target} with the specified target and {@link TargetingRule#CASCADE CASCADE} targeting.
*/
@NotNull
- public static Target cascade(@Nullable Class> target) {
- return new Target(target, TargetingRule.CASCADE);
+ public static Target cascade(@NotNull Class> clazz) {
+ return new Target(clazz, TargetingRule.CASCADE);
}
/**
- * Returns a {@code ClassTarget} with the specified target and {@link TargetingRule#REVERSE_CASCADE REVERSE_CASCADE} targeting.
+ * Returns a {@link Target} with the specified target and {@link TargetingRule#REVERSE_CASCADE REVERSE_CASCADE} targeting.
*
- * @param target the target class.
- * @return a {@code ClassTarget} with the specified target and {@link TargetingRule#REVERSE_CASCADE REVERSE_CASCADE} targeting.
+ * @param clazz the target class.
+ * @return a {@link Target} with the specified target and {@link TargetingRule#REVERSE_CASCADE REVERSE_CASCADE} targeting.
*/
@NotNull
- public static Target reverseCascade(@Nullable Class> target) {
- return new Target(target, TargetingRule.REVERSE_CASCADE);
+ public static Target reverseCascade(@NotNull Class> clazz) {
+ return new Target(clazz, TargetingRule.REVERSE_CASCADE);
}
/**
@@ -103,37 +102,60 @@ public static Target reverseCascade(@Nullable Class> target) {
* @return {@code true} if the class matches the target, {@code false} otherwise.
*/
public boolean targets(@NotNull Class> clazz) {
- if (this.clazz == null) {
- return true; // Null target class will target anything
+ if (this.clazz == Object.class) {
+ //System.out.println(clazz);
+ return true;
}
- return rule.isMatch(clazz, this.clazz);
+ //System.out.println(clazz);
+ return rule.classesMatch(clazz, this.clazz);
}
/**
- * Returns the target class.
+ * Returns the {@linkplain #clazz target class}.
*
- * @return the target class, {@code null} if no target is set.
+ * @return the {@linkplain #clazz target class}.
*/
- @Nullable
+ @NotNull
public Class> clazz() {
return clazz;
}
/**
- * Returns the targeting rule.
+ * Returns the {@linkplain #rule targeting rule}.
*
- * @return the targeting rule.
+ * @return the {@linkplain #rule targeting rule}.
*/
@NotNull
public TargetingRule rule() {
return rule;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if ((obj == null) || (getClass() != obj.getClass())) {
+ return false;
+ }
+
+ Target target = (Target) obj;
+ return clazz.equals(target.clazz)
+ && (rule == target.rule);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = clazz.hashCode();
+ result = (31 * result) + rule.hashCode();
+ return result;
+ }
+
@Override
public String toString() {
- return "ClassTarget{" +
- "target=" + clazz +
- ", matching=" + rule +
+ return "Target{" +
+ "clazz=" + clazz +
+ ", rule=" + rule +
'}';
}
@@ -146,7 +168,7 @@ public enum TargetingRule {
*/
FINE {
@Override
- public boolean isMatch(Class> clazz, Class> target) {
+ public boolean classesMatch(Class> clazz, Class> target) {
return Objects.equals(clazz, target);
}
},
@@ -155,7 +177,7 @@ public boolean isMatch(Class> clazz, Class> target) {
*/
CASCADE {
@Override
- public boolean isMatch(Class> clazz, Class> target) {
+ public boolean classesMatch(Class> clazz, Class> target) {
return target.isAssignableFrom(clazz);
}
},
@@ -164,11 +186,11 @@ public boolean isMatch(Class> clazz, Class> target) {
*/
REVERSE_CASCADE {
@Override
- public boolean isMatch(Class> clazz, Class> target) {
+ public boolean classesMatch(Class> clazz, Class> target) {
return clazz.isAssignableFrom(target);
}
};
- public abstract boolean isMatch(Class> clazz, Class> target);
+ public abstract boolean classesMatch(Class> clazz, Class> target);
}
}
\ No newline at end of file
diff --git a/src/main/java/dev/tori/wraith/listener/Listener.java b/src/main/java/dev/tori/wraith/listener/Listener.java
index c9b8fc8..b9b6a33 100644
--- a/src/main/java/dev/tori/wraith/listener/Listener.java
+++ b/src/main/java/dev/tori/wraith/listener/Listener.java
@@ -37,7 +37,7 @@
* @see Invokable
* @since 1.0.0
*/
-public interface Listener extends Invokable {
+public interface Listener extends Invokable, Comparable> {
int DEFAULT_PERSISTENCE = 0;
@@ -78,4 +78,14 @@ default boolean shouldPersist() {
default boolean hasIndefinitePersistence() {
return true;
}
+
+ /**
+ * @param listener the listener to be compared.
+ * @apiNote This class has a natural ordering that is inconsistent with equals.
+ * @since 4.0.0
+ */
+ @Override
+ default int compareTo(@NotNull Listener listener) {
+ return listener.getPriority() - getPriority();
+ }
}
\ No newline at end of file
From 6c4aaf1b6f8867d919741485139bde8a6109fc1d Mon Sep 17 00:00:00 2001
From: Tori <7orivorian+github@gmail.com>
Date: Wed, 31 Jul 2024 00:31:52 -0400
Subject: [PATCH 19/30] Duplicate unit tests for all event bus implementations
Signed-off-by: Tori <7orivorian+github@gmail.com>
---
.../persistency/PersistenceTest.java | 2 +-
.../{ => eventbus}/priority/PriorityTest.java | 2 +-
.../registration/RegistrationTest.java | 2 +-
.../statusevent/StatusEventTest.java | 2 +-
.../persistency/PersistenceTest.java} | 79 ++++++--------
.../openeventbus/priority/PriorityTest.java | 74 +++++++++++++
.../registration/RegistrationTest.java | 101 ++++++++++++++++++
.../statusevent/StatusEventTest.java | 90 ++++++++++++++++
8 files changed, 304 insertions(+), 48 deletions(-)
rename src/main/test/dev/tori/wraith/{ => eventbus}/persistency/PersistenceTest.java (98%)
rename src/main/test/dev/tori/wraith/{ => eventbus}/priority/PriorityTest.java (98%)
rename src/main/test/dev/tori/wraith/{ => eventbus}/registration/RegistrationTest.java (98%)
rename src/main/test/dev/tori/wraith/{ => eventbus}/statusevent/StatusEventTest.java (98%)
rename src/main/test/dev/tori/wraith/{MainTwo.java => openeventbus/persistency/PersistenceTest.java} (50%)
create mode 100644 src/main/test/dev/tori/wraith/openeventbus/priority/PriorityTest.java
create mode 100644 src/main/test/dev/tori/wraith/openeventbus/registration/RegistrationTest.java
create mode 100644 src/main/test/dev/tori/wraith/openeventbus/statusevent/StatusEventTest.java
diff --git a/src/main/test/dev/tori/wraith/persistency/PersistenceTest.java b/src/main/test/dev/tori/wraith/eventbus/persistency/PersistenceTest.java
similarity index 98%
rename from src/main/test/dev/tori/wraith/persistency/PersistenceTest.java
rename to src/main/test/dev/tori/wraith/eventbus/persistency/PersistenceTest.java
index 696dd57..c8b1157 100644
--- a/src/main/test/dev/tori/wraith/persistency/PersistenceTest.java
+++ b/src/main/test/dev/tori/wraith/eventbus/persistency/PersistenceTest.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package dev.tori.wraith.persistency;
+package dev.tori.wraith.eventbus.persistency;
import dev.tori.wraith.bus.EventBus;
import dev.tori.wraith.event.Target;
diff --git a/src/main/test/dev/tori/wraith/priority/PriorityTest.java b/src/main/test/dev/tori/wraith/eventbus/priority/PriorityTest.java
similarity index 98%
rename from src/main/test/dev/tori/wraith/priority/PriorityTest.java
rename to src/main/test/dev/tori/wraith/eventbus/priority/PriorityTest.java
index 52d1588..e881eb8 100644
--- a/src/main/test/dev/tori/wraith/priority/PriorityTest.java
+++ b/src/main/test/dev/tori/wraith/eventbus/priority/PriorityTest.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package dev.tori.wraith.priority;
+package dev.tori.wraith.eventbus.priority;
import dev.tori.wraith.bus.EventBus;
import dev.tori.wraith.event.Target;
diff --git a/src/main/test/dev/tori/wraith/registration/RegistrationTest.java b/src/main/test/dev/tori/wraith/eventbus/registration/RegistrationTest.java
similarity index 98%
rename from src/main/test/dev/tori/wraith/registration/RegistrationTest.java
rename to src/main/test/dev/tori/wraith/eventbus/registration/RegistrationTest.java
index 219bf42..41f89c4 100644
--- a/src/main/test/dev/tori/wraith/registration/RegistrationTest.java
+++ b/src/main/test/dev/tori/wraith/eventbus/registration/RegistrationTest.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package dev.tori.wraith.registration;
+package dev.tori.wraith.eventbus.registration;
import dev.tori.wraith.bus.EventBus;
import dev.tori.wraith.event.Target;
diff --git a/src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java b/src/main/test/dev/tori/wraith/eventbus/statusevent/StatusEventTest.java
similarity index 98%
rename from src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java
rename to src/main/test/dev/tori/wraith/eventbus/statusevent/StatusEventTest.java
index 55b0533..d9e4620 100644
--- a/src/main/test/dev/tori/wraith/statusevent/StatusEventTest.java
+++ b/src/main/test/dev/tori/wraith/eventbus/statusevent/StatusEventTest.java
@@ -19,7 +19,7 @@
* THE SOFTWARE.
*/
-package dev.tori.wraith.statusevent;
+package dev.tori.wraith.eventbus.statusevent;
import dev.tori.wraith.bus.EventBus;
import dev.tori.wraith.event.Target;
diff --git a/src/main/test/dev/tori/wraith/MainTwo.java b/src/main/test/dev/tori/wraith/openeventbus/persistency/PersistenceTest.java
similarity index 50%
rename from src/main/test/dev/tori/wraith/MainTwo.java
rename to src/main/test/dev/tori/wraith/openeventbus/persistency/PersistenceTest.java
index 712f180..46cff95 100644
--- a/src/main/test/dev/tori/wraith/MainTwo.java
+++ b/src/main/test/dev/tori/wraith/openeventbus/persistency/PersistenceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024 7orivorian.
+ * Copyright (c) 2021-2024 7orivorian.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -19,76 +19,67 @@
* THE SOFTWARE.
*/
-package dev.tori.wraith;
+package dev.tori.wraith.openeventbus.persistency;
-import dev.tori.wraith.bus.EventBus;
+import dev.tori.wraith.bus.OpenEventBus;
import dev.tori.wraith.event.Target;
-import dev.tori.wraith.event.targeted.ClassTargetingEvent;
+import dev.tori.wraith.event.status.StatusEvent;
import dev.tori.wraith.listener.EventListener;
-import dev.tori.wraith.listener.Listener;
import dev.tori.wraith.subscriber.Subscriber;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.ThreadLocalRandom;
/**
* @author 7orivorian
- * @since 4.0.0
+ * @since 3.2.0
*/
-public class MainTwo {
+public class PersistenceTest {
+
+ @Test
+ public void testRandomPersistence() {
+ final OpenEventBus bus = new OpenEventBus();
+
+ final int persists = ThreadLocalRandom.current().nextInt(1, 101);
- public static void main(String[] args) {
- final EventBus bus = new EventBus();
bus.subscribe(new Subscriber() {{
- registerListeners(
- new ListenerOne(),
- new ListenerTwo()
- );
+ registerListener(new MyListener(persists));
}});
- TestEvent event = new TestEvent(null);
-
- bus.dispatch(event);
+ for (int i = 0; i < persists; i++) {
+ Assertions.assertTrue(bus.dispatch(new MyEvent()));
+ }
- System.out.println(event);
+ Assertions.assertFalse(bus.dispatch(new MyEvent()));
}
- static class ListenerOne extends EventListener {
+ @Test
+ public void testIndefinitePersistence() {
+ final OpenEventBus bus = new OpenEventBus();
- public ListenerOne() {
- super(Target.fine(TestEvent.class));
- }
+ bus.subscribe(new Subscriber() {{
+ registerListener(new MyListener(0)); // <= 0 means persist indefinitely
+ }});
- @Override
- public void invoke(TestEvent event) {
- event.mod();
+ for (int i = 0; i < 1_000; i++) {
+ Assertions.assertTrue(bus.dispatch(new MyEvent()));
}
}
- static class ListenerTwo extends EventListener {
+ static class MyListener extends EventListener {
- public ListenerTwo() {
- super(Target.fine(TestEvent.class));
+ public MyListener(int persists) {
+ super(Target.fine(MyEvent.class), 0, persists);
}
@Override
- public void invoke(TestEvent event) {
- event.mod();
+ public void invoke(MyEvent event) {
+ event.suppress();
}
}
- static class TestEvent extends ClassTargetingEvent {
-
- private int mods = 0;
-
- public TestEvent(Class extends Listener>> target) {
- super(target);
- }
-
- public void mod() {
- this.mods++;
- }
+ static class MyEvent extends StatusEvent {
- @Override
- public String toString() {
- return "mods=" + mods;
- }
}
}
\ No newline at end of file
diff --git a/src/main/test/dev/tori/wraith/openeventbus/priority/PriorityTest.java b/src/main/test/dev/tori/wraith/openeventbus/priority/PriorityTest.java
new file mode 100644
index 0000000..482fcbd
--- /dev/null
+++ b/src/main/test/dev/tori/wraith/openeventbus/priority/PriorityTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package dev.tori.wraith.openeventbus.priority;
+
+import dev.tori.wraith.bus.OpenEventBus;
+import dev.tori.wraith.event.Target;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class PriorityTest {
+
+ @Test
+ public void testPriority() {
+ final OpenEventBus bus = new OpenEventBus();
+ bus.subscribe(new Subscriber() {{
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 5, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 4, event -> {
+ event.setFlag(false);
+ event.terminate();
+ }));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 3, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 2, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 1, event -> event.setFlag(true)));
+ registerListener(new LambdaEventListener(Target.fine(MyEvent.class), 0, event -> event.setFlag(true)));
+ }});
+
+ MyEvent event = new MyEvent();
+ Assertions.assertTrue(bus.dispatch(event));
+ Assertions.assertFalse(event.flag());
+ }
+
+ static class MyEvent extends StatusEvent {
+
+ private boolean flag;
+
+ MyEvent() {
+ this.flag = true;
+ }
+
+ public boolean flag() {
+ return flag;
+ }
+
+ public void setFlag(boolean flag) {
+ this.flag = flag;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/test/dev/tori/wraith/openeventbus/registration/RegistrationTest.java b/src/main/test/dev/tori/wraith/openeventbus/registration/RegistrationTest.java
new file mode 100644
index 0000000..eb1c164
--- /dev/null
+++ b/src/main/test/dev/tori/wraith/openeventbus/registration/RegistrationTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package dev.tori.wraith.openeventbus.registration;
+
+import dev.tori.wraith.bus.OpenEventBus;
+import dev.tori.wraith.event.Target;
+import dev.tori.wraith.event.status.IStatusEvent;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author 7orivorian
+ * @since 4.0.0
+ */
+public class RegistrationTest {
+
+ @Test
+ public void testResistration() {
+ final OpenEventBus bus = new OpenEventBus();
+ final LambdaEventListener listener = new LambdaEventListener(
+ Target.fine(StatusEvent.class),
+ IStatusEvent::terminate
+ );
+
+ bus.register(listener);
+ Assertions.assertTrue(bus.dispatch(new StatusEvent()));
+
+ bus.unregister(listener);
+ Assertions.assertFalse(bus.dispatch(new StatusEvent()));
+ }
+
+ @Test
+ public void testSubscription() {
+ final OpenEventBus bus = new OpenEventBus();
+ final Subscriber subscriber = new Subscriber() {{
+ registerListener(new LambdaEventListener(Target.fine(StatusEvent.class), IStatusEvent::terminate));
+ }};
+
+ bus.subscribe(subscriber);
+ Assertions.assertTrue(bus.dispatch(new StatusEvent()));
+
+ bus.unsubscribe(subscriber);
+ Assertions.assertFalse(bus.dispatch(new StatusEvent()));
+ }
+
+ @Test
+ public void testLateSubscription() {
+ final String expectedMessage = "Hello world!";
+
+ final OpenEventBus bus = new OpenEventBus();
+ final Subscriber subscriber = new Subscriber();
+
+ bus.subscribe(subscriber);
+
+ subscriber.registerListener(new LambdaEventListener(Target.fine(MyEvent.class), event -> event.setMessage(expectedMessage)));
+
+ MyEvent event = new MyEvent(null);
+ bus.dispatch(event);
+
+ Assertions.assertEquals(expectedMessage, event.message());
+ }
+
+ static final class MyEvent {
+
+ private String message;
+
+ MyEvent(String message) {
+ this.message = message;
+ }
+
+ public String message() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/test/dev/tori/wraith/openeventbus/statusevent/StatusEventTest.java b/src/main/test/dev/tori/wraith/openeventbus/statusevent/StatusEventTest.java
new file mode 100644
index 0000000..e334445
--- /dev/null
+++ b/src/main/test/dev/tori/wraith/openeventbus/statusevent/StatusEventTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2024 7orivorian.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package dev.tori.wraith.openeventbus.statusevent;
+
+import dev.tori.wraith.bus.OpenEventBus;
+import dev.tori.wraith.event.Target;
+import dev.tori.wraith.event.status.StatusEvent;
+import dev.tori.wraith.listener.LambdaEventListener;
+import dev.tori.wraith.subscriber.Subscriber;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author 7orivorian
+ * @since 3.2.0
+ */
+public class StatusEventTest {
+
+ @Test
+ public void testSupression() {
+ final OpenEventBus bus = new OpenEventBus();
+
+ MySubscriber subscriber = new MySubscriber() {{
+ registerListeners(
+ new LambdaEventListener(Target.fine(StatusEvent.class), 1, event -> {
+ this.counter = 1;
+ event.suppress();
+ }),
+ new LambdaEventListener(Target.fine(StatusEvent.class), 0, event -> {
+ this.counter++;
+ })
+ );
+ }};
+ bus.subscribe(subscriber);
+
+ Assertions.assertEquals(2, bus.getListeners().size());
+
+ Assertions.assertTrue(bus.dispatch(new StatusEvent()));
+ Assertions.assertEquals(2, subscriber.counter);
+ }
+
+ @Test
+ public void testTermination() {
+ final OpenEventBus bus = new OpenEventBus();
+
+ MySubscriber subscriber = new MySubscriber() {{
+ registerListeners(
+ new LambdaEventListener(Target.fine(StatusEvent.class), 1, event -> {
+ this.counter = 1;
+ event.terminate();
+ }),
+ new LambdaEventListener(Target.fine(StatusEvent.class), 0, event -> {
+ this.counter = 1_000;
+ })
+ );
+ }};
+ bus.subscribe(subscriber);
+
+ Assertions.assertTrue(bus.dispatch(new StatusEvent()));
+ Assertions.assertEquals(1, subscriber.counter);
+ }
+
+ private static class MySubscriber extends Subscriber {
+
+ public int counter = 0;
+
+ public MySubscriber() {
+
+ }
+ }
+}
\ No newline at end of file
From 20412d1b30a802e33408639dcfabd36cc5f7b359 Mon Sep 17 00:00:00 2001
From: Tori <7orivorian+github@gmail.com>
Date: Wed, 31 Jul 2024 00:32:20 -0400
Subject: [PATCH 20/30] Refactor IndexedHashSetTest unit test
Signed-off-by: Tori <7orivorian+github@gmail.com>
---
src/main/test/dev/tori/wraith/util/IndexedHashSetTest.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/main/test/dev/tori/wraith/util/IndexedHashSetTest.java b/src/main/test/dev/tori/wraith/util/IndexedHashSetTest.java
index 1882998..9fec4cc 100644
--- a/src/main/test/dev/tori/wraith/util/IndexedHashSetTest.java
+++ b/src/main/test/dev/tori/wraith/util/IndexedHashSetTest.java
@@ -21,7 +21,6 @@
package dev.tori.wraith.util;
-import dev.tori.wraith.util.IndexedHashSet;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
From d39f915ceb840c46c091b77dd7bc7b7845d38be0 Mon Sep 17 00:00:00 2001
From: Tori <7orivorian+github@gmail.com>
Date: Wed, 31 Jul 2024 00:32:45 -0400
Subject: [PATCH 21/30] Update MyBenchmark
Signed-off-by: Tori <7orivorian+github@gmail.com>
---
.../tori/wraith/benchmarking/MyBenchmark.java | 72 ++++---------------
1 file changed, 12 insertions(+), 60 deletions(-)
diff --git a/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java b/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
index 0f2511e..73abcac 100644
--- a/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
+++ b/src/main/test/dev/tori/wraith/benchmarking/MyBenchmark.java
@@ -24,7 +24,6 @@
import dev.tori.wraith.bus.EventBus;
import dev.tori.wraith.event.Target;
import dev.tori.wraith.listener.EventListener;
-import dev.tori.wraith.subscriber.Subscriber;
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;
@@ -33,80 +32,33 @@
* @author 7orivorian
* @since 3.2.0
*/
+@State(Scope.Thread)
public class MyBenchmark {
@State(Scope.Thread)
public static class BenchmarkState {
- MyListener myListener;
- MySubscriber mySubscriber;
+ EventListener