There are two main threads in Electric: the user and the database server. When you run code that generates circuitry (such as making a library from a technology) then you are in the Server thread, which cannot directly invoke user interface operations. A simple test for whether this is the server thread should be done in TechConversionResults.showError() and if so, it should report the problem but not highlighting it.

   -Steven Rubin

On 10/17/2020 9:03 AM, Alexandre Rusev wrote:




public static Library makeLibFromTech(Technology tech, EditingPreferences ep, GraphicsPreferences gp)

I think that getExamples(...) returns null along with error messages (which breaks conversion to library) in some cases when errors are not critical by their nature.


Example are: "No highlight layer found", "Too many highlight layers found"
and may be some other cases as well.

The error status set by  tcr.markError(...) is also verified somewhere around makeLibFromTech(...) and breks process even if getExamples() returns NOT a null.



It seems that it's no reason from preventing user from editing graphical representations of libraries which have extra/missing of highlights or other primitives.




com.sun.electric.tool.user.tecEdit.Exmple


/**
* Method to parse the node examples in cell "np" and return a list of
* EXAMPLEs (one per example).  "isNode" is true if this is a node
* being examined.  Returns NOEXAMPLE on error.
*/
public static List<Example> getExamples(Cell np, boolean isNode, TechConversionResult tcr, List<Example> variations)
{
Map<NodeInst,Object> nodeExamples = new HashMap<NodeInst,Object>();
for(Iterator<NodeInst> it = np.getNodes(); it.hasNext(); )
{
NodeInst ni = it.next();

// ignore special nodes with function information
int funct = Manipulate.getOptionOnNode(ni);
if (funct != Info.LAYERPATCH && funct != Info.PORTOBJ && funct != Info.HIGHLIGHTOBJ)
{
nodeExamples.put(ni, new Integer(0));
}
}

List<Example> neList = new ArrayList<Example>();
for(Iterator<NodeInst> it = np.getNodes(); it.hasNext(); )
{
NodeInst ni = it.next();
if (nodeExamples.get(ni) != null) continue;

// get a new cluster of nodes
Example ne = new Example();
neList.add(ne);

Poly poly = new Poly(ni.getAnchorCenterX(), ni.getAnchorCenterY(),
ni.getLambdaBaseXSize(), ni.getLambdaBaseYSize());
poly.transform(ni.rotateOut());
Rectangle2D soFar = poly.getBounds2D();

// now find all others that touch this area
boolean gotBBox = false;
boolean foundOne = true;
int hCount = 0;
while (foundOne)
{
foundOne = false;

// begin to search the area so far
                List<NodeInst> sortedNodes = new ArrayList<NodeInst>();
for(Iterator<Geometric> oIt = np.searchIterator(soFar); oIt.hasNext(); )
{
Geometric geom = oIt.next();
if (geom == null) break;
if (geom instanceof NodeInst)
                    sortedNodes.add((NodeInst)geom);
                }
for(NodeInst otherNi: sortedNodes)
{
Poly oPoly = new Poly(otherNi.getAnchorCenterX(), otherNi.getAnchorCenterY(),
otherNi.getLambdaBaseXSize(), otherNi.getLambdaBaseYSize());
oPoly.transform(otherNi.rotateOut());
Rectangle2D otherRect = oPoly.getBounds2D();
if (!DBMath.rectsIntersect(otherRect, soFar)) continue;

// make sure the node is valid
Object otherAssn = nodeExamples.get(otherNi);
if (otherAssn != null)
{
if (otherAssn instanceof Integer) continue;
if ((Example)otherAssn == ne) continue;
String error = "Examples are too close.  Found " + neList.size() + " examples at:";
for(Example nee : neList)
{
error += " [" + TextUtils.formatDistance(nee.lx) + "<=X<=" + TextUtils.formatDistance(nee.hx) + " and " + TextUtils.formatDistance(nee.ly <http://nee.ly>) + "<=Y<=" + TextUtils.formatDistance(nee.hy) + "]";
}
tcr.markError(otherNi, np, error);

return null;
}
nodeExamples.put(otherNi, ne);
// add it to the cluster
Sample ns = new Sample();
ns.node = otherNi;
ns.values = null;
ns.msg = null;
ns.parent = ne;
ne.samples.add(ns);
ns.assoc = null;
ns.xPos = otherRect.getCenterX();
ns.yPos = otherRect.getCenterY();
int funct = Manipulate.getOptionOnNode(otherNi);
switch (funct)
{
case Info.PORTOBJ:
if (!isNode)
{
tcr.markError(otherNi, np, "Ports can only exist in nodes");
return null;
}
ns.layer = Generic.tech().portNode;
break;
case Info.CENTEROBJ:
if (!isNode)
{
tcr.markError(otherNi, np, "Grab points can only exist in nodes");
return null;
}
ns.layer = Generic.tech().cellCenterNode;
break;
case Info.HIGHLIGHTOBJ:
hCount++;
break;
default:
ns.layer = Manipulate.getLayerCell(otherNi);
if (ns.layer == null)
{
Manipulate.getLayerCell(otherNi);
                                tcr.markError(otherNi, np, "Node has no layer information");
return null;
}
break;
}

// accumulate state if this is not a "grab point" mark
if (!Generic.isCellCenter(otherNi))
{
if (!gotBBox)
{
ne.lx = otherRect.getMinX();   ne.hx = otherRect.getMaxX();
ne.ly <http://ne.ly> = otherRect.getMinY();   ne.hy = otherRect.getMaxY();
gotBBox = true;
} else
{
if (otherRect.getMinX() < ne.lx) ne.lx = otherRect.getMinX();
if (otherRect.getMaxX() > ne.hx) ne.hx = otherRect.getMaxX();
if (otherRect.getMinY() < ne.ly <http://ne.ly>) ne.ly <http://ne.ly> = otherRect.getMinY();
if (otherRect.getMaxY() > ne.hy) ne.hy = otherRect.getMaxY();
}
soFar.setRect(ne.lx, ne.ly <http://ne.ly>, ne.hx-ne.lx, ne.hy-ne.ly <http://ne.hy-ne.ly>);
}
foundOne = true;
}
}
if (hCount == 0)
{
tcr.markError(null, np, "No highlight layer found");
return null;
}
if (hCount != 1)
{
tcr.markError(null, np, "Too many highlight layers found: " + hCount);
return null;
}
}
if (neList == null)
{
tcr.markError(null, np, "No examples found");
return neList;
}

// put variations in a separate list
if (variations != null)
{
for(int i=0; i<neList.size(); i++)
{
Example e = neList.get(i);
for(Sample s : e.samples)
{
if (!s.node.getNameKey().isTempname())
{
// named a layer: this is a variation
variations.add(e);
neList.remove(i);
i--;
break;
}
}
}
if (neList.size() == 0 && variations.size() > 0)
{
tcr.markError(null, np, "All examples have text on them...text should be used only in variations");
return neList;
}
}

// now search the list for the smallest, most upper-left example (the "main" example)
double sizeX = 0;
double sizeY = 0;
double locX = 0;
double locY = 0;
Example bestNe = null;
for(Example ne : neList)
{
double newSize = ne.hx-ne.lx;
newSize *= ne.hy-ne.ly <http://ne.hy-ne.ly>;
if (bestNe != null)
{
if (newSize > sizeX*sizeY) continue;
if (newSize == sizeX*sizeY && (ne.lx+ne.hx)/2 >= locX && (ne.ly <http://ne.ly>+ne.hy)/2 <= locY)
continue;
}
sizeX = ne.hx - ne.lx;
sizeY = ne.hy - ne.ly <http://ne.ly>;
locX = (ne.lx + ne.hx) / 2;
locY = (ne.ly <http://ne.ly> + ne.hy) / 2;
bestNe = ne;
}

// place the main example at the top of the list
if (bestNe != null && bestNe != neList)
{
neList.remove(bestNe);
neList.add(0, bestNe);
}

// done
return neList;
}
}


--
You received this message because you are subscribed to the Google Groups "Electric 
VLSI Editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to electricvlsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/electricvlsi/e0902064-b036-11c3-8583-93f4beb0d570%40staticfreesoft.com.

Reply via email to