The latest changes to the repository now detect a server job and avoid the crashes that happen when a bad technology is converted to a library.

   -Steve

On 10/20/2020 2:11 AM, Alexandre Rusev wrote:
>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.


Ok.
Thanks.

I still think that we can ignore some nonecritical errors when converting imported from XML technology to library for editing.
And  ... report errors later in user thread and post them to log window.
Is it correct approach?



On Sat, Oct 17, 2020 at 7:13 PM Steven Rubin <[email protected] <mailto:[email protected]>> wrote:

    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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/electricvlsi/ce87e69c-c595-53f9-4d2e-e99cb3ac9a83%40staticfreesoft.com.

Reply via email to