/******************************************************************************* * Copyright (c) 2012-present Jakub Kováč, Jozef Brandýs, Katarína Kotrlová, * Pavol Lukča, Ladislav Pápay, Viktor Tomkovič, Tatiana Tóthová * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package algvis.core; import algvis.core.history.UpdatableStateEdit; import algvis.core.visual.DoubleArrow; import algvis.core.visual.Edge; import algvis.core.visual.ShadePair; import algvis.core.visual.ShadeSubtree; import algvis.core.visual.ShadeTriple; import algvis.core.visual.TextBubble; import algvis.core.visual.VisualElement; import algvis.internationalization.IIntParamString; import algvis.internationalization.IParamString; import algvis.internationalization.IString; import algvis.ui.NewVisPanel; import algvis.ui.VisPanel; import algvis.ui.view.REL; import java.awt.EventQueue; import java.util.HashMap; import java.util.concurrent.Semaphore; /** * The Class Algorithm. Each visualized data structure consists of data and * algorithms (such as insert, delete) that update the data. All such algorithms * are descendants of the class Algorithm. * <p/> * A visualized algorithm has its own thread which can be suspended (e.g., after * each step of the algorithm; see method pause) and is automatically resumed * (method myresume) after pressing the "Next" button. */ abstract public class Algorithm implements Runnable { private final VisPanel panel; private volatile boolean done = false; private UpdatableStateEdit panelState; private boolean wrapped = false; private Algorithm wrapperAlg; protected Algorithm(VisPanel panel) { this.panel = panel; wrapperAlg = null; wrapped = false; } protected Algorithm(VisPanel panel, Algorithm a) { this(panel); wrapperAlg = a; wrapped = (a != null); } @Override public void run() { panel.D.A = this; begin(); runAlgorithm(); end(); } public abstract void runAlgorithm(); protected void pause() { if (wrapped) { wrapperAlg.pause(); } else { //System.out.println("panel state end"); panelState.end(); //System.out.println("new panel state"); panelState = new UpdatableStateEdit(panel, panel.history.getNextId()); panel.history.addEdit(panelState); panel.scene.next(); } } protected void setHeader(String s) { if (!wrapped && !(panel instanceof NewVisPanel)) { // TODO: just until // we get rid of the // old VisPanel panel.commentary.setHeader(s); } } protected void setHeader(String s, String... par) { if (!wrapped && !(panel instanceof NewVisPanel)) { panel.commentary.setHeader(s, par); } } protected void setHeader(String s, int... par) { if (!wrapped && !(panel instanceof NewVisPanel)) { panel.commentary.setHeader(s, par); } } protected void addNote(String s) { if (!(panel instanceof NewVisPanel)) { panel.commentary.addNote(s); } } public void addNote(String s, String[] par) { if (!(panel instanceof NewVisPanel)) { panel.commentary.addNote(s, par); } } protected void addNote(String s, int... par) { if (!(panel instanceof NewVisPanel)) { panel.commentary.addNote(s, par); } } protected void addStep(int x, int y, int w, REL pos, String s) { addToSceneUntilNext(new TextBubble(new IString(s), x, y, w, pos)); } protected void addStep(int x, int y, int w, REL pos, String s, String... par) { addToSceneUntilNext(new TextBubble(new IParamString(s, par), x, y, w, pos)); } protected void addStep(int x, int y, int w, REL pos, String s, int... par) { addToSceneUntilNext(new TextBubble(new IIntParamString(s, par), x, y, w, pos)); } protected void addStep(Node v, REL pos, String s) { addToSceneUntilNext(new TextBubble(new IString(s), v.tox, v.toy, 200, pos)); } protected void addStep(Node v, REL pos, String s, String... par) { addToSceneUntilNext(new TextBubble(new IParamString(s, par), v.tox, v.toy, 200, pos)); } protected void addStep(Node v, REL pos, String s, int... par) { addToSceneUntilNext(new TextBubble(new IIntParamString(s, par), v.tox, v.toy, 200, pos)); } protected void addStep(String s) { if (!(panel instanceof NewVisPanel)) { panel.commentary.addStep(s); } } protected void addStep(String s, String... par) { if (!(panel instanceof NewVisPanel)) { panel.commentary.addStep(s, par); } } protected void addStep(String s, int... par) { if (!(panel instanceof NewVisPanel)) { panel.commentary.addStep(s, par); } } protected void addToScene(VisualElement element) { if (wrapped) { wrapperAlg.addToScene(element); } else { panel.scene.add(element); panelState.addToPreState(element); } } protected void addToSceneUntilNext(VisualElement element) { if (wrapped) { wrapperAlg.addToSceneUntilNext(element); } else { panel.scene.addUntilNext(element); panelState.addToPreState(element); } } protected void removeFromScene(VisualElement element) { if (element == null) return; // if (panel.pauses) { panel.scene.remove(element); // } else { // element.removeFromSceneNow(); // } } void begin() { panelState = new UpdatableStateEdit(panel, panel.history.getNextId()); panel.history.addEdit(panelState); if (!(panel instanceof NewVisPanel)) { panel.commentary.clear(); } EventQueue.invokeLater(new Runnable() { @Override public void run() { panel.buttons.refresh(); } }); } void end() { panel.D.setStats(); panelState.end(); panel.history.putAlgorithmEnd(); this.done = true; EventQueue.invokeLater(new Runnable() { @Override public void run() { panel.refresh(); } }); } public boolean isDone() { return done; } public HashMap<String, Object> getResult() { return null; } }