📄 cell.java
字号:
{ if (obj instanceof CellGroup && groupName != null) { return groupName.equals(((CellGroup)obj).groupName); } return this == obj; } /** * Returns a string representing the name of the cell group */ public String getName() { return groupName != null ? groupName.getName() : null; } public EDatabase getDatabase() { return lib.getDatabase(); } /** * Method to check invariants in this CellGroup. * @exception AssertionError if invariants are not valid */ void check() { for (Cell cell : cells) { assert lib.cells.get(cell.getCellName()) == cell; assert cell.cellGroup == this; assert cell.d.groupName.equals(groupName); } if (mainSchematic != null) { assert containsCell(mainSchematic); assert mainSchematic.getNewestVersion() == mainSchematic; } } /** * Method to set the main schematics Cell in ths CellGroup. * The main schematic is the one that is shown when descending into an icon. * Other schematic views may exist in the group, but they are "alternates". * Only one schematic view should be in cell group. * If many schematic views exists then main schematics is the newest version of first in alpahabetical order schematic cell. */ private void setMainSchematics(boolean undo) { if (cells.isEmpty()) { groupName = null; mainSchematic = null; return; } // not set: see if it is obvious List<CellName> cellNames = new ArrayList<CellName>();// String bestName = null; Cell mainSchematic = null; for (Cell cell: cells) { if (cell.isSchematic() && mainSchematic == null) mainSchematic = cell; cellNames.add(cell.getCellName()); } groupName = Snapshot.makeCellGroupName(cellNames); this.mainSchematic = mainSchematic; for (Cell cell: cells) { if (undo) { assert cell.d.groupName.equals(groupName); } else { cell.setD(cell.d.withGroupName(groupName)); } } } } private class MaxSuffix { int v = 0; } // -------------------------- private data --------------------------------- /** Variable key for characteristic spacing for a cell. */ public static final Variable.Key CHARACTERISTIC_SPACING = Variable.newKey("FACET_characteristic_spacing"); /** Variable key for text cell contents. */ public static final Variable.Key CELL_TEXT_KEY = Variable.newKey("FACET_message"); /** Variable key for number of multipage pages. */ public static final Variable.Key MULTIPAGE_COUNT_KEY = Variable.newKey("CELL_page_count"); /** Variable key for font of text in textual cells. */ public static final Variable.Key TEXT_CELL_FONT_NAME = Variable.newKey("CELL_text_font"); /** Variable key for size of text in textual cells. */ public static final Variable.Key TEXT_CELL_FONT_SIZE = Variable.newKey("CELL_text_size"); private static final int[] NULL_INT_ARRAY = {}; private static final Export[] NULL_EXPORT_ARRAY = {}; /** set if instances should be expanded */ public static final int WANTNEXPAND = 02;// /** set if cell is modified */ private static final int MODIFIED = 01000000; /** set if everything in cell is locked */ public static final int NPLOCKED = 04000000; /** set if instances in cell are locked */ public static final int NPILOCKED = 010000000; /** set if cell is part of a "cell library" */ public static final int INCELLLIBRARY = 020000000; /** set if cell is from a technology-library */ public static final int TECEDITCELL = 040000000; /** set if cell is a multi-page schematic */ private static final int MULTIPAGE = 017600000000; /** Length of base name for autonaming. */ private static final int ABBREVLEN = 8; /** zero rectangle */ private static final Rectangle2D CENTERRECT = new Rectangle2D.Double(0, 0, 0, 0); /** Bounds are correct */ private static final byte BOUNDS_CORRECT = 0; /** Bounds are correct if all subcells have correct bounds. */ private static final byte BOUNDS_CORRECT_SUB = 1; /** Bounds are correct if all geoms have correct bounds. */ private static final byte BOUNDS_CORRECT_GEOM = 2; /** Bounds need to be recomputed. */ private static final byte BOUNDS_RECOMPUTE = 3; /** Database to which this Library belongs. */ private final EDatabase database; /** Persistent data of this Cell. */ private ImmutableCell d; /** The CellGroup this Cell belongs to. */ private CellGroup cellGroup; /** The library this Cell belongs to. */ private Library lib; /** The technology of this Cell. */ private Technology tech; /** The newest version of this Cell. */ Cell newestVersion; /** An array of Exports on the Cell by chronological index. */ private Export[] chronExports = new Export[2]; /** A sorted array of Exports on the Cell. */ private Export[] exports = NULL_EXPORT_ARRAY; /** Cell's topology. */ private final Topology topology = new Topology(this, false); /** The Cell's essential-bounds. */ private final List<NodeInst> essenBounds = new ArrayList<NodeInst>(); /** Chronological list of NodeInsts in this Cell. */ private final List<NodeInst> chronNodes = new ArrayList<NodeInst>(); /** Set containing nodeIds of expanded cells. */ private final BitSet expandedNodes = new BitSet(); /** A list of NodeInsts in this Cell. */ private final List<NodeInst> nodes = new ArrayList<NodeInst>(); /** Counts of NodeInsts for each CellUsage. */ private int[] cellUsages = NULL_INT_ARRAY; /** A map from canonic String to Integer maximal numeric suffix */private final Map<String,MaxSuffix> maxSuffix = new HashMap<String,MaxSuffix>(); /** The bounds of the Cell. */ private ERectangle cellBounds; /** Whether the bounds need to be recomputed. * BOUNDS_CORRECT - bounds are correct. * BOUNDS_CORRECT_SUB - bounds are correct provided that bounds of subcells are correct. * BOUNDS_CORRECT_GEOM - bounds are correct proveded that bounds of nodes and arcs are correct. * BOUNDS_RECOMPUTE - bounds need to be recomputed. */ private byte boundsDirty = BOUNDS_RECOMPUTE; /** The temporary integer value. */ private int tempInt; /** Set if expanded status of subcell instances is modified. */ private boolean expandStatusModified; /** Last backup of this Cell */ CellBackup backup; /** True if cell together with contents matches cell backup. */ boolean cellBackupFresh; /** True if cell contents matches cell backup. */ private boolean cellContentsFresh; /** True if cell revision date is just set by lowLevelSetRevisionDate*/private boolean revisionDateFresh; // ------------------ protected and private methods ----------------------- /** * This constructor should not be called. * Use the factory "newInstance" to create a Cell. */ Cell(EDatabase database, ImmutableCell d) { this.database = database; this.d = d; lib = database.getLib(d.getLibId()); assert lib != null; if (d.techId != null) tech = database.getTech(d.techId); } private Object writeReplace() { return new CellKey(this); } private static class CellKey extends EObjectInputStream.Key<Cell> { public CellKey() {} private CellKey(Cell cell) { super(cell); } @Override public void writeExternal(EObjectOutputStream out, Cell cell) throws IOException { CellId cellId = cell.getId(); if (cell.getDatabase() != out.getDatabase() || !cell.isLinked()) throw new NotSerializableException(cell + " not linked"); out.writeObject(cellId); } @Override public Cell readExternal(EObjectInputStream in) throws IOException, ClassNotFoundException { CellId cellId = (CellId)in.readObject(); Cell cell = cellId.inDatabase(in.getDatabase()); if (cell == null) throw new InvalidObjectException(cellId + " not linked"); return cell; } } /****************************** CREATE, DELETE ******************************/ /** * Factory method to create a new Cell. * Also does auxiliary things to create the Cell, such as placing a cell-center if requested. * @param lib the Library in which to place this cell. * @param name the name of this cell. * Cell names may not contain unprintable characters, spaces, tabs, a colon (:), semicolon (;) or curly braces ({}). * However, the name can be fully qualified with version and view information. * For example, "foo;2{sch}". * @return the newly created cell (null on error). */ public static Cell makeInstance(Library lib, String name) { Cell cell = newInstance(lib, name); // add cell-center if requested if (User.isPlaceCellCenter()) { NodeProto cellCenterProto = Generic.tech().cellCenterNode; NodeInst cellCenter = NodeInst.newInstance(cellCenterProto, new Point2D.Double(0, 0), cellCenterProto.getDefWidth(), cellCenterProto.getDefHeight(), cell); if (cellCenter != null) { cellCenter.setVisInside(); cellCenter.setHardSelect(); } } return cell; } /** * Factory method to create a new Cell. * @param lib the Library in which to place this cell. * @param name the name of this cell. * Cell names may not contain unprintable characters, spaces, tabs, a colon (:), semicolon (;) or curly braces ({}). * However, the name can be fully qualified with version and view information. * For example, "foo;2{sch}". * @return the newly created cell (null on error). */ public static Cell newInstance(Library lib, String name) { lib.checkChanging(); EDatabase database = lib.getDatabase(); CellName cellName = CellName.parseName(name); if (cellName == null) return null; // check name for legal characters String protoName = cellName.getName(); String original = null; for(int i=0; i<protoName.length(); i++) { char chr = protoName.charAt(i); if (Character.isWhitespace(chr) || chr == ':' || chr == ';' || chr == '{' || chr == '}') { if (original == null) original = protoName; protoName = protoName.substring(0, i) + '_' + protoName.substring(i+1); } } if (original != null) { System.out.println("Cell name changed from '" + original + "' to '" + protoName + "'"); cellName = CellName.newName(protoName, cellName.getView(), cellName.getVersion()); } cellName = makeUnique(lib, cellName); Date creationDate = new Date(); CellId cellId = lib.getId().newCellId(cellName); Cell cell = new Cell(lib.getDatabase(), ImmutableCell.newInstance(cellId, creationDate.getTime())); // success database.addCell(cell); // add ourselves to the library lib.addCell(cell); // add ourselves to cell group cell.lowLevelLinkCellName(); // handle change control, constraint, and broadcast database.unfreshSnapshot(); Constraints.getCurrent().newObject(cell); return cell; } private void lowLevelLinkCellName() { // determine the cell group for (Iterator<Cell> it = getViewsTail(); it.hasNext(); ) { Cell c = it.next(); if (c.getName().equals(getName())) cellGroup = c.cellGroup; } // still none: make a new one if (cellGroup == null) cellGroup = new CellGroup(lib); // add ourselves to cell group cellGroup.add(this); } /** * Method to remove this node from all lists. */ public void kill() { if (!isLinked()) { System.out.println("Cell already killed"); return; } checkChanging(); // remove ourselves from the cellGroup. lib.removeCell(this); cellGroup.remove(this); database.removeCell(getId()); // handle change control, constraint, and broadcast database.unfreshSnapshot();// lib.setChanged(); Constraints.getCurrent().killObject(this); } /** * Method to copy a Cell to any Library. * @param fromCell the Cell to copy. * @param toLib the Library to copy it to. * @param toName the name of the Cell in the destination Library. * If the destination library is the same as the original Cell's library and the new name is the same * as the old name, a new version is made. * @param useExisting true to use existing subcell instances if they exist in the destination Library. * @return the new Cell in the destination Library. */ public static Cell copyNodeProto(Cell fromCell, Library toLib, String toName, boolean useExisting) { return copyNodeProto(fromCell, toLib, toName, useExisting, null); } /** * Method to copy a Cell to any Library. * @param fromCell the Cell to copy. * @param toLib the Library to copy it to. * @param toName the name of the Cell in the destination Library. * If the destination library is the same as the original Cell's library and the new name is the same * as the old name, a new version is made. * @param useExisting true to use existing subcell instances if they exist in the destination Library. * @param cellNamesToUse a map that disambiguates cell names when they clash in different original libraries. * The main key is an old cell name, and the value for that key is a map of library names to new cell names. * So, for example, if libraries "A" and "B" both have a cell called "X", then existing.get("X").get("A") is "X" but * existing.get(X").get("B") is "X_1" which disambiguates the cell names in the destination library. The map may be null. * @return the new Cell in the destination Library. */ public static Cell copyNodeProto(Cell fromCell, Library toLib, String toName, boolean useExisting, Map<String,Map<String,String>> cellNamesToUse) { // check for validity if (fromCell == null) return null; if (toLib == null) return null; // make sure name of new cell is valid for(int i=0; i<toName.length(); i++) { char ch = toName.charAt(i); if (ch <= ' ' || ch == ':' || ch >= 0177) { System.out.println("invalid name of new cell"); return null; } } // determine whether this copy is to a different library Library destLib = toLib; if (toLib == fromCell.getLibrary()) destLib = null; // mark the proper prototype to use for each node Map<NodeInst,NodeProto> nodePrototypes = new HashMap<NodeInst,NodeProto>(); // if doing a cross-library copy and can use existing ones from new library, do it
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -