优化 EventBus (#4565)

This commit is contained in:
Glavo
2025-10-02 15:38:03 +08:00
committed by GitHub
parent 35ecd58460
commit e0f5c4d91e
5 changed files with 27 additions and 70 deletions

View File

@@ -17,29 +17,32 @@
*/
package org.jackhuang.hmcl.event;
import java.util.concurrent.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
*
* @author huangyuhui
*/
public final class EventBus {
/// @author huangyuhui
public final class EventBus extends ClassValue<EventManager<?>> {
private final ConcurrentHashMap<Class<?>, EventManager<?>> events = new ConcurrentHashMap<>();
public static final EventBus EVENT_BUS = new EventBus();
private EventBus() {
}
@Override
protected EventManager<?> computeValue(@NotNull Class<?> type) {
return new EventManager<>();
}
@SuppressWarnings("unchecked")
public <T extends Event> EventManager<T> channel(Class<T> clazz) {
return (EventManager<T>) events.computeIfAbsent(clazz, ignored -> new EventManager<>());
return (EventManager<T>) get(clazz);
}
@SuppressWarnings("unchecked")
public Event.Result fireEvent(Event obj) {
LOG.info(obj + " gets fired");
return channel((Class<Event>) obj.getClass()).fireEvent(obj);
return ((EventManager<Event>) get(obj.getClass())).fireEvent(obj);
}
public static final EventBus EVENT_BUS = new EventBus();
}

View File

@@ -18,6 +18,7 @@
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;
@@ -25,21 +26,20 @@ import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
/**
*
* @author huangyuhui
*/
/// @author huangyuhui
public final class EventManager<T extends Event> {
private final ReentrantLock lock = new ReentrantLock();
private final SimpleMultimap<EventPriority, Consumer<T>, CopyOnWriteArraySet<Consumer<T>>> handlers
= new SimpleMultimap<>(() -> new EnumMap<>(EventPriority.class), CopyOnWriteArraySet::new);
@Contract("_ -> param1")
public Consumer<T> registerWeak(Consumer<T> consumer) {
register(new WeakListener(consumer));
return consumer;
}
@Contract("_, _ -> param1")
public Consumer<T> registerWeak(Consumer<T> consumer, EventPriority priority) {
register(new WeakListener(consumer), priority);
return consumer;

View File

@@ -1,47 +0,0 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.event;
/**
*
* @author huang
*/
public class FailedEvent<T> extends Event {
private final int failedTime;
private T newResult;
public FailedEvent(Object source, int failedTime, T newResult) {
super(source);
this.failedTime = failedTime;
this.newResult = newResult;
}
public int getFailedTime() {
return failedTime;
}
public T getNewResult() {
return newResult;
}
public void setNewResult(T newResult) {
this.newResult = newResult;
}
}

View File

@@ -19,6 +19,7 @@ package org.jackhuang.hmcl.task;
import org.jackhuang.hmcl.event.Event;
import org.jackhuang.hmcl.event.EventBus;
import org.jackhuang.hmcl.event.EventManager;
import org.jackhuang.hmcl.util.*;
import org.jackhuang.hmcl.util.io.ContentEncoding;
import org.jackhuang.hmcl.util.io.IOUtils;
@@ -355,13 +356,13 @@ public abstract class FetchTask<T> extends Task<T> {
private static final Timer timer = new Timer("DownloadSpeedRecorder", true);
private static final AtomicLong downloadSpeed = new AtomicLong(0L);
public static final EventBus speedEvent = new EventBus();
public static final EventManager<SpeedEvent> SPEED_EVENT = EventBus.EVENT_BUS.channel(SpeedEvent.class);
static {
timer.schedule(new TimerTask() {
@Override
public void run() {
speedEvent.channel(SpeedEvent.class).fireEvent(new SpeedEvent(speedEvent, downloadSpeed.getAndSet(0)));
SPEED_EVENT.fireEvent(new SpeedEvent(SPEED_EVENT, downloadSpeed.getAndSet(0)));
}
}, 0, 1000);
}