清理 EventManager (#5381)
This commit is contained in:
@@ -17,31 +17,31 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.event;
|
package org.jackhuang.hmcl.event;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.util.SimpleMultimap;
|
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.EnumMap;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/// @author huangyuhui
|
/// @author huangyuhui
|
||||||
public final class EventManager<T extends Event> {
|
public final class EventManager<T extends Event> {
|
||||||
|
|
||||||
|
private static final int PRIORITY_COUNT = EventPriority.values().length;
|
||||||
|
|
||||||
private final ReentrantLock lock = new ReentrantLock();
|
private final ReentrantLock lock = new ReentrantLock();
|
||||||
private final SimpleMultimap<EventPriority, Consumer<T>, CopyOnWriteArraySet<Consumer<T>>> handlers
|
@SuppressWarnings("unchecked")
|
||||||
= new SimpleMultimap<>(() -> new EnumMap<>(EventPriority.class), CopyOnWriteArraySet::new);
|
private final CopyOnWriteArrayList<Consumer<T>>[] allHandlers = (CopyOnWriteArrayList<Consumer<T>>[]) new CopyOnWriteArrayList<?>[PRIORITY_COUNT];
|
||||||
|
|
||||||
@Contract("_ -> param1")
|
@Contract("_ -> param1")
|
||||||
public Consumer<T> registerWeak(Consumer<T> consumer) {
|
public Consumer<T> registerWeak(Consumer<T> consumer) {
|
||||||
register(new WeakListener(consumer));
|
register(new WeakListener<>(new WeakReference<>(consumer)));
|
||||||
return consumer;
|
return consumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Contract("_, _ -> param1")
|
@Contract("_, _ -> param1")
|
||||||
public Consumer<T> registerWeak(Consumer<T> consumer, EventPriority priority) {
|
public Consumer<T> registerWeak(Consumer<T> consumer, EventPriority priority) {
|
||||||
register(new WeakListener(consumer), priority);
|
register(new WeakListener<>(new WeakReference<>(consumer)), priority);
|
||||||
return consumer;
|
return consumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,12 @@ public final class EventManager<T extends Event> {
|
|||||||
public void register(Consumer<T> consumer, EventPriority priority) {
|
public void register(Consumer<T> consumer, EventPriority priority) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
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 {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
@@ -69,9 +74,21 @@ public final class EventManager<T extends Event> {
|
|||||||
public Event.Result fireEvent(T event) {
|
public Event.Result fireEvent(T event) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
for (EventPriority priority : EventPriority.values()) {
|
for (var handlers : allHandlers) {
|
||||||
for (Consumer<T> handler : handlers.get(priority))
|
if (handlers != null) {
|
||||||
handler.accept(event);
|
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 {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
@@ -80,30 +97,12 @@ public final class EventManager<T extends Event> {
|
|||||||
return event.hasResult() ? event.getResult() : Event.Result.DEFAULT;
|
return event.hasResult() ? event.getResult() : Event.Result.DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregister(Consumer<T> consumer) {
|
private record WeakListener<T>(WeakReference<Consumer<T>> ref) implements Consumer<T> {
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(T t) {
|
public void accept(T t) {
|
||||||
Consumer<T> listener = ref.get();
|
Consumer<T> listener = ref.get();
|
||||||
if (listener == null) {
|
if (listener != null)
|
||||||
unregister(this);
|
|
||||||
} else {
|
|
||||||
listener.accept(t);
|
listener.accept(t);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user