优化 EventBus (#4565)
This commit is contained in:
@@ -40,6 +40,7 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
|||||||
public class TaskExecutorDialogPane extends BorderPane {
|
public class TaskExecutorDialogPane extends BorderPane {
|
||||||
private TaskExecutor executor;
|
private TaskExecutor executor;
|
||||||
private TaskCancellationAction onCancel;
|
private TaskCancellationAction onCancel;
|
||||||
|
@SuppressWarnings({"unused", "FieldCanBeLocal"})
|
||||||
private final Consumer<FetchTask.SpeedEvent> speedEventHandler;
|
private final Consumer<FetchTask.SpeedEvent> speedEventHandler;
|
||||||
|
|
||||||
private final Label lblTitle;
|
private final Label lblTitle;
|
||||||
@@ -84,7 +85,7 @@ public class TaskExecutorDialogPane extends BorderPane {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
speedEventHandler = speedEvent -> {
|
speedEventHandler = FetchTask.SPEED_EVENT.registerWeak(speedEvent -> {
|
||||||
String unit = "B/s";
|
String unit = "B/s";
|
||||||
double speed = speedEvent.getSpeed();
|
double speed = speedEvent.getSpeed();
|
||||||
if (speed > 1024) {
|
if (speed > 1024) {
|
||||||
@@ -95,11 +96,10 @@ public class TaskExecutorDialogPane extends BorderPane {
|
|||||||
speed /= 1024;
|
speed /= 1024;
|
||||||
unit = "MiB/s";
|
unit = "MiB/s";
|
||||||
}
|
}
|
||||||
double finalSpeed = speed;
|
|
||||||
String finalUnit = unit;
|
String message = String.format("%.1f %s", speed, unit);
|
||||||
Platform.runLater(() -> lblProgress.setText(String.format("%.1f %s", finalSpeed, finalUnit)));
|
Platform.runLater(() -> lblProgress.setText(message));
|
||||||
};
|
});
|
||||||
FileDownloadTask.speedEvent.channel(FetchTask.SpeedEvent.class).registerWeak(speedEventHandler);
|
|
||||||
|
|
||||||
onEscPressed(this, btnCancel::fire);
|
onEscPressed(this, btnCancel::fire);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,29 +17,32 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.event;
|
package org.jackhuang.hmcl.event;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
|
|
||||||
/**
|
/// @author huangyuhui
|
||||||
*
|
public final class EventBus extends ClassValue<EventManager<?>> {
|
||||||
* @author huangyuhui
|
|
||||||
*/
|
|
||||||
public final class EventBus {
|
|
||||||
|
|
||||||
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")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Event> EventManager<T> channel(Class<T> clazz) {
|
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")
|
@SuppressWarnings("unchecked")
|
||||||
public Event.Result fireEvent(Event obj) {
|
public Event.Result fireEvent(Event obj) {
|
||||||
LOG.info(obj + " gets fired");
|
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();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package org.jackhuang.hmcl.event;
|
package org.jackhuang.hmcl.event;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.util.SimpleMultimap;
|
import org.jackhuang.hmcl.util.SimpleMultimap;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
@@ -25,21 +26,20 @@ 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 final ReentrantLock lock = new ReentrantLock();
|
private final ReentrantLock lock = new ReentrantLock();
|
||||||
private final SimpleMultimap<EventPriority, Consumer<T>, CopyOnWriteArraySet<Consumer<T>>> handlers
|
private final SimpleMultimap<EventPriority, Consumer<T>, CopyOnWriteArraySet<Consumer<T>>> handlers
|
||||||
= new SimpleMultimap<>(() -> new EnumMap<>(EventPriority.class), CopyOnWriteArraySet::new);
|
= new SimpleMultimap<>(() -> new EnumMap<>(EventPriority.class), CopyOnWriteArraySet::new);
|
||||||
|
|
||||||
|
@Contract("_ -> param1")
|
||||||
public Consumer<T> registerWeak(Consumer<T> consumer) {
|
public Consumer<T> registerWeak(Consumer<T> consumer) {
|
||||||
register(new WeakListener(consumer));
|
register(new WeakListener(consumer));
|
||||||
return consumer;
|
return consumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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(consumer), priority);
|
||||||
return consumer;
|
return consumer;
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -19,6 +19,7 @@ package org.jackhuang.hmcl.task;
|
|||||||
|
|
||||||
import org.jackhuang.hmcl.event.Event;
|
import org.jackhuang.hmcl.event.Event;
|
||||||
import org.jackhuang.hmcl.event.EventBus;
|
import org.jackhuang.hmcl.event.EventBus;
|
||||||
|
import org.jackhuang.hmcl.event.EventManager;
|
||||||
import org.jackhuang.hmcl.util.*;
|
import org.jackhuang.hmcl.util.*;
|
||||||
import org.jackhuang.hmcl.util.io.ContentEncoding;
|
import org.jackhuang.hmcl.util.io.ContentEncoding;
|
||||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
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 Timer timer = new Timer("DownloadSpeedRecorder", true);
|
||||||
private static final AtomicLong downloadSpeed = new AtomicLong(0L);
|
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 {
|
static {
|
||||||
timer.schedule(new TimerTask() {
|
timer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
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);
|
}, 0, 1000);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user