mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-15 06:45:42 -04:00
add: show asset and mod download progress
This commit is contained in:
parent
4f51ab00a1
commit
3efec78732
@ -57,6 +57,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class TaskListPane extends StackPane {
|
||||
@ -172,12 +173,24 @@ public final class TaskListPane extends StackPane {
|
||||
node.setThrowable(throwable);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPropertiesUpdate(Map<String, Map<String, Object>> stageProperties) {
|
||||
stageProperties.forEach((stage, properties) -> {
|
||||
int count = tryCast(properties.get("count"), Integer.class).orElse(0),
|
||||
total = tryCast(properties.get("total"), Integer.class).orElse(0);
|
||||
if (total > 0)
|
||||
Platform.runLater(() ->
|
||||
stageNodes.stream().filter(x -> x.stage.equals(stage)).findAny().ifPresent(stageNode -> stageNode.updateCounter(count, total)));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class StageNode extends BorderPane {
|
||||
private static class StageNode extends BorderPane {
|
||||
private final String stage;
|
||||
private final Label title = new Label();
|
||||
private final String message;
|
||||
private boolean started = false;
|
||||
|
||||
public StageNode(String stage) {
|
||||
@ -185,7 +198,6 @@ public final class TaskListPane extends StackPane {
|
||||
|
||||
String stageKey = StringUtils.substringBefore(stage, ':');
|
||||
String stageValue = StringUtils.substringAfter(stage, ':');
|
||||
String message;
|
||||
|
||||
// @formatter:off
|
||||
switch (stageKey) {
|
||||
@ -222,6 +234,13 @@ public final class TaskListPane extends StackPane {
|
||||
public void succeed() {
|
||||
setLeft(FXUtils.limitingSize(SVG.check(Theme.blackFillBinding(), 14, 14), 14, 14));
|
||||
}
|
||||
|
||||
public void updateCounter(int count, int total) {
|
||||
if (total > 0)
|
||||
title.setText(String.format("%s - %d/%d", message, count, total));
|
||||
else
|
||||
title.setText(message);
|
||||
}
|
||||
}
|
||||
|
||||
private class ProgressListNode extends BorderPane {
|
||||
|
@ -78,6 +78,7 @@ public class VersionPage extends Control implements DecoratorPage {
|
||||
Profiles.registerVersionsListener(this::loadVersions);
|
||||
|
||||
listView.getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> {
|
||||
if (newValue != null)
|
||||
loadVersion(newValue, profile);
|
||||
});
|
||||
|
||||
|
@ -123,13 +123,17 @@ public final class GameAssetDownloadTask extends Task<Void> {
|
||||
.setCacheRepository(dependencyManager.getCacheRepository())
|
||||
.setCaching(true)
|
||||
.setCandidate(dependencyManager.getCacheRepository().getCommonDirectory()
|
||||
.resolve("assets").resolve("objects").resolve(assetObject.getLocation())));
|
||||
.resolve("assets").resolve("objects").resolve(assetObject.getLocation())).withCounter());
|
||||
} else {
|
||||
dependencyManager.getCacheRepository().tryCacheFile(file.toPath(), CacheRepository.SHA1, assetObject.getHash());
|
||||
}
|
||||
|
||||
updateProgress(++progress, index.getObjects().size());
|
||||
}
|
||||
|
||||
if (!dependencies.isEmpty()) {
|
||||
getProperties().put("total", dependencies.size());
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean DOWNLOAD_INDEX_FORCIBLY = true;
|
||||
|
@ -151,9 +151,13 @@ public final class CurseCompletionTask extends Task<Void> {
|
||||
if (!modManager.hasSimpleMod(file.getFileName())) {
|
||||
dependencies.add(new FileDownloadTask(file.getUrl(), modManager.getSimpleModPath(file.getFileName()).toFile())
|
||||
.setCacheRepository(dependency.getCacheRepository())
|
||||
.setCaching(true));
|
||||
.setCaching(true).withCounter());
|
||||
}
|
||||
}
|
||||
|
||||
if (!dependencies.isEmpty()) {
|
||||
getProperties().put("total", dependencies.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,11 +20,10 @@ package org.jackhuang.hmcl.task;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.function.ExceptionalRunnable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CancellableTaskExecutor extends TaskExecutor {
|
||||
@ -105,6 +104,19 @@ public class CancellableTaskExecutor extends TaskExecutor {
|
||||
return success.get() && !cancelled.get();
|
||||
}
|
||||
|
||||
private synchronized void updateStageProperties(String stage, Map<String, Object> taskProperties) {
|
||||
stageProperties.putIfAbsent(stage, new HashMap<>());
|
||||
Map<String, Object> prop = stageProperties.get(stage);
|
||||
for (Map.Entry<String, Object> entry : taskProperties.entrySet()) {
|
||||
if (entry.getValue() instanceof UnaryOperator) {
|
||||
prop.put(entry.getKey(), ((UnaryOperator) entry.getValue()).apply(prop.get(entry.getKey())));
|
||||
} else {
|
||||
prop.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
taskListeners.forEach(taskListener -> taskListener.onPropertiesUpdate(stageProperties));
|
||||
}
|
||||
|
||||
private boolean executeTask(Task<?> parentTask, Task<?> task) {
|
||||
task.setCancelled(this::isCancelled);
|
||||
|
||||
@ -161,6 +173,10 @@ public class CancellableTaskExecutor extends TaskExecutor {
|
||||
task.setState(Task.TaskState.EXECUTED);
|
||||
}
|
||||
|
||||
if (task.properties != null) {
|
||||
updateStageProperties(task.getStage(), task.properties);
|
||||
}
|
||||
|
||||
Collection<? extends Task<?>> dependencies = task.getDependencies();
|
||||
boolean doDependenciesSucceeded = executeTasks(task, dependencies);
|
||||
Exception dependenciesException = dependencies.stream().map(Task::getException)
|
||||
@ -191,6 +207,10 @@ public class CancellableTaskExecutor extends TaskExecutor {
|
||||
Logging.LOG.log(Level.FINER, "Task finished: " + task.getName());
|
||||
}
|
||||
|
||||
if (task.properties != null) {
|
||||
updateStageProperties(task.getStage(), task.properties);
|
||||
}
|
||||
|
||||
task.onDone().fireEvent(new TaskEvent(this, task, false));
|
||||
taskListeners.forEach(it -> it.onFinished(task));
|
||||
} catch (RejectedExecutionException e) {
|
||||
|
@ -32,15 +32,13 @@ import org.jackhuang.hmcl.util.function.ExceptionalFunction;
|
||||
import org.jackhuang.hmcl.util.function.ExceptionalRunnable;
|
||||
import org.jackhuang.hmcl.util.function.ExceptionalSupplier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@ -107,6 +105,13 @@ public abstract class Task<T> {
|
||||
return getStage() == null ? Collections.emptyList() : Collections.singletonList(getStage());
|
||||
}
|
||||
|
||||
Map<String, Object> properties;
|
||||
|
||||
protected Map<String, Object> getProperties() {
|
||||
if (properties == null) properties = new HashMap<>();
|
||||
return properties;
|
||||
}
|
||||
|
||||
// state
|
||||
private TaskState state = TaskState.READY;
|
||||
|
||||
@ -802,6 +807,10 @@ public abstract class Task<T> {
|
||||
};
|
||||
}
|
||||
|
||||
public Task<T> withCounter() {
|
||||
return new CountTask();
|
||||
}
|
||||
|
||||
public static Task<Void> runAsync(ExceptionalRunnable<?> closure) {
|
||||
return runAsync(Schedulers.defaultScheduler(), closure);
|
||||
}
|
||||
@ -1063,4 +1072,37 @@ public abstract class Task<T> {
|
||||
return Lang.merge(Task.this.getStages(), super.getStages());
|
||||
}
|
||||
}
|
||||
|
||||
private class CountTask extends Task<T> {
|
||||
private final UnaryOperator<Integer> COUNTER = a -> {
|
||||
int result = 0;
|
||||
if (a != null) result += a;
|
||||
return result + 1;
|
||||
};
|
||||
|
||||
@Override
|
||||
public Collection<Task<?>> getDependents() {
|
||||
return Collections.singleton(Task.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
setResult(Task.this.getResult());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doPostExecute() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postExecute() {
|
||||
getProperties().put("count", COUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getStages() {
|
||||
return Lang.merge(Task.this.getStages(), super.getStages());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,10 @@ package org.jackhuang.hmcl.task;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@ -31,6 +33,7 @@ public abstract class TaskExecutor {
|
||||
protected final AtomicBoolean cancelled = new AtomicBoolean(false);
|
||||
protected Exception exception;
|
||||
private final List<String> stages;
|
||||
protected final Map<String, Map<String, Object>> stageProperties = new HashMap<>();
|
||||
|
||||
public TaskExecutor(Task<?> task) {
|
||||
this.firstTask = task;
|
||||
|
@ -18,6 +18,7 @@
|
||||
package org.jackhuang.hmcl.task;
|
||||
|
||||
import java.util.EventListener;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -78,4 +79,7 @@ public abstract class TaskListener implements EventListener {
|
||||
*/
|
||||
public void onStop(boolean success, TaskExecutor executor) {
|
||||
}
|
||||
|
||||
public void onPropertiesUpdate(Map<String, Map<String, Object>> stageProperties) {
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user