/* * Copyright (c) 2016 Jesper Öqvist <jesper@llbit.se> * * This file is part of Chunky. * * Chunky 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. * * Chunky 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 Chunky. If not, see <http://www.gnu.org/licenses/>. */ package se.llbit.util; /** * A task tracker is used to update a progress listener with current task progress. * The task tracker has a stack of tasks. When a new task is created the previous * task is remembered so when the new task is finished the old task will be the * current one. */ public class TaskTracker { public interface TaskBuilder { Task newTask(TaskTracker tracker, Task previous, String name, int size); } private final ProgressListener progress; private final TaskBuilder taskBuilder; private final Task backgroundTask; private Task currentTask; public TaskTracker(ProgressListener progress) { this(progress, Task::new); } public TaskTracker(ProgressListener progress, TaskBuilder taskBuilder) { this(progress, taskBuilder, taskBuilder); } public TaskTracker(ProgressListener progress, TaskBuilder taskBuilder, TaskBuilder backgroundTaskBuilder) { this.progress = progress; this.taskBuilder = taskBuilder; this.backgroundTask = backgroundTaskBuilder.newTask(this, null, "N/A", 1); currentTask = backgroundTask; } public static class Task implements AutoCloseable { public static final Task NONE = new Task(null, null, "None", 1) { @Override protected void update() { } @Override public void close() { } }; private String taskName; private int target; private int done; protected final TaskTracker tracker; protected final Task previous; private String eta = ""; protected final long startTime; public Task(TaskTracker tracker, Task previous, String taskName, int size) { this.tracker = tracker; this.previous = previous; this.taskName = taskName; this.done = 0; this.target = size; this.startTime = System.currentTimeMillis(); } /** Set the current progress. */ public void update(int done) { this.done = done; update(); } /** Set the current progress. */ public void update(int target, int done) { this.done = done; this.target = target; update(); } protected void update() { tracker.updateProgress(taskName, target, done, eta); } @Override public void close() { tracker.currentTask = previous; previous.update(); } /** Changes the task name and state. */ public void update(String task, int target, int done) { update(task, target, done, ""); } /** * Changes the task name and state. * Reports the task state to the progress listener. */ public void update(String task, int target, int done, String eta) { this.taskName = task; this.done = done; this.target = target; this.eta = eta; update(); } } private void updateProgress(String taskName, int target, int done, String eta) { if (!eta.isEmpty()) { progress.setProgress(taskName, done, 0, target, eta); } else { progress.setProgress(taskName, done, 0, target); } } public final Task task(String taskName) { return task(taskName, 1); } public Task task(String taskName, int taskSize) { Task task = taskBuilder.newTask(this, currentTask, taskName, taskSize); currentTask = task; task.update(); return task; } public Task backgroundTask() { return backgroundTask; } }