/** * @file .java * @author Anderson Antunes <anderson.utf@gmail.com> * *seu nome* <*seu email*> * @version 1.0 * * @section LICENSE * * Copyright (C) 2013 by Anderson Antunes <anderson.utf@gmail.com> * *seu nome* <*seu email*> * * RobotInterface 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. * * RobotInterface 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 * RobotInterface. If not, see <http://www.gnu.org/licenses/>. * */ package robotinterface.algorithm.procedure; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import org.nfunk.jep.JEP; import robotinterface.algorithm.Command; import org.nfunk.jep.SymbolTable; import org.nfunk.jep.Variable; import robotinterface.drawable.GraphicObject; import robotinterface.drawable.graphicresource.GraphicResource; import robotinterface.gui.panels.sidepanel.Item; import robotinterface.interpreter.ExecutionException; import robotinterface.interpreter.ResourceManager; import robotinterface.interpreter.ResourceNotFoundException; import robotinterface.robot.Robot; import robotinterface.util.trafficsimulator.Clock; /** * Bloco de comandos com suporte a escopo de variável. */ public class Block extends Procedure { /** * Classe usada para definir o final de um loop. */ public class BlockEnd extends Command { protected Command begin; protected BlockEnd() { } /** * Define o inicio do bloco de coamndos. * * @param b Bloco de comando. */ public void setBlockBegin(Command b) { begin = b; } /** * Reseta o escopo de variável e retorna o bloco de comandos que * pertence. */ @Override public Command step(ResourceManager rm) throws ResourceNotFoundException { returnNext = true; resetVariableScope(rm); return begin; } @Override public GraphicObject getDrawableResource() { return null; } } protected Command start; protected boolean returnNext = false; protected boolean breakLoop = false; private BlockEnd end; public Block() { setEnd(new BlockEnd()); start = end; } public void clear() { start = end; end.setNext(null); end.setPrevious(null); } public final Command getStart() { return start; } public Command shiftStart() { if (start != null && start != end) { start = start.getNext(); } return start; } public final BlockEnd getEnd() { return end; } public final void setEnd(BlockEnd end) { if (this.end != null) { end.setNext(this.end.getNext()); end.setPrevious(this.end.getPrevious()); } end.setBlockBegin(this); end.setParent(this); this.end = end; } public final boolean add(Command c) { if (c == null) { return false; } c.setParent(this); //pega o elemento antes do ultimo Command begin = end.getPrevious(); Command it = c; while (it.getNext() != null) { it.setParent(this); it = it.getNext(); } it.setNext(end); it.setParent(this); end.setPrevious(c); end.setNext(null); //adiciona end ao final da lista if (begin != null) { //...<-it<->c<->end->null begin.setNext(c); c.setPrevious(begin); } else { start = c; } return true; } // public final boolean addAfter(Command x, Command c) { // if (contains(x) && c != null) { // c.setPrevious(x); // c.setNext(x.getNext()); // x.getNext().setPrevious(c); // x.setNext(c); // c.setParent(this); // } // return false; // } public final boolean addAfter(Command x, Command c) { if (c == null || x == null) { return false; } c.setParent(this); //pega o elemento antes do ultimo Command begin = x; Command it = c; while (it != null && it.getNext() != x) { it = it.getNext(); } //begin<->c<->...<->end<->begin.next if (it != null && begin.getNext() != null) { it.setNext(begin.getNext()); begin.getNext().setPrevious(it); begin.setNext(c); c.setPrevious(begin); return true; } else { return false; } } /** * Obtem o numero de comandos dentro do bloco. * * @return O numero de comandos dentro desse bloco */ public final int size() { int size = 0; Command it = start; while (it != null) { size++; it = it.getNext(); } return size; } //não protege o final! public final int indexOf(Command c) { int index = 0; Command it = start; while (it != null) { if (it == c) { return index; } it = it.getNext(); index++; } return -1; } //não protege o final! public final Command get(int index) { int i = 0; Command it = start; while (it != null) { if (i == index) { return it; } it = it.getNext(); i++; } return null; } //protege o final public final boolean remove(int index) { int i = 0; Command it = start; while (it != null) { if (i == index) { if (it == end) { return false; //protege o final } Command prev = it.getPrevious(); Command next = it.getNext(); if (prev != null) { prev.setNext(it.getNext()); } else { start = it; } if (next != null) { next.setPrevious(it.getPrevious()); } return true; } it = it.getNext(); i++; } return false; } //protege o final public final boolean remove(Command c) { int i = indexOf(c); if (i >= 0) { remove(i); return true; } return false; } public final boolean contains(Command c) { return (indexOf(c) >= 0); } public final boolean addBegin(Command c) { return addBefore(start, c); } public final boolean addBefore(Command x, Command c) { if (contains(x)) { Command prev = x.getPrevious(); if (prev != null) { addAfter(prev, c); } else { x.setPrevious(c); c.setNext(x); start = c; } c.setParent(this); } return false; } //função executada ao final do bloco protected void reset() { } //remove todas as variaveis definidas dentro do bloco private void resetVariableScope(ResourceManager rm) throws ResourceNotFoundException { JEP parser = rm.getResource(JEP.class); SymbolTable st = parser.getSymbolTable(); Command it = start; while (it != null) { if (it instanceof Procedure) { for (String varName : ((Procedure) it).getVariableNames()) { Variable remove = st.getVar(varName); if (remove != null) { // System.out.println("Removed var: " + remove.getName()); remove.setValidValue(false); } } } it = it.getNext(); } } public boolean isDone() { return returnNext; } public void setDone(boolean b) { returnNext = b; } public void breakLoop(boolean b) { breakLoop = b; } @Override public boolean perform(ResourceManager rm) throws ExecutionException { return true; } @Override public Command step(ResourceManager rm) throws ExecutionException { if (returnNext) { returnNext = false; reset(); return super.step(rm); } else { return start; } } @Override public void toString(String ident, StringBuilder sb) { //sb.append(ident).append("").append("{\n"); Command it = start; while (it != null) { it.toString(ident + identChar, sb); it = it.getNext(); } //sb.append(ident).append("}\n"); } @Override public Rectangle2D.Double getBounds(Rectangle2D.Double tmp, double j, double k) { tmp = super.getBounds(tmp, j, k); Rectangle2D.Double p = new Rectangle2D.Double(); Command it = this.start; // boolean ident = true; while (it != null) { p = it.getBounds(p, j, k); tmp.x = (p.x < tmp.x) ? p.x : tmp.x; tmp.y = (p.y < tmp.y) ? p.y : tmp.y; tmp.width = (p.width > tmp.width) ? p.width : tmp.width; tmp.height += p.height; // if (it instanceof If) { // ident = false; // } it = it.getNext(); } // tmp.x -= j; // tmp.width += 2 * j; return tmp; } @Override public final void ident(double x, double y, double j, double k) { double cw = 0; double ch = 0; Rectangle2D.Double t = null; if (this instanceof GraphicResource) { GraphicObject d = ((GraphicResource) this).getDrawableResource(); if (d != null) { t = (Rectangle2D.Double) d.getObjectBouds(); } } if (t != null) { cw = t.width; ch = t.height; double px = x - cw / 2; double py = y; if (this instanceof GraphicResource) { GraphicObject d = ((GraphicResource) this).getDrawableResource(); if (d != null) { d.setLocation(px, py); } } y += ch + j; } start.ident(x, y, j, k); if (getNext() != null) { getNext().ident(x, y + this.getBounds(null, j, k).height - (ch + j), j, k); } } @Override public Item getItem() { return super.getItem(); } @Override public Object createInstance() { return new Block(); } @Override public Procedure copy(Procedure copy) { Procedure p = super.copy(copy); if (copy instanceof Block) { if (start instanceof Procedure) { ((Block) copy).add(Procedure.copyAll((Procedure) start)); } } else { System.out.println("Erro ao copiar: "); start.print(); } return p; } @Override public GraphicObject getDrawableResource() { return null; } }