package nl.fontys.sofa.limo.simulation;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import nl.fontys.sofa.limo.simulation.result.SimulationResult;
import nl.fontys.sofa.limo.simulation.task.Simulation;
import org.netbeans.api.progress.aggregate.AggregateProgressFactory;
import org.netbeans.api.progress.aggregate.AggregateProgressHandle;
import org.openide.util.Cancellable;
import org.openide.util.Task;
import org.openide.util.TaskListener;
/**
*
* @author Dominik Kaisers {@literal <d.kaisers@student.fontys.nl>}
*/
public class SimulatorTask implements TaskListener, Cancellable {
private final Map<Task, Simulation> simulations;
private final List<SimulationResult> results;
private Set<SimulatorTaskListener> list;
private final AggregateProgressHandle processHandle;
private final AtomicBoolean cancelled;
public SimulatorTask() {
simulations = new HashMap<>();
results = new ArrayList<>();
processHandle = AggregateProgressFactory.createHandle("Simulating...", null, this, null);
processHandle.start();
System.out.println("-> Starting simulation @ " + new Date());
cancelled = new AtomicBoolean(false);
}
public boolean isDone() {
return results.size() == simulations.size();
}
public double getProgress() {
return (double) results.size() / (double) simulations.size();
}
public List<SimulationResult> getResults() {
return results;
}
protected void addSimulation(Simulation simulation, Task task) {
processHandle.addContributor(simulation.getProgressContributor());
task.addTaskListener(this);
simulations.put(task, simulation);
}
@Override
public void taskFinished(Task task) {
results.add(simulations.get(task).getResult());
if (isDone()) {
processHandle.finish();
if (list != null) {
list.stream().forEach((stl) -> {
stl.taskFinished(this);
});
}
}
}
/**
* Add a listener to the task. The listener will be called once the task
* {@link #taskFinished(Task task)}. In case the task is already finished, the listener
* is called immediately.
*
* @param l the listener to add
*/
public void addTaskListener(SimulatorTaskListener l) {
synchronized (this) {
if (list == null) {
list = new HashSet<>();
}
list.add(l);
}
if (isDone()) {
l.taskFinished(this);
}
}
/**
* Remove a listener from the task.
*
* @param l the listener to remove
*/
public synchronized void removeTaskListener(SimulatorTaskListener l) {
if (list == null) {
return;
}
list.remove(l);
}
@Override
public boolean cancel() {
if (!simulations.values().stream().map((s) -> s.cancel()).noneMatch((canceled) -> (!canceled))) {
return false;
}
cancelled.set(true);
return true;
}
public AtomicBoolean getCancelled() {
return cancelled;
}
}