/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: NccJob.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;
import java.util.List;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.View;
import com.sun.electric.database.network.NetworkTool;
import com.sun.electric.tool.Job;
import com.sun.electric.tool.ncc.basic.CellContext;
import com.sun.electric.tool.ncc.basic.NccUtils;
import com.sun.electric.tool.ncc.result.NccResults;
import com.sun.electric.tool.user.ncc.NccMsgsFrame;
/* Implements the NCC user command */
public class NccJob extends Job {
static final long serialVersionUID = 0;
/** Save the results from the last NCC run here. lastResults is static
* because we want results to persist even after the job is done.
* This makes it possible to do schematic / layout cross probing
* after running NCC. */
private static NccResults lastResults = null;
/** Remember which Cells have already passed NCC. passed is
* static because the next run of NCC might want to skip
* checking cells because they passed in the previous run of NCC.
* passed is only used in interactive mode. */
private static PassedNcc passed = null;
/** nccgui is static for efficiency. It is public because we want
* to share with com.sun.electric.plugins.pie.NccJob. nccgui
* is only used in interactive mode. Avoid initializing it
* in batch mode because it will throw an exception. */
public static NccMsgsFrame nccgui = null;
// These fields are arguments passed to server
private final int numWindows;
private final NccOptions options;
private final CellContext[] cellCtxts;
// This field is the result passed from the server to the client
private NccResults results;
private void prln(String s) {System.out.println(s);}
private void pr(String s) {System.out.print(s);}
private void initInteractiveStatics() {
if (passed==null) passed = new PassedNcc();
if (nccgui==null) nccgui = new NccMsgsFrame();
}
private CellContext[] getSchemLayFromCurrentWindow() {
CellContext curCellCtxt = NccUtils.getCurrentCellContext();
if (curCellCtxt==null) {
prln("Please open the Cell you wish to NCC");
return null;
}
Cell[] schLay = NccUtils.findSchematicAndLayout(curCellCtxt.cell);
if (schLay==null) {
prln("current Cell Group doesn't have both schematic and layout Cells");
return null;
}
CellContext[] cc = {
new CellContext(schLay[0], curCellCtxt.context),
new CellContext(schLay[1], curCellCtxt.context)
};
return cc;
}
private boolean isSchemOrLay(CellContext cc) {
Cell c = cc.cell;
View v = c.getView();
boolean ok = c.isSchematic() || v==View.LAYOUT;
if (!ok) prln("Cell: "+NccUtils.fullName(c)+
" isn't schematic or layout");
return ok;
}
private boolean isSchem(CellContext cc) {
return cc.cell.isSchematic();
}
/** If one Cell is a schematprlnst
* @return null if not schematic or layout Cells */
private CellContext[] getTwoCellsFromTwoWindows() {
List<CellContext> cellCtxts = NccUtils.getCellContextsFromWindows();
if (cellCtxts.size()<2) {
prln("Two Cells aren't open in two windows");
return null;
}
if (cellCtxts.size()>2) {
prln("More than two Cells are open in windows. Could you please");
prln("close windows until only two Cells are open. (Sorry JonL.)");
return null;
}
CellContext[] cellContexts = new CellContext[2];
cellContexts[0] = (CellContext) cellCtxts.get(0);
cellContexts[1] = (CellContext) cellCtxts.get(1);
if (!isSchemOrLay(cellContexts[0]) ||
!isSchemOrLay(cellContexts[1])) return null;
// Try to put schematic first
if (!isSchem(cellContexts[0]) && isSchem(cellContexts[1])) {
CellContext cc = cellContexts[0];
cellContexts[0] = cellContexts[1];
cellContexts[1] = cc;
}
return cellContexts;
}
/** @return array of two CellContexts to compare */
private CellContext[] getCellsFromWindows(int numWindows) {
if (numWindows==2) return getTwoCellsFromTwoWindows();
else return getSchemLayFromCurrentWindow();
}
// Some day we may run this on server
@Override
public boolean doIt() {
if (cellCtxts==null) {
// null results means couldn't run NCC
results = null;
return true;
}
passed.removeCellsChangedSinceLastNccRun(cellCtxts);
results = Ncc.compare(cellCtxts[0].cell, cellCtxts[0].context,
cellCtxts[1].cell, cellCtxts[1].context,
passed, options, this);
fieldVariableChanged("results");
return true;
}
@Override
public void terminateOK() {
lastResults = results;
if (results==null) return; // NCC couldn't even run
nccgui.setMismatches(results.getAllComparisonMismatches(), options);
NccJob.nccgui.display();
}
// ------------------------- public methods -------------------------------
/** Get the results from the last NCC run. If null then there are no
* valid results. */
public static NccResults getLastNccResults() {return lastResults;}
/** Call this if you modify the design or preferences so that the
* results from the last NCC run are discarded. */
public static void invalidateLastNccResult() {
lastResults=null;
passed = null;
}
/**
* Run a NCC job.
* @param numWind may be 1 or 2. 1 means compare the schematic and layout
* views of the current window. 2 means compare the 2 Cells open in 2 Windows.
*/
public NccJob(int numWind) {
super("Run NCC", NetworkTool.getNetworkTool(), Job.Type.SERVER_EXAMINE, null,
null, Job.Priority.ANALYSIS);
// Set up arguments for doIt() method that is run on server
numWindows = numWind;
error(numWindows!=1 && numWindows!=2,
"numWindows must be 1 or 2");
cellCtxts = getCellsFromWindows(numWindows);
options = NccOptions.getOptionsFromNccPreferences();
// abandon results from last run in order to reclaim storage
results = null;
initInteractiveStatics();
startJob();
}
}