清理 EventManager (#5381)

This commit is contained in:
Glavo
2026-02-01 16:09:31 +08:00
committed by GitHub
parent 17be25c036
commit a524ba8506

View File

@@ -17,31 +17,31 @@
*/
package org.jackhuang.hmcl.event;
import org.jackhuang.hmcl.util.SimpleMultimap;
import org.jetbrains.annotations.Contract;
import java.lang.ref.WeakReference;
import java.util.EnumMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
/// @author huangyuhui
public final class EventManager<T extends Event> {
private static final int PRIORITY_COUNT = EventPriority.values().length;
private final ReentrantLock lock = new ReentrantLock();
private final SimpleMultimap<EventPriority, Consumer<T>, CopyOnWriteArraySet<Consumer<T>>> handlers
= new SimpleMultimap<>(() -> new EnumMap<>(EventPriority.class), CopyOnWriteArraySet::new);
@SuppressWarnings("unchecked")
private final CopyOnWriteArrayList<Consumer<T>>[] allHandlers = (CopyOnWriteArrayList<Consumer<T>>[]) new CopyOnWriteArrayList<?>[PRIORITY_COUNT];
@Contract("_ -> param1")
public Consumer<T> registerWeak(Consumer<T> consumer) {
register(new WeakListener(consumer));
register(new WeakListener<>(new WeakReference<>(consumer)));
return consumer;
}
@Contract("_, _ -> param1")
public Consumer<T> registerWeak(Consumer<T> consumer, EventPriority priority) {
register(new WeakListener(consumer), priority);
register(new WeakListener<>(new WeakReference<>(consumer)), priority);
return consumer;
}
@@ -52,7 +52,12 @@ public final class EventManager<T extends Event> {
public void register(Consumer<T> consumer, EventPriority priority) {
lock.lock();
try {
handlers.get(priority).add(consumer);
var handlers = allHandlers[priority.ordinal()];
if (handlers == null) {
handlers = new CopyOnWriteArrayList<>();
allHandlers[priority.ordinal()] = handlers;
}
handlers.add(consumer);
} finally {
lock.unlock();
}
@@ -69,10 +74,22 @@ public final class EventManager<T extends Event> {
public Event.Result fireEvent(T event) {
lock.lock();
try {
for (EventPriority priority : EventPriority.values()) {
for (Consumer<T> handler : handlers.get(priority))
for (var handlers : allHandlers) {
if (handlers != null) {
for (Consumer<T> handler : handlers) {
if (handler instanceof WeakListener<T> weakListener) {
Consumer<T> consumer = weakListener.ref.get();
if (consumer != null) {
consumer.accept(event);
} else {
handlers.remove(weakListener);
}
} else {
handler.accept(event);
}
}
}
}
} finally {
lock.unlock();
}
@@ -80,30 +97,12 @@ public final class EventManager<T extends Event> {
return event.hasResult() ? event.getResult() : Event.Result.DEFAULT;
}
public void unregister(Consumer<T> consumer) {
lock.lock();
try {
handlers.removeValue(consumer);
} finally {
lock.unlock();
}
}
private final class WeakListener implements Consumer<T> {
private final WeakReference<Consumer<T>> ref;
public WeakListener(Consumer<T> listener) {
this.ref = new WeakReference<>(listener);
}
private record WeakListener<T>(WeakReference<Consumer<T>> ref) implements Consumer<T> {
@Override
public void accept(T t) {
Consumer<T> listener = ref.get();
if (listener == null) {
unregister(this);
} else {
if (listener != null)
listener.accept(t);
}
}
}
}