/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2016 Neil C Smith. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 only, as * published by the Free Software Foundation. * * This code 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 * version 3 for more details. * * You should have received a copy of the GNU General Public License version 3 * along with this work; if not, see http://www.gnu.org/licenses/ * * * Please visit http://neilcsmith.net if you need additional information or * have any questions. */ package net.neilcsmith.praxis.live.util; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayDeque; import java.util.Arrays; import java.util.Queue; import net.neilcsmith.praxis.live.core.api.Task; /** * * @author Neil C Smith (http://neilcsmith.net) */ public class SerialTasks extends AbstractTask { private final Queue<Task> tasks; private final Listener listener; private Task activeTask; public SerialTasks(Task ... tasks) { this.tasks = new ArrayDeque<>(Arrays.asList(tasks)); listener = new Listener(); } @Override protected void handleExecute() throws Exception { if (tasks.isEmpty()) { updateState(State.COMPLETED); return; } handleTaskQueue(); } private void handleTaskQueue() { while (!tasks.isEmpty()) { activeTask = tasks.poll(); State state = activeTask.execute(); if (state == State.RUNNING) { activeTask.addPropertyChangeListener(listener); return; } if (state == State.ERROR || state == State.CANCELLED) { updateState(state); return; } } updateState(State.COMPLETED); } @Override protected boolean handleCancel() { boolean cancelled = true; if (activeTask != null) { cancelled = activeTask.cancel(); } if (cancelled) { for (Task task : tasks) { task.cancel(); } } return cancelled; } private class Listener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { assert evt.getSource() == activeTask; if (getState() == State.RUNNING && evt.getSource() == activeTask) { State taskState = activeTask.getState(); if (taskState == State.RUNNING) { assert false; return; } activeTask.removePropertyChangeListener(this); if (taskState == State.COMPLETED) { handleTaskQueue(); } else if (taskState == State.CANCELLED || taskState == State.ERROR) { updateState(taskState); } } } } }