/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: Wire.java
*
* Copyright (c) 2003 Sun Microsystems and Static Free Software
*
* Electric(tm) 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.
*
* Electric(tm) 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 Electric(tm); see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, Mass 02111-1307, USA.
*/
package com.sun.electric.tool.ncc.netlist;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import com.sun.electric.database.prototype.PortCharacteristic;
import com.sun.electric.tool.ncc.netlist.NccNameProxy.WireNameProxy;
import com.sun.electric.tool.ncc.result.WireReport.WireReportable;
import com.sun.electric.tool.ncc.trees.Circuit;
/** A Wire represents an electrical equipotential.
*/
public class Wire extends NetObject implements WireReportable {
private static final ArrayList<Part> DELETED = null;
// ---------- private data -------------
private ArrayList<Part> parts = new ArrayList<Part>();
private Port port; // usually null because most Wires have no Port
private WireNameProxy nameProxy;
// ---------- public methods ----------
public Wire(WireNameProxy name){nameProxy = name;}
@Override
public String getName() {return nameProxy.getName();}
public WireNameProxy getNameProxy() {return nameProxy;}
public Iterator<Part> getParts() {return parts.iterator();}
@Override
public Iterator getConnected() {return getParts();}
/** add a Part to this Wire
* @param p the Part to add */
public void add(Part p){
error(p==null, "Wires can't add null Part");
parts.add(p);
}
/** add a Port to this Wire
* @param portName the Port to add
*/
public Port addExport(String portName, PortCharacteristic type, boolean oneNamePerPort) {
if (port==null) port = new Port(portName, type, this);
else port.addExport(portName, type, oneNamePerPort);
return port;
}
/** Remove deleted Parts. Remove duplicate Parts. Minimize storage use. */
public void putInFinalForm() {
Set<Part> goodParts = new HashSet<Part>();
for (Iterator<Part> it=getParts(); it.hasNext();) {
Part p = it.next();
if (!p.isDeleted()) goodParts.add(p);
}
parts = new ArrayList<Part>();
parts.addAll(goodParts);
parts.trimToSize();
}
/** @return the Port on this Wire. Return null if wire has no Export
* attached */
public Port getPort() {return port;}
@Override
public Type getNetObjType() {return Type.WIRE;}
/** Mark this wire deleted and release all storage */
public void setDeleted() {parts=DELETED;}
@Override
public boolean isDeleted() {return parts==DELETED;}
/** check that this Wire is properly structured. check each
* connection to see if it points back
* @param parent the wire's parent */
@Override
public void checkMe(Circuit parent){
error(getParent()!=parent, "wrong parent");
for (Iterator<Part> it=getParts(); it.hasNext();) {
NetObject nn=it.next();
error(!(nn instanceof Part), "expecting only parts");
Part pp=(Part)nn;
error(pp.numPinsConnected(this)==0,
"Part not connected back to wire");
}
}
/**
* Does this Wire connect to the given Part?
* @param p the Part to test
* @return true if it touches, false if not
*/
public boolean touches(Part p){return parts.contains(p);}
/** Does this Wire connect to the given Port?
* @param p the Port in question
* @return true if Wire connects to Port p
*/
public boolean touches(Port p) {return port==p;}
public Integer computeHashCode(){
int sum= 0;
for (Iterator<Part> it=getParts(); it.hasNext();) {
Part pp= it.next();
sum += pp.getHashFor(this);
}
return new Integer(sum);
}
/** count the number of Parts connected to this wire.
* @return an int with the number of connections */
public int numParts(){return parts.size();}
/** @return a String describing Cell containing wire and instance path */
@Override
public String instanceDescription() {
// Don't print "Cell instance:" in root Cell where there is no path.
String inst = nameProxy.cellInstPath();
String instMsg = inst.equals("") ? "" : (" Cell instance: "+inst);
return "Wire: "+nameProxy.leafName()+" in Cell: "+
nameProxy.leafCell().libDescribe()+instMsg;
}
@Override
public String valueDescription() {return "";}
/** Get a String indicating up to N connections for this NetObject.
* @param maxParts the maximum number of connections to list
* @return a String of connections. */
@Override
public String connectionDescription(int maxParts){
if (parts.size()==0) return (" unconnected");
String s = " connected to";
if (numParts()>maxParts) s+=" "+parts.size() + " parts starting with";
s += ": ";
int i=0;
for (Iterator<Part> it=getParts(); it.hasNext() && i<maxParts; i++){
Part p = it.next();
String cc = p.instanceDescription();
s += " (" + cc + " Port: " + p.connectionDescription(this)+") ";
}
return s;
}
}