Mercurial > hg > ltpda
view src/MPipeline/src/mpipeline/MElementWithPorts.java @ 49:0bcdf74587d1 database-connection-manager
Cleanup
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 07 Dec 2011 17:24:36 +0100 |
parents | f0afece42f48 |
children |
line wrap: on
line source
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package mpipeline; import java.awt.Color; import java.awt.Dimension; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; /** * * @author hewitson */ public class MElementWithPorts extends MElementSelectableResizable { /** * */ protected MBlockCore blockCore = new MBlockCore(); /** * */ protected MBlockNameLabel nameView = new MBlockNameLabel("New Element"); /** * */ protected int defaultHmargin = 6; /** * */ protected int defaultVmargin = 9; /** * */ protected int hMargin = defaultHmargin; /** * */ protected int vMargin = defaultVmargin; /** * */ protected Dimension defaultPortDimension = new Dimension(5, 5); /** * */ protected Dimension portDimension = new Dimension(5, 5); /** * */ protected ArrayList<MPort> inputs = new ArrayList<MPort>(); /** * */ protected ArrayList<MPort> outputs = new ArrayList<MPort>(); /** * */ protected boolean ready = false; /** * */ protected boolean executed = false; /** * */ public final static int READY = 0; /** * */ public final static int EXECUTED = 1; /** * */ public final static int IDLE = 2; /** * */ protected static Color readyColor = new Color(0, 180, 10); //Color.green; /** * */ protected static Color executedColor = new Color(210, 190, 255); //Color.cyan; /** * */ protected Color idleColor = new Color(170, 200, 255); /** * Move the block by dx and dy * @param dx * @param dy */ @Override public void translate(int dx, int dy) { super.translate(dx, dy); // we also need to update any connected pipes, so // ... // iterate over my inputs and outputs Iterator it = inputs.iterator(); while (it.hasNext()) { MPort p = (MPort) it.next(); if (p.getNode() != null) { p.getNode().translate(dx, dy); } } it = outputs.iterator(); while (it.hasNext()) { MPort p = (MPort) it.next(); if (p.getNode() != null) { p.getNode().translate(dx, dy); } } // MCanvas c = (MCanvas) getParent(); // c.setNotSaved(); } /** * Is this block a modifier? * * @return */ public boolean isModifier() { return false; } /** * Return the number of inputs ports on this block. * * @return */ public int getNumInputs() { return inputs.size(); } /** * Return the number of output ports on this block. * * @return */ public int getNumOutputs() { return outputs.size(); } public ArrayList<MPipe> getMyInputPipes() { ArrayList<MPipe> pipes = new ArrayList<MPipe>(); // go over all inputs Iterator it = inputs.iterator(); while (it.hasNext()) { MPort p = (MPort) it.next(); if (p.getNode() != null) { MNode n = p.getNode(); pipes.addAll(n.getPipes()); } } return pipes; } public ArrayList<MPipe> getMyOutputPipes() { ArrayList<MPipe> pipes = new ArrayList<MPipe>(); // go over all inputs Iterator it = outputs.iterator(); while (it.hasNext()) { MPort p = (MPort) it.next(); if (p.getNode() != null) { MNode n = p.getNode(); pipes.addAll(n.getPipes()); } } return pipes; } /** * Check if the given input port number is free to be used. * * @param n * @return */ public boolean isInputPortFree(int n) { if (inputs.size() < n + 1) { return true; } MPort p = inputs.get(n); if (p == null) { return true; } if (p.getNode() == null) { return true; } else { return false; } } /** * Returns the number of the next free input port, or creates a new port * if no free input is found. The number of the new port is then returned. * * @return */ public int getNextFreeInput() { Iterator it = inputs.iterator(); int n = 0; while (it.hasNext()) { MPort p = (MPort) it.next(); if (p.getNode() == null) { return n; } n++; } // then add a new input addInput(); MPort lastPort = inputs.get(inputs.size()-1); return lastPort.getNumber(); } /** * Set up the block name label */ protected void setupBlockNameView() { nameView.setText(getName()); nameView.setBounds(5, getHeight() - vMargin, getWidth() - 10, vMargin); } protected int getFirstFreePortNumber(ArrayList<MPort> ports) { int pnum = 0; boolean run = true; while (run) { // System.out.println("Checking for port number: " + pnum); // check for this port boolean portFound = false; Iterator it = ports.iterator(); while (it.hasNext()) { MPort p = (MPort) it.next(); // System.out.println(" have port " + p.getNumber()); if (p.getNumber() == pnum) { portFound = true; break; } } if (portFound) { pnum++; } else { run = false; } } // System.out.println(" returning port " + pnum); return pnum; } /** * Add an input port to the block. * */ public void addInput() { MPort p = new MPort(0); p.setMyElement(this); // find the first free port number int pnum = getFirstFreePortNumber(inputs); p.setNumber(pnum); inputs.add(p); setupPorts(inputs); this.add(p, 0); revalidate(); MCanvas c = (MCanvas) getParent(); if (c != null) { c.setNotSaved("Added input"); } } public MPort createInput(Integer pnum) { // check existing ports boolean portExists = false; Iterator it = inputs.iterator(); while (it.hasNext()) { MPort p = (MPort) it.next(); if (p.getNumber() == pnum) { portExists = true; } } if (portExists) { System.err.println("Can't create an input port with number " + pnum + "; it already exists"); return null; } else { MPort p = new MPort(0); p.setMyElement(this); // find the first free port number p.setNumber(pnum); inputs.add(p); setupPorts(inputs); this.add(p, 0); revalidate(); MCanvas c = (MCanvas) getParent(); if (c != null) { c.setNotSaved("Added input"); } return p; } } public MPort createOutput(Integer pnum) { // check existing ports boolean portExists = false; Iterator it = outputs.iterator(); while (it.hasNext()) { MPort p = (MPort) it.next(); if (p.getNumber() == pnum) { portExists = true; } } if (portExists) { System.err.println("Can't create an output port with number " + pnum + "; it already exists"); return null; } else { MPort p = new MPort(1); p.setMyElement(this); // find the first free port number p.setNumber(pnum); outputs.add(p); setupPorts(outputs); this.add(p, 0); revalidate(); MCanvas c = (MCanvas) getParent(); if (c != null) { c.setNotSaved("Added output"); } return p; } } /** * Remove the specified input port from the block. * * Give a value of null to remove the last added port. * * @param p */ public void removeInput(MPort p) { if (p == null) { p = inputs.get(inputs.size() - 1); } if (!inputs.isEmpty()) { // remove any node if (p.getNode() != null) { p.getNode().delete(); } this.remove(p); // remove from list inputs.remove(p); // reposition ports setupPorts(inputs); revalidate(); repaint(); MCanvas c = (MCanvas) getParent(); c.setNotSaved("Removed input"); } } /** * Add a new output port to the block. * */ public void addOutput() { MPort p = new MPort(1); p.setMyElement(this); // find the first free port number int pnum = getFirstFreePortNumber(outputs); p.setNumber(pnum); outputs.add(p); setupPorts(outputs); this.add(p, 0); revalidate(); MCanvas c = (MCanvas) getParent(); if (c != null) { c.setNotSaved("Added output"); } } /** * Remove the specified output port from the block. * * Give a value of null to remove the last added port. * * @param p */ void removeOutput(MPort p) { if (p == null) { // System.out.println("Removing last output port"); p = outputs.get(outputs.size() - 1); } if (!outputs.isEmpty()) { // just remove the pipes MCanvas c = (MCanvas) getParent(); c.deletePipes(p.getMypipes()); this.remove(p); outputs.remove(p); setupPorts(outputs); revalidate(); repaint(); c.setNotSaved("Removed output"); } } /** * Return an array of blocks that are one step downstream of this * block. * * @return */ public ArrayList<MElementWithPorts> getChildBlocks() { ArrayList<MElementWithPorts> oblocks = new ArrayList<MElementWithPorts>(); // Iterate over output ports MCanvas c = (MCanvas) getParent(); // System.out.println("Looking for children blocks of: " + c.getMyDiagramTitle() + " / " + getName()); Iterator it = outputs.iterator(); while (it.hasNext()) { MPort op = (MPort) it.next(); if (op.getNode() != null) { MNode n = op.getNode(); // follow all pipes to the next blocks ArrayList<MPipe> pipes = n.getPipes(); Iterator pit = pipes.iterator(); while (pit.hasNext()) { MPipe pipe = (MPipe) pit.next(); MNode dnode = pipe.getDstNode(); MElementWithPorts db = (MElementWithPorts) dnode.getPort().getParent(); // If this is a subsystem, then we either need to step inside // or move on if all inside blocks are executed. if (db instanceof MSubsystem) { MSubsystem ss = (MSubsystem) db; // if this is the input to a subsystem, we should jump over // the terminal and get the block inside ss.setState(MElementWithPorts.READY); // System.out.println("Entering subsystem: " + ss.getMyDiagTitle()); MPort p = dnode.getPort(); // get the terminal inside MTerminal t = p.getMyTerm(); t.setState(MElementWithPorts.EXECUTED); oblocks.addAll(t.getChildBlocks()); } else if (db instanceof MTerminal) { // If this is an output terminal of a subsystem then // we should jump out to the block outside MTerminal t = (MTerminal) db; // System.out.println(" found a terminal: " + t.getName()); // t.display(); if (!t.isInputTerminal()) { // if the subsystem is completely executed // we can go down-stream of it. MCanvas pc = (MCanvas) t.getParent(); BlockDiagram bd = pc.getBlockDiagram(); MSubsystem pss = bd.getMySubsystem(); if (pss.executed) { oblocks.addAll(pss.getChildBlocks()); } } } else { // System.out.println(" adding block to list: " + db.getName()); oblocks.add(db); } } } } return oblocks; } /** * Get the block that is the source of the given port for this block. * @param port * @return */ public MElementWithPorts getSourceBlock(int port) { // System.out.println("Getting source block for " + getName() + "[" + port + "]"); MPort p = getInput(port); if (p != null) { MNode n = p.getMynode(); if (n != null) { ArrayList<MPipe> pipes = n.getPipes(); if (pipes.size() > 0) { MPipe pipe = pipes.get(0); MNode sn = pipe.getSrcNode(); MPort sp = sn.getMyport(); MElementWithPorts sb = (MElementWithPorts) sp.getParent(); if (sb instanceof MTerminal) { // System.out.println("Found terminal: " + sb.getName()); // step out of the subsystem to the input block return sb.getSourceBlock(port); } else if (sb instanceof MSubsystem) { // System.out.println("Found subsystem: " + sb.getName()); // step back inside the subsystem to get the src block MSubsystem ss = (MSubsystem) sb; return ss.getSourceBlockForOutputPort(sp.getNumber()); } else { // System.out.println("Found source block " + sb.getName()); return sb; } } } } return null; } /** * Get the number of the port that is the source of the given port for this block. * @param port * @return */ public int getSourceBlockPortNumber(int port) { // System.out.println("Getting source block for " + getName() + "[" + port + "]"); MPort p = getInput(port); if (p != null) { MNode n = p.getMynode(); if (n != null) { ArrayList<MPipe> pipes = n.getPipes(); if (pipes.size() > 0) { MPipe pipe = pipes.get(0); MNode sn = pipe.getSrcNode(); MPort sp = sn.getMyport(); MElementWithPorts sb = (MElementWithPorts) sp.getParent(); if (sb instanceof MTerminal) { // System.out.println("Found terminal: " + sb.getName()); // step out of the subsystem to the input block return sb.getSourceBlockPortNumber(0); } else if (sb instanceof MSubsystem) { // step back inside the subsystem to get the src block // System.out.println("Found subsystem: " + sb.getName()); MSubsystem ss = (MSubsystem) sb; return ss.getSourceBlockPortForOutputPort(sp.getNumber()); } else { // System.out.println("Found source block " + sb.getName()); return sp.getNumber(); } } } } return -1; } /** * Returns a string that represents a variable name for * the output of the src block connected to this input. * * Format is: srcBlockName_PORT# * * * @param input * @return */ public String getSrcBlockPortName(int input) { if (input < inputs.size()) { MPort p = inputs.get(input); MNode n = p.getNode(); if (n != null) { MPipe pp = n.getPipes(0); MNode sn = pp.getSrcNode(); MPort sp = sn.getPort(); int pn = sp.getNumber(); MElementWithPorts srcblock = (MElementWithPorts) sp.getParent(); return srcblock.getName() + "_PORT" + pn; } } return ""; } /** * * @param port * @return */ public String getVarName(int port) { //[strrep(char(block.getName()), ' ', '_') '_PORT' num2str(kk-1)]; MCanvas mc = (MCanvas) getParent(); String varname = mc.getFullAncestorName() + "." + getName(); varname = varname.replaceAll("\\s", "_"); // varname = varname.replaceAll("\\W+", "_"); varname += "_PORT" + port; return varname; } /** * Setup the array of ports. The positions of the ports are * set based on the number and the size of the block. * * @param ports */ protected void setupPorts(ArrayList<MPort> ports) { int nPorts = ports.size(); // System.out.println("Setting up ports: " + nPorts); // System.out.println(" my height: " + getHeight()); // System.out.println(" port dim: " + portDimension.getHeight()); // System.out.println(" vmargin: " + vMargin); // System.out.println(" space: " + (1.0*getHeight() - nPorts * portDimension.getHeight() - 2 * vMargin)); int dy = (int) Math.round((1.0 * getHeight() - nPorts * portDimension.getHeight() - 2 * vMargin) / (nPorts + 1.0)); // System.out.println("dy = " + dy); if (dy >= 0) { if (dy < 4) { setMySize(getWidth(), (int) Math.round(1.3 * getHeight())); dy = (int) Math.round((1.0 * getHeight() - nPorts * portDimension.getHeight() - 2 * vMargin) / (nPorts + 1.0)); } Iterator it = ports.iterator(); int y = (int) (dy + vMargin); int n = 0; while (it.hasNext()) { MPort p = (MPort) it.next(); p.setSize(portDimension); int xOff; if (p.getType() == MPort.INPUT) { // input xOff = (int) (hMargin); } else { // output xOff = (int) (getSize().width - p.getWidth() - hMargin); } p.setLocation(xOff, y); // move node connected to this port if (p.getNode() != null) { p.getNode().moveTo(getX() + xOff, getY() + y); } y += (int) (dy + portDimension.getHeight()); n++; } } revalidate(); } /** * Set the state of the block. * * 0 = ready to execute * 1 = executed * 2 = idle * * @param state */ public void setState(int state) { // java.awt.EventQueue.invokeLater(new Runnable() { // // public void run() { switch (state) { case MBlock.READY: // System.out.println("Setting state to READY for block: " + getName()); ready = true; executed = false; blockCore.setDefaultBackgroundColor(readyColor); break; case MBlock.EXECUTED: // System.out.println("Setting state to EXECUTED for block: " + getName()); ready = false; executed = true; blockCore.setDefaultBackgroundColor(executedColor); break; case MBlock.IDLE: // System.out.println("Setting state to IDLE for block: " + getName()); ready = false; executed = false; blockCore.setDefaultBackgroundColor(idleColor); break; default: // System.out.println("Setting state to IDLE for block: " + getName()); ready = false; executed = false; blockCore.setDefaultBackgroundColor(idleColor); break; } revalidate(); repaint(); // } // }); } /** * Set this block to the ready state. * @param state */ public void setReady(boolean state) { ready = state; if (ready) { blockCore.setDefaultBackgroundColor(readyColor); } else { blockCore.setDefaultBackgroundColor(idleColor); } } /** * Set the executed state of the block * * @param state */ public void setExecuted(boolean state) { executed = state; if (executed) { blockCore.setDefaultBackgroundColor(executedColor); } else { blockCore.setDefaultBackgroundColor(idleColor); } } /** * Can this block be executed? * * If all previous blocks in the pipeline have been * executed, then yes. * * @return */ public boolean canExecute() { // System.out.println("Checking if block can execute: " + getName()); boolean canex = true; // look at all my input ports Iterator it = inputs.iterator(); while (it.hasNext()) { MPort in = (MPort) it.next(); // get node MNode n = in.getNode(); if (n != null) { // get pipe MPipe pipe = n.getPipes(0); // get the src node MNode sn = pipe.getSrcNode(); // get src block MElementWithPorts sb = (MElementWithPorts) sn.getPort().getParent(); if (!sb.hasExecuted()) { canex = false; } } } return canex; } /** * */ public void reset() { setSelected(false); setExecuted(false); } /** * Returns true if the block has no connected inputs, and at least one * connected output. * @return */ public boolean isRootBlock() { boolean isrootblock = false; // check inputs Iterator it = inputs.iterator(); boolean hasInNode = false; while (it.hasNext()) { MPort ip = (MPort) it.next(); if (ip.getNode() != null) { hasInNode = true; } } // check outputs it = outputs.iterator(); boolean hasOutNode = false; while (it.hasNext()) { MPort ip = (MPort) it.next(); if (ip.getNode() != null) { hasOutNode = true; } } // if (!hasInNode & hasOutNode) { if (!hasInNode) { isrootblock = true; } return isrootblock; } /** * * @param b * @return * @throws java.io.IOException * @throws java.lang.ClassNotFoundException */ public static MElementWithPorts copy(MElementWithPorts b) throws IOException, ClassNotFoundException { return (MElementWithPorts) MElement.copy(b); } /** * Returns true if the block is ready to execute. * * @return */ public boolean isReady() { if (ready) { return true; } else { return false; } } /** * Returns true if the block is idle. * * @return */ public boolean isIdle() { if (!ready & !executed) { return true; } else { return false; } } protected String getPortNumberString(ArrayList<MPort> ports) { String ips = ""; Iterator iit = ports.iterator(); while (iit.hasNext()) { MPort p = (MPort) iit.next(); ips += "" + p.getNumber() + " "; } return ips; } /** * Get the given input port of this block. * @param sp * @return */ public MPort getInput(int sp) { // System.out.println("asked for input " + sp); // System.out.println(" but I have inputs: " + inputs.size()); Iterator it = inputs.iterator(); while (it.hasNext()) { MPort tp = (MPort) it.next(); if (tp.getNumber() == sp) { return tp; } } // or make a new port, if the port doesn't already exist MPort np = createInput(sp); // while (inputs.size() < sp + 1) { // // add a new input // System.out.println("--- adding an input"); // createInput(); // } return np; } /** * Get the given output port of this block. * @param sp * @return */ public MPort getOutput(int sp) { Iterator it = outputs.iterator(); while (it.hasNext()) { MPort tp = (MPort) it.next(); if (tp.getNumber() == sp) { return tp; } } // System.out.println("asked for output " + sp); // System.out.println(" but I have outputs: " + outputs.size()); while (outputs.size() < sp + 1) { // add a new input // System.out.println("--- adding an output"); addOutput(); } return outputs.get(sp); } /** * Reset all ports to have null nodes. */ public void resetAllPorts() { Iterator pit = inputs.iterator(); while (pit.hasNext()) { MPort p = (MPort) pit.next(); p.setNode(null); } pit = outputs.iterator(); while (pit.hasNext()) { MPort p = (MPort) pit.next(); p.setNode(null); } } /** * Return the executed state of this block. * @return */ protected boolean hasExecuted() { return executed; } /** * Return the array of input ports for this block. * @return */ public ArrayList<MPort> getInputs() { return inputs; } /** * Return the array of output ports for this block. * @return */ public ArrayList<MPort> getOutputs() { return outputs; } /** * Return the core of this block. * @return */ public MBlockCore getBlockCore() { return blockCore; } /** * Make the block larger. * */ @Override public void scaleElement() { super.scaleElement(); // change margins hMargin = Math.round(scaleFactor * defaultHmargin); vMargin = Math.round(scaleFactor * defaultVmargin); // increase size of ports portDimension.width = Math.round(defaultPortDimension.width * scaleFactor); portDimension.height = Math.round(defaultPortDimension.height * scaleFactor); if (portDimension.width < 3) { portDimension.width = 3; } if (portDimension.height < 3) { portDimension.height = 3; } setupHandles(); setBlockCoreBounds(); setupPorts(inputs); setupPorts(outputs); nameView.scaleFontSize(scaleFactor); setupBlockNameView(); revalidate(); repaint(); } /** * Set if this block can act as a modifier * * @param state */ public void setIsModifier(boolean state) { } @Override public void setName(String name) { myName = name; super.setName(myName); setupBlockNameView(); revalidate(); repaint(); } /** * Set the size of this block. * */ @Override public void setMySize(int w, int h) { mySize.width = w; mySize.height = h; setBounds(getX(), getY(), w, h); setupHandles(); setBlockCoreBounds(); setupBlockNameView(); setupPorts(inputs); setupPorts(outputs); revalidate(); } /** * Resize this block. * * @param dx * @param dy * @param minWidth * @param minHeight */ @Override public void resizeMe(int dx, int dy, int minWidth, int minHeight) { super.resizeMe(dx, dy, minWidth, minHeight); setBlockCoreBounds(); setupBlockNameView(); setupPorts(inputs); setupPorts(outputs); revalidate(); } /** * Set the size and position of the core block given the sizes * of the margins and ports. */ protected void setBlockCoreBounds() { blockCore.setBounds(hMargin + portDimension.width, vMargin, this.getWidth() - 2 * hMargin - 2 * portDimension.width, this.getHeight() - 2 * vMargin); } /** * */ public void display() { String header = "-------" + getName() + "--------"; String footer = "-"; while (footer.length() < header.length()) { footer += "-"; } System.out.println(header); System.out.println(" num inputs: " + inputs.size()); System.out.println("num outputs: " + outputs.size()); System.out.println(footer); } /** * * @return */ public int getDefaultHmargin() { return defaultHmargin; } /** * * @param defaultHmargin */ public void setDefaultHmargin(int defaultHmargin) { this.defaultHmargin = defaultHmargin; } /** * * @return */ public Dimension getDefaultPortDimension() { return defaultPortDimension; } /** * * @param defaultPortDimension */ public void setDefaultPortDimension(Dimension defaultPortDimension) { this.defaultPortDimension = defaultPortDimension; } /** * * @return */ public int getDefaultVmargin() { return defaultVmargin; } /** * * @param defaultVmargin */ public void setDefaultVmargin(int defaultVmargin) { this.defaultVmargin = defaultVmargin; } /** * * @return */ public static Color getExecutedColor() { return executedColor; } /** * * @return */ public int getHMargin() { return hMargin; } /** * * @param hMargin */ public void setHMargin(int hMargin) { this.hMargin = hMargin; } /** * * @return */ public Color getIdleColor() { return idleColor; } /** * * @param c */ public void setIdleColor(Color c) { this.idleColor = c; } /** * * @return */ public MBlockNameLabel getNameView() { return nameView; } /** * * @param nameView */ public void setNameView(MBlockNameLabel nameView) { this.nameView = nameView; } /** * * @return */ public Dimension getPortDimension() { return portDimension; } /** * * @param portDimension */ public void setPortDimension(Dimension portDimension) { this.portDimension = portDimension; } /** * * @return */ public static Color getReadyColor() { return readyColor; } /** * * @return */ public int getVMargin() { return vMargin; } /** * * @param vMargin */ public void setVMargin(int vMargin) { this.vMargin = vMargin; } }