修复 TaskListPane 未正确处理 StagesHintTask 的问题 (#4285)

This commit is contained in:
Glavo
2025-08-19 16:22:51 +08:00
committed by GitHub
parent 6cf933741f
commit aab3b22290

View File

@@ -63,24 +63,26 @@ import org.jackhuang.hmcl.task.TaskExecutor;
import org.jackhuang.hmcl.task.TaskListener; import org.jackhuang.hmcl.task.TaskListener;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.SVG; import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.FXThread;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX; import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.Lang.tryCast; import static org.jackhuang.hmcl.util.Lang.tryCast;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class TaskListPane extends StackPane { public final class TaskListPane extends StackPane {
private static final Insets DEFAULT_PROGRESS_NODE_PADDING = new Insets(0, 0, 8, 0);
private static final Insets STAGED_PROGRESS_NODE_PADDING = new Insets(0, 0, 8, 26);
private TaskExecutor executor; private TaskExecutor executor;
private final AdvancedListBox listBox = new AdvancedListBox(); private final AdvancedListBox listBox = new AdvancedListBox();
private final Map<Task<?>, ProgressListNode> nodes = new HashMap<>(); private final Map<Task<?>, ProgressListNode> nodes = new HashMap<>();
private final List<StageNode> stageNodes = new ArrayList<>(); private final Map<String, StageNode> stageNodes = new HashMap<>();
private final ObjectProperty<Insets> progressNodePadding = new SimpleObjectProperty<>(Insets.EMPTY); private final ObjectProperty<Insets> progressNodePadding = new SimpleObjectProperty<>(Insets.EMPTY);
public TaskListPane() { public TaskListPane() {
@@ -89,8 +91,23 @@ public final class TaskListPane extends StackPane {
getChildren().setAll(listBox); getChildren().setAll(listBox);
} }
@FXThread
private void addStages(@NotNull Collection<String> stages) {
for (String stage : stages) {
stageNodes.computeIfAbsent(stage, s -> {
StageNode node = new StageNode(stage);
listBox.add(node);
return node;
});
}
}
@FXThread
private void updateProgressNodePadding() {
progressNodePadding.set(stageNodes.isEmpty() ? DEFAULT_PROGRESS_NODE_PADDING : STAGED_PROGRESS_NODE_PADDING);
}
public void setExecutor(TaskExecutor executor) { public void setExecutor(TaskExecutor executor) {
List<String> stages = Lang.removingDuplicates(executor.getStages());
this.executor = executor; this.executor = executor;
executor.addTaskListener(new TaskListener() { executor.addTaskListener(new TaskListener() {
@Override @Override
@@ -98,19 +115,25 @@ public final class TaskListPane extends StackPane {
Platform.runLater(() -> { Platform.runLater(() -> {
stageNodes.clear(); stageNodes.clear();
listBox.clear(); listBox.clear();
stageNodes.addAll(stages.stream().map(StageNode::new).collect(Collectors.toList())); addStages(executor.getStages());
stageNodes.forEach(listBox::add); updateProgressNodePadding();
if (stages.isEmpty()) progressNodePadding.setValue(new Insets(0, 0, 8, 0));
else progressNodePadding.setValue(new Insets(0, 0, 8, 26));
}); });
} }
@Override @Override
public void onReady(Task<?> task) { public void onReady(Task<?> task) {
if (task instanceof Task.StagesHintTask) {
Platform.runLater(() -> {
addStages(((Task<?>.StagesHintTask) task).getStages());
updateProgressNodePadding();
});
}
if (task.getStage() != null) { if (task.getStage() != null) {
Platform.runLater(() -> { Platform.runLater(() -> {
stageNodes.stream().filter(x -> x.stage.equals(task.getStage())).findAny().ifPresent(StageNode::begin); StageNode node = stageNodes.get(task.getStage());
if (node != null)
node.begin();
}); });
} }
} }
@@ -169,20 +192,20 @@ public final class TaskListPane extends StackPane {
Platform.runLater(() -> { Platform.runLater(() -> {
ProgressListNode node = new ProgressListNode(task); ProgressListNode node = new ProgressListNode(task);
nodes.put(task, node); nodes.put(task, node);
StageNode stageNode = stageNodes.stream().filter(x -> x.stage.equals(task.getInheritedStage())).findAny().orElse(null); StageNode stageNode = stageNodes.get(task.getInheritedStage());
listBox.add(listBox.indexOf(stageNode) + 1, node); listBox.add(listBox.indexOf(stageNode) + 1, node);
}); });
} }
@Override @Override
public void onFinished(Task<?> task) { public void onFinished(Task<?> task) {
if (task.getStage() != null) {
Platform.runLater(() -> {
stageNodes.stream().filter(x -> x.stage.equals(task.getStage())).findAny().ifPresent(StageNode::succeed);
});
}
Platform.runLater(() -> { Platform.runLater(() -> {
if (task.getStage() != null) {
StageNode stageNode = stageNodes.get(task.getStage());
if (stageNode != null)
stageNode.succeed();
}
ProgressListNode node = nodes.remove(task); ProgressListNode node = nodes.remove(task);
if (node == null) if (node == null)
return; return;
@@ -195,25 +218,23 @@ public final class TaskListPane extends StackPane {
public void onFailed(Task<?> task, Throwable throwable) { public void onFailed(Task<?> task, Throwable throwable) {
if (task.getStage() != null) { if (task.getStage() != null) {
Platform.runLater(() -> { Platform.runLater(() -> {
stageNodes.stream().filter(x -> x.stage.equals(task.getStage())).findAny().ifPresent(StageNode::fail); StageNode stageNode = stageNodes.get(task.getStage());
if (stageNode != null)
stageNode.fail();
}); });
} }
ProgressListNode node = nodes.remove(task); ProgressListNode node = nodes.remove(task);
if (node == null) if (node != null)
return; Platform.runLater(() -> node.setThrowable(throwable));
Platform.runLater(() -> {
node.setThrowable(throwable);
});
} }
@Override @Override
public void onPropertiesUpdate(Task<?> task) { public void onPropertiesUpdate(Task<?> task) {
if (task instanceof Task.CountTask) { if (task instanceof Task.CountTask) {
runInFX(() -> { runInFX(() -> {
stageNodes.stream() StageNode stageNode = stageNodes.get(((Task<?>.CountTask) task).getCountStage());
.filter(x -> x.stage.equals(((Task<?>.CountTask) task).getCountStage())) if (stageNode != null)
.findAny() stageNode.count();
.ifPresent(StageNode::count);
}); });
return; return;
@@ -222,12 +243,9 @@ public final class TaskListPane extends StackPane {
if (task.getStage() != null) { if (task.getStage() != null) {
int total = tryCast(task.getProperties().get("total"), Integer.class).orElse(0); int total = tryCast(task.getProperties().get("total"), Integer.class).orElse(0);
runInFX(() -> { runInFX(() -> {
stageNodes.stream() StageNode stageNode = stageNodes.get(task.getStage());
.filter(x -> x.stage.equals(task.getStage())) if (stageNode != null)
.findAny() stageNode.setTotal(total);
.ifPresent(stageNode -> {
stageNode.setTotal(total);
});
}); });
} }
} }