简化 InvocationDispatcher (#2674)

* 优化 InvocationDispatcher

* update

* Rename type parameter

* update
This commit is contained in:
Glavo 2024-03-08 10:06:08 +08:00 committed by GitHub
parent 20d93dd085
commit 2d83de7c31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -20,36 +20,37 @@ package org.jackhuang.hmcl.util;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
/** /**
* When {@link #accept(ARG)} is called, this class invokes the handler on another thread. * When {@link #accept(T)} is called, this class invokes the handler on another thread.
* If {@link #accept(ARG)} is called more than one time before the handler starts processing, * If {@link #accept(T)} is called more than one time before the handler starts processing,
* the handler will only be invoked once, taking the latest argument as its input. * the handler will only be invoked once, taking the latest argument as its input.
* *
* @author yushijinhun * @author yushijinhun
*/ */
public final class InvocationDispatcher<ARG> implements Consumer<ARG> { public final class InvocationDispatcher<T> implements Consumer<T> {
public static <ARG> InvocationDispatcher<ARG> runOn(Executor executor, Consumer<ARG> action) { public static <T> InvocationDispatcher<T> runOn(Executor executor, Consumer<T> action) {
return new InvocationDispatcher<>(arg -> executor.execute(() -> { return new InvocationDispatcher<>(executor, action);
synchronized (action) {
action.accept(arg.get());
}
}));
} }
private final Consumer<Supplier<ARG>> handler; private final Executor executor;
private final AtomicReference<Holder<ARG>> pendingArg = new AtomicReference<>(); private final Consumer<T> action;
private final AtomicReference<Holder<T>> pendingArg = new AtomicReference<>();
public InvocationDispatcher(Consumer<Supplier<ARG>> handler) { private InvocationDispatcher(Executor executor, Consumer<T> action) {
this.handler = handler; this.executor = executor;
this.action = action;
} }
@Override @Override
public void accept(ARG arg) { public void accept(T t) {
if (pendingArg.getAndSet(new Holder<>(arg)) == null) { if (pendingArg.getAndSet(new Holder<>(t)) == null) {
handler.accept(() -> pendingArg.getAndSet(null).value); executor.execute(() -> {
synchronized (InvocationDispatcher.this) {
action.accept(pendingArg.getAndSet(null).value);
}
});
} }
} }
} }