🐛 fix race-condition
This commit is contained in:
@@ -7,11 +7,11 @@ plugins {
|
|||||||
id("java-library")
|
id("java-library")
|
||||||
|
|
||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
id("me.champeau.jmh") version "0.7.2"
|
id("me.champeau.jmh") version "0.7.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "cc.lunary"
|
group = "cc.lunary"
|
||||||
version = "1.1.1-release"
|
version = "1.2.0-release"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
@@ -62,12 +62,12 @@ dependencies {
|
|||||||
java {
|
java {
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
toolchain.languageVersion = JavaLanguageVersion.of(JavaVersion.VERSION_17.toString())
|
toolchain.languageVersion = JavaLanguageVersion.of(JavaVersion.VERSION_21.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<JavaCompile> {
|
tasks.withType<JavaCompile> {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17.toString()
|
sourceCompatibility = JavaVersion.VERSION_21.toString()
|
||||||
targetCompatibility = JavaVersion.VERSION_17.toString()
|
targetCompatibility = JavaVersion.VERSION_21.toString()
|
||||||
options.encoding = StandardCharsets.UTF_8.toString()
|
options.encoding = StandardCharsets.UTF_8.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ publishing {
|
|||||||
|
|
||||||
pom {
|
pom {
|
||||||
name.set("Lilith")
|
name.set("Lilith")
|
||||||
description.set("A blazingly fast, easy-to-use Java-17 event system.")
|
description.set("A blazingly fast, easy-to-use Java-21 event system.")
|
||||||
|
|
||||||
url.set("https://github.com/lunarydess/Library-Lilith-JVM")
|
url.set("https://github.com/lunarydess/Library-Lilith-JVM")
|
||||||
packaging = "jar"
|
packaging = "jar"
|
||||||
@@ -110,11 +110,11 @@ publishing {
|
|||||||
name.set("Lucielle R. H.")
|
name.set("Lucielle R. H.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
issueManagement { url = "https://github.com/lunarydess/Library-TinyEvents/issues" }
|
issueManagement { url = "https://git.celesteflare.cc/i0uring/lib_tinyevents/issues" }
|
||||||
scm {
|
scm {
|
||||||
connection = "scm:git:git://github.com/lunarydess/Library-TinyEvents.git"
|
connection = "scm:git:git://git.celesteflare.cc/i0uring/lib_tinyevents.git"
|
||||||
developerConnection = "scm:git:ssh://github.com/lunarydess/Library-TinyEvents.git"
|
developerConnection = "scm:git:ssh://git.celesteflare.cc/i0uring/lib_tinyevents.git"
|
||||||
url = "github.com/lunarydess/Library-TinyEvents"
|
url = "git.celesteflare.cc/i0uring/lib_tinyevents"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
org.gradle.java.home=/usr/lib/jvm/openjdk21
|
||||||
# gradle tweaks
|
# gradle tweaks
|
||||||
org.gradle.daemon = true
|
org.gradle.daemon = true
|
||||||
org.gradle.configureondemand = true
|
org.gradle.configureondemand = true
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* This file is part of <a href="https://github.com/lunarydess/Library-TinyEvents">TinyEvents</a>
|
* This file is part of <a href="https://git.celesteflare.cc/i0uring/lib_tinyevents">TinyEvents</a>
|
||||||
* Copyright (C) 2024 lunarydess (inbox@luzey.zip)
|
* Copyright (C) 2024 lucielle (inbox@celesteflare.cc)
|
||||||
* <p>
|
* <p>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package cc.lunary.tinyevents;
|
package io.lucielle.tinyevents;
|
||||||
|
|
||||||
import org.openjdk.jmh.annotations.*;
|
import org.openjdk.jmh.annotations.*;
|
||||||
import org.openjdk.jmh.infra.Blackhole;
|
import org.openjdk.jmh.infra.Blackhole;
|
||||||
@@ -47,7 +47,7 @@ public class BenchmarkCaller implements BenchmarkListener {
|
|||||||
@Fork(value = 1, warmups = 1)
|
@Fork(value = 1, warmups = 1)
|
||||||
public void callBenchmarkListener(Blackhole blackhole) {
|
public void callBenchmarkListener(Blackhole blackhole) {
|
||||||
for (int i = 0; i < ITERATIONS; i++) {
|
for (int i = 0; i < ITERATIONS; i++) {
|
||||||
EVENTS.call(new BenchmarkListener.BenchmarkEvent(blackhole));
|
EVENTS.call0(new BenchmarkListener.BenchmarkEvent(blackhole));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* This file is part of <a href="https://github.com/lunarydess/Library-TinyEvents">TinyEvents</a>
|
* This file is part of <a href="https://git.celesteflare.cc/i0uring/lib_tinyevents">TinyEvents</a>
|
||||||
* Copyright (C) 2024 lunarydess (inbox@luzey.zip)
|
* Copyright (C) 2024 lucielle (inbox@celesteflare.cc)
|
||||||
* <p>
|
* <p>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,10 +14,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package cc.lunary.tinyevents;
|
package io.lucielle.tinyevents;
|
||||||
|
|
||||||
import cc.lunary.tinyevents.BenchmarkListener.BenchmarkEvent;
|
import io.lucielle.tinyevents.BenchmarkListener.BenchmarkEvent;
|
||||||
import cc.lunary.tinyevents.EventHandlers.IHandler;
|
import io.lucielle.tinyevents.EventHandlers.IHandler;
|
||||||
import org.openjdk.jmh.infra.Blackhole;
|
import org.openjdk.jmh.infra.Blackhole;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -63,8 +63,8 @@ public interface BenchmarkListener extends IHandler<BenchmarkEvent> {
|
|||||||
|
|
||||||
public @Override String toString() {
|
public @Override String toString() {
|
||||||
return "BenchmarkEvent{" +
|
return "BenchmarkEvent{" +
|
||||||
"blackhole=" + blackhole +
|
"blackhole=" + blackhole +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* This file is part of <a href="https://github.com/lunarydess/Library-TinyEvents">TinyEvents</a>
|
* This file is part of <a href="https://git.celesteflare.cc/i0uring/lib_tinyevents">TinyEvents</a>
|
||||||
* Copyright (C) 2024 lunarydess (inbox@luzey.zip)
|
* Copyright (C) 2024 lucielle (inbox@celesteflare.cc)
|
||||||
* <p>
|
* <p>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package cc.lunary.tinyevents;
|
package io.lucielle.tinyevents;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The abstraction layer for all events.
|
* The abstraction layer for all events.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* This file is part of <a href="https://github.com/lunarydess/Library-TinyEvents">TinyEvents</a>
|
* This file is part of <a href="https://git.celesteflare.cc/i0uring/lib_tinyevents">TinyEvents</a>
|
||||||
* Copyright (C) 2024 lunarydess (inbox@luzey.zip)
|
* Copyright (C) 2024 lucielle (inbox@celesteflare.cc)
|
||||||
* <p>
|
* <p>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package cc.lunary.tinyevents;
|
package io.lucielle.tinyevents;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -29,14 +29,16 @@ import java.util.function.Consumer;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class EventHandlers {
|
public final class EventHandlers {
|
||||||
/**
|
/**
|
||||||
* This is an abstraction layer for a consumer-handlers to implement our own handle-logic for events.
|
* This is an abstraction layer for a consumer-handlers to implement our own
|
||||||
|
* handle-logic for events.
|
||||||
*
|
*
|
||||||
* @param <E> The event-type of our handler.
|
* @param <E> The event-type of our handler.
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface IHandler<E extends AbstractEvent> extends Consumer<E>, Comparable<IHandler<E>> {
|
public interface IHandler<E extends AbstractEvent> extends Consumer<E>, Comparable<IHandler<E>> {
|
||||||
/**
|
/**
|
||||||
* Handles our incoming events when {@link TinyEvents#call(AbstractEvent)} gets called.
|
* Handles our incoming events when {@link TinyEvents#call(AbstractEvent)} gets
|
||||||
|
* called.
|
||||||
*
|
*
|
||||||
* @param event The event we want to implement the logic for.
|
* @param event The event we want to implement the logic for.
|
||||||
*/
|
*/
|
||||||
@@ -63,13 +65,15 @@ public final class EventHandlers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an abstraction layer for class-handlers to implement our own handle-logic for events.
|
* This is an abstraction layer for class-handlers to implement our own
|
||||||
|
* handle-logic for events.
|
||||||
*
|
*
|
||||||
* @param <E> The event-type of our handler.
|
* @param <E> The event-type of our handler.
|
||||||
*/
|
*/
|
||||||
public abstract static class AbstractHandler<E extends AbstractEvent> implements IHandler<E> {
|
public abstract static class AbstractHandler<E extends AbstractEvent> implements IHandler<E> {
|
||||||
/**
|
/**
|
||||||
* Handles our incoming events when {@link TinyEvents#call(AbstractEvent)} gets called.
|
* Handles our incoming events when {@link TinyEvents#call(AbstractEvent)} gets
|
||||||
|
* called.
|
||||||
*
|
*
|
||||||
* @param event The event we want to implement the logic for.
|
* @param event The event we want to implement the logic for.
|
||||||
*/
|
*/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* This file is part of <a href="https://github.com/lunarydess/Library-TinyEvents">TinyEvents</a>
|
* This file is part of <a href="https://git.celesteflare.cc/i0uring/lib_tinyevents">TinyEvents</a>
|
||||||
* Copyright (C) 2024 lunarydess (inbox@luzey.zip)
|
* Copyright (C) 2024 lucielle (inbox@celesteflare.cc)
|
||||||
* <p>
|
* <p>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,11 +14,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package cc.lunary.tinyevents;
|
package io.lucielle.tinyevents;
|
||||||
|
|
||||||
import cc.lunary.tinyevents.EventHandlers.IHandler;
|
import io.lucielle.tinyevents.EventHandlers.IHandler;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@@ -39,37 +40,37 @@ public final class TinyEvents {
|
|||||||
private final Map<Class<? extends AbstractEvent>, IHandler<? extends AbstractEvent>[]> handlers;
|
private final Map<Class<? extends AbstractEvent>, IHandler<? extends AbstractEvent>[]> handlers;
|
||||||
private final Object2IntMap<IHandler<? extends AbstractEvent>> handlersIndices = new Object2IntMap<>();
|
private final Object2IntMap<IHandler<? extends AbstractEvent>> handlersIndices = new Object2IntMap<>();
|
||||||
|
|
||||||
|
final transient Object lock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new event-manager with a default {@link IdentityHashMap map} and {@link TinyEvents#DEFAULT_ON_ERROR error-handler}.
|
* Creates a new event-manager with a default {@link IdentityHashMap map} and
|
||||||
|
* {@link TinyEvents#DEFAULT_ON_ERROR error-handler}.
|
||||||
*/
|
*/
|
||||||
public TinyEvents() {
|
public TinyEvents() {
|
||||||
this(IdentityHashMap::new, DEFAULT_ON_ERROR);
|
this(IdentityHashMap::new, DEFAULT_ON_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new event-manager with a custom {@link Supplier<Map> map} and default {@link TinyEvents#DEFAULT_ON_ERROR error-handler}.
|
* Creates a new event-manager with a custom {@link Supplier<Map> map} and
|
||||||
|
* default {@link TinyEvents#DEFAULT_ON_ERROR error-handler}.
|
||||||
*
|
*
|
||||||
* @param factory The custom map we want to provide.
|
* @param factory The custom map we want to provide.
|
||||||
*/
|
*/
|
||||||
public TinyEvents(
|
public TinyEvents(
|
||||||
final Supplier<Map<Class<? extends AbstractEvent>,
|
final Supplier<Map<Class<? extends AbstractEvent>, IHandler<? extends AbstractEvent>[]>> factory) {
|
||||||
IHandler<? extends AbstractEvent>[]
|
|
||||||
>> factory
|
|
||||||
) {
|
|
||||||
this(factory, DEFAULT_ON_ERROR);
|
this(factory, DEFAULT_ON_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new event-manager with a custom {@link Supplier<Map> map} and {@link Consumer<Throwable> error-handler}.
|
* Creates a new event-manager with a custom {@link Supplier<Map> map} and
|
||||||
|
* {@link Consumer<Throwable> error-handler}.
|
||||||
*
|
*
|
||||||
* @param factory The custom map we want to provide.
|
* @param factory The custom map we want to provide.
|
||||||
* @param onError The custom error-handler we want to provide.
|
* @param onError The custom error-handler we want to provide.
|
||||||
*/
|
*/
|
||||||
public TinyEvents(
|
public TinyEvents(
|
||||||
final Supplier<Map<Class<? extends AbstractEvent>, IHandler<? extends AbstractEvent>[]>> factory,
|
final Supplier<Map<Class<? extends AbstractEvent>, IHandler<? extends AbstractEvent>[]>> factory,
|
||||||
final Consumer<Throwable> onError
|
final Consumer<Throwable> onError) {
|
||||||
) {
|
|
||||||
this.handlers = factory.get();
|
this.handlers = factory.get();
|
||||||
this.onError = onError;
|
this.onError = onError;
|
||||||
}
|
}
|
||||||
@@ -81,20 +82,19 @@ public final class TinyEvents {
|
|||||||
* @param <E> The type of the event for our handler.
|
* @param <E> The type of the event for our handler.
|
||||||
*/
|
*/
|
||||||
public <H extends EventHandlers.IHandler<E>, E extends AbstractEvent> void register(
|
public <H extends EventHandlers.IHandler<E>, E extends AbstractEvent> void register(
|
||||||
final Class<E> clazz,
|
final Class<E> clazz,
|
||||||
final H handler
|
final H handler) {
|
||||||
) {
|
synchronized (this.lock) {
|
||||||
try {
|
|
||||||
final IHandler<? extends AbstractEvent>[] current = this.handlers.getOrDefault(clazz, new IHandler<?>[0]);
|
final IHandler<? extends AbstractEvent>[] current = this.handlers.getOrDefault(clazz, new IHandler<?>[0]);
|
||||||
final IHandler<? extends AbstractEvent>[] updated = Arrays.copyOf(current, current.length + 1);
|
final IHandler<? extends AbstractEvent>[] updated = Arrays.copyOf(current, current.length + 1);
|
||||||
updated[updated.length - 1] = handler;
|
updated[updated.length - 1] = handler;
|
||||||
|
|
||||||
final Comparator<IHandler<? extends AbstractEvent>> sort = Comparator.comparingInt(wrapper1 -> handler.priority());
|
final Comparator<IHandler<? extends AbstractEvent>> sort = Comparator
|
||||||
|
.comparingInt(wrapper1 -> handler.priority());
|
||||||
Arrays.sort(updated, sort);
|
Arrays.sort(updated, sort);
|
||||||
|
|
||||||
this.handlers.put(clazz, updated);
|
this.handlers.put(clazz, updated);
|
||||||
this.handlersIndices.put(handler, Arrays.binarySearch(updated, handler, sort));
|
this.handlersIndices.put(handler, Arrays.binarySearch(updated, handler, sort));
|
||||||
} catch (final Throwable throwable) {
|
|
||||||
onError.accept(throwable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,32 +105,30 @@ public final class TinyEvents {
|
|||||||
* @param <E> The type of the event for our handler.
|
* @param <E> The type of the event for our handler.
|
||||||
*/
|
*/
|
||||||
public <H extends EventHandlers.IHandler<E>, E extends AbstractEvent> void unregister(
|
public <H extends EventHandlers.IHandler<E>, E extends AbstractEvent> void unregister(
|
||||||
final Class<E> clazz,
|
final Class<E> clazz,
|
||||||
final H handler
|
final H handler) {
|
||||||
) {
|
synchronized (this.lock) {
|
||||||
final IHandler<? extends AbstractEvent>[] current = this.handlers.getOrDefault(clazz, new IHandler<?>[0]);
|
final IHandler<? extends AbstractEvent>[] current = this.handlers.getOrDefault(clazz, new IHandler<?>[0]);
|
||||||
|
|
||||||
if (current.length == 0) {
|
if (current.length == 0) {
|
||||||
this.handlers.remove(clazz);
|
this.handlers.remove(clazz);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = this.handlersIndices.get(handler);
|
||||||
|
if (index < 0 || index > current.length - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final IHandler<? extends AbstractEvent>[] updated = new IHandler<?>[current.length - 1];
|
||||||
|
if (updated.length > 0) {
|
||||||
|
System.arraycopy(current, 0, updated, 0, index);
|
||||||
|
System.arraycopy(current, index + 1, updated, index, current.length - index - 1);
|
||||||
|
this.handlers.put(clazz, updated);
|
||||||
|
} else
|
||||||
|
this.handlers.remove(clazz);
|
||||||
|
this.handlersIndices.remove(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = this.handlersIndices.get(handler);
|
|
||||||
if (index < 0 || index > current.length - 1) {
|
|
||||||
this.onError.accept(new NoSuchFieldError(String.format(
|
|
||||||
"The handler %s doesn't exist.",
|
|
||||||
handler.toString()
|
|
||||||
)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final IHandler<? extends AbstractEvent>[] updated = new IHandler<?>[current.length - 1];
|
|
||||||
if (updated.length > 0) {
|
|
||||||
System.arraycopy(current, 0, updated, 0, index);
|
|
||||||
System.arraycopy(current, index + 1, updated, index, current.length - index - 1);
|
|
||||||
this.handlers.put(clazz, updated);
|
|
||||||
} else this.handlers.remove(clazz);
|
|
||||||
this.handlersIndices.remove(handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,7 +138,16 @@ public final class TinyEvents {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <E extends AbstractEvent> void call(final E event) {
|
public <E extends AbstractEvent> void call(final E event) {
|
||||||
final IHandler<E>[] handlers = (IHandler<E>[]) this.handlers.get(event.getClass());
|
final IHandler<E>[] handlers = (IHandler<E>[]) this.handlers.get(event.getClass());
|
||||||
if (handlers == null) return;
|
|
||||||
|
if (handlers == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this.onError == null) {
|
||||||
|
for (final IHandler<E> handler : handlers)
|
||||||
|
handler.accept(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (final IHandler<E> handler : handlers) {
|
for (final IHandler<E> handler : handlers) {
|
||||||
try {
|
try {
|
||||||
handler.accept(event);
|
handler.accept(event);
|
||||||
@@ -150,6 +157,21 @@ public final class TinyEvents {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param event The event we want to call.
|
||||||
|
* @param <E> The type of our event.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <E extends AbstractEvent> void call0(final E event) {
|
||||||
|
final IHandler<E>[] handlers = (IHandler<E>[]) this.handlers.get(event.getClass());
|
||||||
|
|
||||||
|
if (handlers == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (final IHandler<E> handler : handlers)
|
||||||
|
handler.accept(event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the internal error-handler
|
* @return the internal error-handler
|
||||||
* @see TinyEvents#call(AbstractEvent)
|
* @see TinyEvents#call(AbstractEvent)
|
||||||
@@ -186,7 +208,6 @@ public final class TinyEvents {
|
|||||||
return this.handlersIndices;
|
return this.handlersIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param <K> The object-type we want to use.
|
* @param <K> The object-type we want to use.
|
||||||
*/
|
*/
|
||||||
@@ -199,7 +220,8 @@ public final class TinyEvents {
|
|||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link Object2IntMap<K> map} with a {@link Object2IntMap#INITIAL_CAPACITY initial capacity}.
|
* Creates a {@link Object2IntMap<K> map} with a
|
||||||
|
* {@link Object2IntMap#INITIAL_CAPACITY initial capacity}.
|
||||||
*/
|
*/
|
||||||
public Object2IntMap() {
|
public Object2IntMap() {
|
||||||
this(INITIAL_CAPACITY);
|
this(INITIAL_CAPACITY);
|
||||||
@@ -220,14 +242,14 @@ public final class TinyEvents {
|
|||||||
* @param value The int-value we want to add.
|
* @param value The int-value we want to add.
|
||||||
*/
|
*/
|
||||||
public void put(
|
public void put(
|
||||||
final K key,
|
final K key,
|
||||||
final int value
|
final int value) {
|
||||||
) {
|
|
||||||
if (size >= table.length * LOAD_FACTOR) {
|
if (size >= table.length * LOAD_FACTOR) {
|
||||||
int newCapacity = table.length * 2;
|
int newCapacity = table.length * 2;
|
||||||
LinkedList<Entry<K>>[] newTable = new LinkedList[newCapacity];
|
LinkedList<Entry<K>>[] newTable = new LinkedList[newCapacity];
|
||||||
for (LinkedList<Entry<K>> entries : table) {
|
for (LinkedList<Entry<K>> entries : table) {
|
||||||
if (entries == null) continue;
|
if (entries == null)
|
||||||
|
continue;
|
||||||
for (Entry<K> entry : entries) {
|
for (Entry<K> entry : entries) {
|
||||||
int index = hash(entry.key) & (newCapacity - 1);
|
int index = hash(entry.key) & (newCapacity - 1);
|
||||||
(newTable[index] == null ? (newTable[index] = new LinkedList<>()) : newTable[index]).add(entry);
|
(newTable[index] == null ? (newTable[index] = new LinkedList<>()) : newTable[index]).add(entry);
|
||||||
@@ -259,10 +281,12 @@ public final class TinyEvents {
|
|||||||
*/
|
*/
|
||||||
public int get(K key) {
|
public int get(K key) {
|
||||||
int index = hash(key) & (table.length - 1);
|
int index = hash(key) & (table.length - 1);
|
||||||
if (table[index] == null) return -1;
|
if (table[index] == null)
|
||||||
|
return -1;
|
||||||
|
|
||||||
for (Entry<K> entry : table[index]) {
|
for (Entry<K> entry : table[index]) {
|
||||||
if (!Objects.equals(entry.key, key)) continue;
|
if (!Objects.equals(entry.key, key))
|
||||||
|
continue;
|
||||||
return entry.value;
|
return entry.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,9 +330,8 @@ public final class TinyEvents {
|
|||||||
* @param value The value of our entry.
|
* @param value The value of our entry.
|
||||||
*/
|
*/
|
||||||
Entry(
|
Entry(
|
||||||
final K key,
|
final K key,
|
||||||
final int value
|
final int value) {
|
||||||
) {
|
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* This file is part of <a href="https://github.com/lunarydess/Library-TinyEvents">TinyEvents</a>
|
* This file is part of <a href="https://git.celesteflare.cc/i0uring/lib_tinyevents">TinyEvents</a>
|
||||||
* Copyright (C) 2024 lunarydess (inbox@luzey.zip)
|
* Copyright (C) 2024 lucielle (inbox@celesteflare.cc)
|
||||||
* <p>
|
* <p>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,13 +14,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package cc.lunary.tinyevents;
|
package io.lucielle.tinyevents;
|
||||||
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestInstance;
|
import org.junit.jupiter.api.TestInstance;
|
||||||
import cc.lunary.tinyevents.AbstractEvent.Cancellable;
|
import io.lucielle.tinyevents.AbstractEvent.Cancellable;
|
||||||
import cc.lunary.tinyevents.EventHandlers.IHandler;
|
import io.lucielle.tinyevents.EventHandlers.IHandler;
|
||||||
|
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -63,7 +63,8 @@ class TestTinyEvents {
|
|||||||
assertEquals(2, events.getHandlers().size());
|
assertEquals(2, events.getHandlers().size());
|
||||||
|
|
||||||
IHandler<DummyEvent3> handler3 = event -> {
|
IHandler<DummyEvent3> handler3 = event -> {
|
||||||
if (event.cancelled()) return;
|
if (event.cancelled())
|
||||||
|
return;
|
||||||
String string1 = event.getString1(), string2 = event.getString2();
|
String string1 = event.getString1(), string2 = event.getString2();
|
||||||
|
|
||||||
event.setString1(string2);
|
event.setString1(string2);
|
||||||
@@ -74,7 +75,8 @@ class TestTinyEvents {
|
|||||||
assertEquals(3, events.getHandlers().size());
|
assertEquals(3, events.getHandlers().size());
|
||||||
|
|
||||||
IHandler<DummyEvent4> handler4 = event -> {
|
IHandler<DummyEvent4> handler4 = event -> {
|
||||||
if (event.cancelled()) return;
|
if (event.cancelled())
|
||||||
|
return;
|
||||||
int num1 = event.getNum1(), num2 = event.getNum2();
|
int num1 = event.getNum1(), num2 = event.getNum2();
|
||||||
|
|
||||||
event.setNum1(num2);
|
event.setNum1(num2);
|
||||||
@@ -85,26 +87,21 @@ class TestTinyEvents {
|
|||||||
assertEquals(4, events.getHandlers().size());
|
assertEquals(4, events.getHandlers().size());
|
||||||
|
|
||||||
DummyEvent1 event1 = new DummyEvent1(
|
DummyEvent1 event1 = new DummyEvent1(
|
||||||
"waow",
|
"waow",
|
||||||
"hellow there"
|
"hellow there");
|
||||||
);
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"waow",
|
"waow",
|
||||||
event1.getString1()
|
event1.getString1());
|
||||||
);
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"hellow there",
|
"hellow there",
|
||||||
event1.getString2()
|
event1.getString2());
|
||||||
);
|
|
||||||
handler1.accept(event1);
|
handler1.accept(event1);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"how are y'all doing",
|
"how are y'all doing",
|
||||||
event1.getString1()
|
event1.getString1());
|
||||||
);
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"hope y'all keep going :)",
|
"hope y'all keep going :)",
|
||||||
event1.getString2()
|
event1.getString2());
|
||||||
);
|
|
||||||
|
|
||||||
DummyEvent2 event2 = new DummyEvent2(1337, 9090);
|
DummyEvent2 event2 = new DummyEvent2(1337, 9090);
|
||||||
assertEquals(1337, event2.getNum1());
|
assertEquals(1337, event2.getNum1());
|
||||||
@@ -114,37 +111,30 @@ class TestTinyEvents {
|
|||||||
assertEquals(1337, event2.getNum2());
|
assertEquals(1337, event2.getNum2());
|
||||||
|
|
||||||
DummyEvent3 event3 = new DummyEvent3(
|
DummyEvent3 event3 = new DummyEvent3(
|
||||||
"i'm doing fine curr",
|
"i'm doing fine curr",
|
||||||
"just wishing it stays like this ;w;"
|
"just wishing it stays like this ;w;");
|
||||||
);
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"i'm doing fine curr",
|
"i'm doing fine curr",
|
||||||
event3.getString1()
|
event3.getString1());
|
||||||
);
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"just wishing it stays like this ;w;",
|
"just wishing it stays like this ;w;",
|
||||||
event3.getString2()
|
event3.getString2());
|
||||||
);
|
|
||||||
assertFalse(event3.cancelled());
|
assertFalse(event3.cancelled());
|
||||||
handler3.accept(event3);
|
handler3.accept(event3);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"just wishing it stays like this ;w;",
|
"just wishing it stays like this ;w;",
|
||||||
event3.getString1()
|
event3.getString1());
|
||||||
);
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"i'm doing fine curr",
|
"i'm doing fine curr",
|
||||||
event3.getString2()
|
event3.getString2());
|
||||||
);
|
|
||||||
assertTrue(event3.cancelled());
|
assertTrue(event3.cancelled());
|
||||||
handler3.accept(event3);
|
handler3.accept(event3);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"just wishing it stays like this ;w;",
|
"just wishing it stays like this ;w;",
|
||||||
event3.getString1()
|
event3.getString1());
|
||||||
);
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"i'm doing fine curr",
|
"i'm doing fine curr",
|
||||||
event3.getString2()
|
event3.getString2());
|
||||||
);
|
|
||||||
|
|
||||||
DummyEvent4 event4 = new DummyEvent4(9090, 1337);
|
DummyEvent4 event4 = new DummyEvent4(9090, 1337);
|
||||||
assertEquals(9090, event4.getNum1());
|
assertEquals(9090, event4.getNum1());
|
||||||
@@ -201,9 +191,8 @@ class TestTinyEvents {
|
|||||||
|
|
||||||
public @Override int hashCode() {
|
public @Override int hashCode() {
|
||||||
return Objects.hash(
|
return Objects.hash(
|
||||||
this.string1,
|
this.string1,
|
||||||
this.string2
|
this.string2);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Override boolean equals(Object object) {
|
public @Override boolean equals(Object object) {
|
||||||
@@ -211,17 +200,16 @@ class TestTinyEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <E extends DummyEvent1> boolean equals(E event) {
|
public <E extends DummyEvent1> boolean equals(E event) {
|
||||||
return Objects.equals(this.hashCode(), event.hashCode()) || (
|
return Objects.equals(this.hashCode(), event.hashCode())
|
||||||
(Objects.equals(this.getString1(), event.getString1())) &&
|
|| ((Objects.equals(this.getString1(), event.getString1())) &&
|
||||||
(Objects.equals(this.getString2(), event.getString2()))
|
(Objects.equals(this.getString2(), event.getString2())));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Override String toString() {
|
public @Override String toString() {
|
||||||
return new StringJoiner(", ", DummyEvent1.class.getSimpleName() + "[", "]")
|
return new StringJoiner(", ", DummyEvent1.class.getSimpleName() + "[", "]")
|
||||||
.add("string1='" + this.string1 + "'")
|
.add("string1='" + this.string1 + "'")
|
||||||
.add("string2='" + this.string2 + "'")
|
.add("string2='" + this.string2 + "'")
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,9 +239,8 @@ class TestTinyEvents {
|
|||||||
|
|
||||||
public @Override int hashCode() {
|
public @Override int hashCode() {
|
||||||
return Objects.hash(
|
return Objects.hash(
|
||||||
this.num1,
|
this.num1,
|
||||||
this.num2
|
this.num2);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Override boolean equals(Object object) {
|
public @Override boolean equals(Object object) {
|
||||||
@@ -261,17 +248,15 @@ class TestTinyEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <E extends DummyEvent2> boolean equals(E event) {
|
public <E extends DummyEvent2> boolean equals(E event) {
|
||||||
return Objects.equals(this.hashCode(), event.hashCode()) || (
|
return Objects.equals(this.hashCode(), event.hashCode()) || ((Objects.equals(this.getNum1(), event.getNum1())) &&
|
||||||
(Objects.equals(this.getNum1(), event.getNum1())) &&
|
(Objects.equals(this.getNum2(), event.getNum2())));
|
||||||
(Objects.equals(this.getNum2(), event.getNum2()))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Override String toString() {
|
public @Override String toString() {
|
||||||
return new StringJoiner(", ", DummyEvent2.class.getSimpleName() + "[", "]")
|
return new StringJoiner(", ", DummyEvent2.class.getSimpleName() + "[", "]")
|
||||||
.add("num1='" + this.num1 + "'")
|
.add("num1='" + this.num1 + "'")
|
||||||
.add("num2='" + this.num2 + "'")
|
.add("num2='" + this.num2 + "'")
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,10 +287,9 @@ class TestTinyEvents {
|
|||||||
|
|
||||||
public @Override int hashCode() {
|
public @Override int hashCode() {
|
||||||
return Objects.hash(
|
return Objects.hash(
|
||||||
this.string1,
|
this.string1,
|
||||||
this.string2,
|
this.string2,
|
||||||
this.cancelled
|
this.cancelled);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Override boolean equals(Object object) {
|
public @Override boolean equals(Object object) {
|
||||||
@@ -313,18 +297,17 @@ class TestTinyEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <E extends DummyEvent3> boolean equals(E event) {
|
public <E extends DummyEvent3> boolean equals(E event) {
|
||||||
return Objects.equals(this.hashCode(), event.hashCode()) || (
|
return Objects.equals(this.hashCode(), event.hashCode())
|
||||||
(Objects.equals(this.getString1(), event.getString1())) &&
|
|| ((Objects.equals(this.getString1(), event.getString1())) &&
|
||||||
(Objects.equals(this.getString2(), event.getString2()))
|
(Objects.equals(this.getString2(), event.getString2())));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Override String toString() {
|
public @Override String toString() {
|
||||||
return new StringJoiner(", ", DummyEvent3.class.getSimpleName() + "[", "]")
|
return new StringJoiner(", ", DummyEvent3.class.getSimpleName() + "[", "]")
|
||||||
.add("string1='" + this.string1 + "'")
|
.add("string1='" + this.string1 + "'")
|
||||||
.add("string2='" + this.string2 + "'")
|
.add("string2='" + this.string2 + "'")
|
||||||
.add("cancelled='" + this.cancelled + "'")
|
.add("cancelled='" + this.cancelled + "'")
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -365,10 +348,9 @@ class TestTinyEvents {
|
|||||||
|
|
||||||
public @Override int hashCode() {
|
public @Override int hashCode() {
|
||||||
return Objects.hash(
|
return Objects.hash(
|
||||||
this.num1,
|
this.num1,
|
||||||
this.num2,
|
this.num2,
|
||||||
this.cancelled
|
this.cancelled);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Override boolean equals(Object object) {
|
public @Override boolean equals(Object object) {
|
||||||
@@ -376,18 +358,16 @@ class TestTinyEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <E extends DummyEvent4> boolean equals(E event) {
|
public <E extends DummyEvent4> boolean equals(E event) {
|
||||||
return Objects.equals(this.hashCode(), event.hashCode()) || (
|
return Objects.equals(this.hashCode(), event.hashCode()) || ((Objects.equals(this.getNum1(), event.getNum1())) &&
|
||||||
(Objects.equals(this.getNum1(), event.getNum1())) &&
|
(Objects.equals(this.getNum2(), event.getNum2())));
|
||||||
(Objects.equals(this.getNum2(), event.getNum2()))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Override String toString() {
|
public @Override String toString() {
|
||||||
return new StringJoiner(", ", DummyEvent4.class.getSimpleName() + "[", "]")
|
return new StringJoiner(", ", DummyEvent4.class.getSimpleName() + "[", "]")
|
||||||
.add("num1='" + this.num1 + "'")
|
.add("num1='" + this.num1 + "'")
|
||||||
.add("num2='" + this.num2 + "'")
|
.add("num2='" + this.num2 + "'")
|
||||||
.add("cancelled='" + this.cancelled + "'")
|
.add("cancelled='" + this.cancelled + "'")
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Reference in New Issue
Block a user