simplified the origin book keeping

This commit is contained in:
hneemann 2017-07-21 16:28:30 +02:00
parent e4308826a9
commit 12141c22b7
10 changed files with 82 additions and 70 deletions

View File

@ -9,8 +9,7 @@ import java.util.Set;
* Created by hneemann on 16.06.17. * Created by hneemann on 16.06.17.
*/ */
public class ExceptionWithOrigin extends Exception { public class ExceptionWithOrigin extends Exception {
private Set<File> origin; private File origin;
/** /**
* Returns the file or the files that caused the given exception. * Returns the file or the files that caused the given exception.
@ -22,9 +21,9 @@ public class ExceptionWithOrigin extends Exception {
public static String getOriginOf(Throwable e) { public static String getOriginOf(Throwable e) {
while (e != null) { while (e != null) {
if (e instanceof ExceptionWithOrigin) { if (e instanceof ExceptionWithOrigin) {
String orig = ((ExceptionWithOrigin) e).getOriginStr(); String originStr = ((ExceptionWithOrigin) e).getOriginStr();
if (orig != null) if (originStr != null)
return orig; return originStr;
} }
e = e.getCause(); e = e.getCause();
} }
@ -63,7 +62,9 @@ public class ExceptionWithOrigin extends Exception {
* @return the origin of the error * @return the origin of the error
*/ */
public Set<File> getOrigin() { public Set<File> getOrigin() {
return origin; HashSet<File> s = new HashSet<>();
s.add(origin);
return s;
} }
/** /**
@ -88,9 +89,9 @@ public class ExceptionWithOrigin extends Exception {
* @param origin the file which had caused the exception * @param origin the file which had caused the exception
*/ */
public void setOrigin(File origin) { public void setOrigin(File origin) {
if (this.origin == null && origin != null) { if (origin != null) {
this.origin = new HashSet<>(); if (this.origin == null)
this.origin.add(origin); this.origin = origin;
} }
} }

View File

@ -57,6 +57,7 @@ public class Circuit {
private transient boolean modified = false; private transient boolean modified = false;
private transient ArrayList<CircRect> recs; private transient ArrayList<CircRect> recs;
private transient ArrayList<ChangedListener> listeners; private transient ArrayList<ChangedListener> listeners;
private transient File origin;
/** /**
* Creates a proper configured XStream instance * Creates a proper configured XStream instance
@ -117,7 +118,7 @@ public class Circuit {
e.setPos(e.getPos().mul(2)); e.setPos(e.getPos().mul(2));
circuit.version = 1; circuit.version = 1;
} }
circuit.origin = filename;
return circuit; return circuit;
} }
} }
@ -134,6 +135,7 @@ public class Circuit {
out.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); out.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
xStream.marshal(this, new PrettyPrintWriter(out)); xStream.marshal(this, new PrettyPrintWriter(out));
modified = false; modified = false;
origin = filename;
} }
} }
@ -475,6 +477,7 @@ public class Circuit {
/** /**
* Sets this circuits state to not modified * Sets this circuits state to not modified
*
* @param modified the modified state * @param modified the modified state
*/ */
public void setModified(boolean modified) { public void setModified(boolean modified) {
@ -616,6 +619,13 @@ public class Circuit {
recs.add(new CircRect(pos, size)); recs.add(new CircRect(pos, size));
} }
/**
* @return the file origin of this circuit, may be null
*/
public File getOrigin() {
return origin;
}
private static final class CircRect { private static final class CircRect {
private final Vector pos; private final Vector pos;
private final Vector size; private final Vector size;

View File

@ -32,6 +32,7 @@ public class PinException extends ExceptionWithOrigin {
public PinException(String message, Net net) { public PinException(String message, Net net) {
super(message); super(message);
this.net = net; this.net = net;
setOrigin(net.getOrigin());
} }
/** /**

View File

@ -1,6 +1,5 @@
package de.neemann.digital.draw.elements; package de.neemann.digital.draw.elements;
import de.neemann.digital.core.Node;
import de.neemann.digital.core.Observer; import de.neemann.digital.core.Observer;
import de.neemann.digital.core.element.*; import de.neemann.digital.core.element.*;
import de.neemann.digital.draw.graphics.*; import de.neemann.digital.draw.graphics.*;
@ -385,18 +384,11 @@ public class VisualElement implements Drawable, Movable, AttributeListener {
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(elementName);
String lab = elementAttributes.getCleanLabel(); String lab = elementAttributes.getCleanLabel();
if (lab != null && lab.length() > 0) if (lab != null && lab.length() > 0)
sb.append(" (").append(lab).append(")"); return elementName + " (" + lab + ")";
else
if (element != null && element instanceof Node) { return elementName;
Node n = (Node) element;
if (n.getOrigin() != null)
sb.append("; ").append(n.getOrigin().getName());
}
return sb.toString();
} }
/** /**

View File

@ -10,8 +10,6 @@ import de.neemann.digital.draw.model.ModelCreator;
import de.neemann.digital.draw.model.NetList; import de.neemann.digital.draw.model.NetList;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import java.io.File;
/** /**
* This class represents a custom, nested element. * This class represents a custom, nested element.
* So it is possible to use an element in the circuit witch is made from an * So it is possible to use an element in the circuit witch is made from an
@ -24,7 +22,6 @@ public class CustomElement implements Element {
private final Circuit circuit; private final Circuit circuit;
private final ElementLibrary library; private final ElementLibrary library;
private final File name;
private NetList netList; private NetList netList;
/** /**
@ -32,12 +29,10 @@ public class CustomElement implements Element {
* *
* @param circuit the inner circuit * @param circuit the inner circuit
* @param library the library to use. * @param library the library to use.
* @param name the name of the element
*/ */
public CustomElement(Circuit circuit, ElementLibrary library, File name) { public CustomElement(Circuit circuit, ElementLibrary library) {
this.circuit = circuit; this.circuit = circuit;
this.library = library; this.library = library;
this.name = name;
} }
/** /**
@ -56,9 +51,9 @@ public class CustomElement implements Element {
netList = new NetList(circuit); netList = new NetList(circuit);
if (depth > MAX_DEPTH) if (depth > MAX_DEPTH)
throw new NodeException(Lang.get("err_recursiveNestingAt_N0", name.getName())); throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin()));
return new ModelCreator(circuit, library, true, name, new NetList(netList), subName, depth); return new ModelCreator(circuit, library, true, new NetList(netList), subName, depth);
} }
@Override @Override

View File

@ -416,7 +416,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
} }
ElementTypeDescriptionCustom description = ElementTypeDescriptionCustom description =
new ElementTypeDescriptionCustom(file, new ElementTypeDescriptionCustom(file,
attributes -> new CustomElement(circuit, ElementLibrary.this, file), attributes -> new CustomElement(circuit, ElementLibrary.this),
circuit.getAttributes(), circuit.getInputNames()); circuit.getAttributes(), circuit.getInputNames());
description.setShortName(createShortName(file)); description.setShortName(createShortName(file));

View File

@ -18,7 +18,6 @@ import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.draw.shapes.Drawable; import de.neemann.digital.draw.shapes.Drawable;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import java.io.File;
import java.util.*; import java.util.*;
/** /**
@ -32,7 +31,6 @@ public class ModelCreator implements Iterable<ModelEntry> {
private final NetList netList; private final NetList netList;
private final ArrayList<ModelEntry> entries; private final ArrayList<ModelEntry> entries;
private final HashMap<String, Pin> ioMap; private final HashMap<String, Pin> ioMap;
private final File origin;
/** /**
* Creates the ModelDescription. * Creates the ModelDescription.
@ -61,7 +59,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
* @throws ElementNotFoundException ElementNotFoundException * @throws ElementNotFoundException ElementNotFoundException
*/ */
public ModelCreator(Circuit circuit, ElementLibrary library, boolean readAsCustom) throws PinException, NodeException, ElementNotFoundException { public ModelCreator(Circuit circuit, ElementLibrary library, boolean readAsCustom) throws PinException, NodeException, ElementNotFoundException {
this(circuit, library, readAsCustom, null, new NetList(circuit), "", 0); this(circuit, library, readAsCustom, new NetList(circuit), "", 0);
} }
/** /**
@ -70,7 +68,6 @@ public class ModelCreator implements Iterable<ModelEntry> {
* @param circuit the circuit to use * @param circuit the circuit to use
* @param library the library to use * @param library the library to use
* @param isNestedCircuit if true the model is created for use as nested element * @param isNestedCircuit if true the model is created for use as nested element
* @param origin only used for better messages in exceptions
* @param netList the NetList of the model. If known it is not necessary to create it. * @param netList the NetList of the model. If known it is not necessary to create it.
* @param subName name of the circuit, used to name unique elements * @param subName name of the circuit, used to name unique elements
* @param depth recursion depth, used to detect a circuit which contains itself * @param depth recursion depth, used to detect a circuit which contains itself
@ -78,8 +75,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
* @throws NodeException NodeException * @throws NodeException NodeException
* @throws ElementNotFoundException ElementNotFoundException * @throws ElementNotFoundException ElementNotFoundException
*/ */
public ModelCreator(Circuit circuit, ElementLibrary library, boolean isNestedCircuit, File origin, NetList netList, String subName, int depth) throws PinException, NodeException, ElementNotFoundException { public ModelCreator(Circuit circuit, ElementLibrary library, boolean isNestedCircuit, NetList netList, String subName, int depth) throws PinException, NodeException, ElementNotFoundException {
this.origin = origin;
this.circuit = circuit; this.circuit = circuit;
this.netList = netList; this.netList = netList;
entries = new ArrayList<>(); entries = new ArrayList<>();
@ -103,7 +99,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
// sets the nodes origin to create better error messages // sets the nodes origin to create better error messages
if (element instanceof Node) if (element instanceof Node)
((Node) element).setOrigin(origin); ((Node) element).setOrigin(circuit.getOrigin());
// if handled as nested element, don't put pins in EntryList, but put the pins in a // if handled as nested element, don't put pins in EntryList, but put the pins in a
// separate map to connect it with the parent! // separate map to connect it with the parent!
@ -112,11 +108,11 @@ public class ModelCreator implements Iterable<ModelEntry> {
if (elementType == In.DESCRIPTION || elementType == Out.DESCRIPTION || elementType == Clock.DESCRIPTION) { if (elementType == In.DESCRIPTION || elementType == Out.DESCRIPTION || elementType == Clock.DESCRIPTION) {
String label = ve.getElementAttributes().getLabel(); String label = ve.getElementAttributes().getLabel();
if (label == null || label.length() == 0) if (label == null || label.length() == 0)
throw new PinException(Lang.get("err_pinWithoutName", origin)); throw new PinException(Lang.get("err_pinWithoutName", circuit.getOrigin()));
if (pins.size() != 1) if (pins.size() != 1)
throw new PinException(Lang.get("err_N_isNotInputOrOutput", label, origin)); throw new PinException(Lang.get("err_N_isNotInputOrOutput", label, circuit.getOrigin()));
if (ioMap.containsKey(label)) if (ioMap.containsKey(label))
throw new PinException(Lang.get("err_duplicatePinLabel", label, origin)); throw new PinException(Lang.get("err_duplicatePinLabel", label, circuit.getOrigin()));
ioMap.put(label, pins.get(0)); ioMap.put(label, pins.get(0));
isNotAIO = false; isNotAIO = false;
@ -124,26 +120,26 @@ public class ModelCreator implements Iterable<ModelEntry> {
} }
if (isNotAIO) if (isNotAIO)
entries.add(new ModelEntry(element, pins, ve, elementType.getInputDescription(ve.getElementAttributes()), isNestedCircuit, origin)); entries.add(new ModelEntry(element, pins, ve, elementType.getInputDescription(ve.getElementAttributes()), isNestedCircuit, circuit.getOrigin()));
for (Pin p : pins) for (Pin p : pins)
netList.add(p); netList.add(p);
} }
// connect all custom elements to the parents net // connect all custom elements to the parents net
ArrayList<ModelCreator> cmdl = new ArrayList<>(); ArrayList<ModelCreator> modelCreators = new ArrayList<>();
Iterator<ModelEntry> it = entries.iterator(); Iterator<ModelEntry> it = entries.iterator();
while (it.hasNext()) { while (it.hasNext()) {
ModelEntry me = it.next(); ModelEntry me = it.next();
if (me.getElement() instanceof CustomElement) { // at first look for custom elements if (me.getElement() instanceof CustomElement) { // at first look for custom elements
CustomElement ce = (CustomElement) me.getElement(); CustomElement ce = (CustomElement) me.getElement();
ModelCreator child = ce.getModelDescription(combineNames(subName, me.getVisualElement().getElementAttributes().getCleanLabel()), depth + 1); ModelCreator child = ce.getModelDescription(combineNames(subName, me.getVisualElement().getElementAttributes().getCleanLabel()), depth + 1);
cmdl.add(child); modelCreators.add(child);
HashMap<Net, Net> netMatch = new HashMap<>(); HashMap<Net, Net> netMatch = new HashMap<>();
for (Pin p : me.getPins()) { // connect the custom elements to the parents net for (Pin p : me.getPins()) { // connect the custom elements to the parents net
Net childNet = child.getNetOfIOandRemove(p.getName()); Net childNet = child.getNetOfIOAndRemove(p.getName());
Net otherParentNet = netMatch.get(childNet); Net otherParentNet = netMatch.get(childNet);
if (otherParentNet != null) { if (otherParentNet != null) {
@ -151,7 +147,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
// two nets in the parent are connected directly by the nested circuit // two nets in the parent are connected directly by the nested circuit
// merge the nets in the parent! // merge the nets in the parent!
// remove the childs inner pin which is already added to the other net // remove the children's inner pin which is already added to the other net
Pin insertedPin = child.getPinOfIO(p.getName()); Pin insertedPin = child.getPinOfIO(p.getName());
otherParentNet.removePin(insertedPin); otherParentNet.removePin(insertedPin);
@ -187,12 +183,12 @@ public class ModelCreator implements Iterable<ModelEntry> {
it.remove(); it.remove();
} }
} }
for (ModelCreator md : cmdl) { // put the elements of the custom element to the parent for (ModelCreator md : modelCreators) { // put the elements of the custom element to the parent
entries.addAll(md.entries); entries.addAll(md.entries);
netList.add(md.netList); netList.add(md.netList);
} }
} catch (PinException | NodeException e) { } catch (PinException | NodeException e) {
e.setOrigin(origin); e.setOrigin(circuit.getOrigin());
throw e; throw e;
} }
} }
@ -219,7 +215,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
return pin; return pin;
} }
private Net getNetOfIOandRemove(String name) throws PinException { private Net getNetOfIOAndRemove(String name) throws PinException {
Pin pin = getPinOfIO(name); Pin pin = getPinOfIO(name);
Net netOfPin = netList.getNetOfPin(pin); Net netOfPin = netList.getNetOfPin(pin);
if (netOfPin == null) if (netOfPin == null)
@ -231,7 +227,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
} }
/** /**
* Creates the model * Creates the model.
* *
* @param attachWires if true the wires are attached to the values * @param attachWires if true the wires are attached to the values
* @return the model * @return the model
@ -239,28 +235,23 @@ public class ModelCreator implements Iterable<ModelEntry> {
* @throws NodeException NodeException * @throws NodeException NodeException
*/ */
public Model createModel(boolean attachWires) throws PinException, NodeException { public Model createModel(boolean attachWires) throws PinException, NodeException {
try { Model m = new Model();
Model m = new Model();
for (Net n : netList) for (Net n : netList)
n.interconnect(m, attachWires); n.interconnect(m, attachWires);
for (ModelEntry e : entries) for (ModelEntry e : entries)
e.applyInputs(); e.applyInputs();
for (ModelEntry e : entries) for (ModelEntry e : entries)
e.getElement().registerNodes(m); e.getElement().registerNodes(m);
for (ModelEntry e : entries) { for (ModelEntry e : entries) {
e.getElement().init(m); e.getElement().init(m);
e.getVisualElement().getShape().registerModel(this, m, e); e.getVisualElement().getShape().registerModel(this, m, e);
}
return m;
} catch (PinException | NodeException e) {
e.setOrigin(origin);
throw e;
} }
return m;
} }
/** /**
@ -306,11 +297,11 @@ public class ModelCreator implements Iterable<ModelEntry> {
* @return the list * @return the list
*/ */
public List<ModelEntry> getEntries(String elementName) { public List<ModelEntry> getEntries(String elementName) {
List<ModelEntry> entr = new ArrayList<>(); List<ModelEntry> entry = new ArrayList<>();
for (ModelEntry me : entries) for (ModelEntry me : entries)
if (me.getVisualElement().getElementName().endsWith(elementName)) if (me.getVisualElement().getElementName().endsWith(elementName))
entr.add(me); entry.add(me);
return entr; return entry;
} }
/** /**

View File

@ -10,6 +10,7 @@ import de.neemann.digital.draw.elements.Wire;
import de.neemann.digital.draw.graphics.Vector; import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@ -27,6 +28,7 @@ public class Net {
private final ArrayList<Pin> pins; private final ArrayList<Pin> pins;
private final ArrayList<Wire> wires; private final ArrayList<Wire> wires;
private final HashSet<String> labelSet; private final HashSet<String> labelSet;
private File origin;
/** /**
* Creates a copy of the given net * Creates a copy of the given net
@ -38,6 +40,7 @@ public class Net {
wires = null; // wires not needed wires = null; // wires not needed
pins = new ArrayList<>(toCopy.pins); // Pins are changed so create a deep copy pins = new ArrayList<>(toCopy.pins); // Pins are changed so create a deep copy
labelSet = new HashSet<>(toCopy.labelSet); //ToDo copy necessary? labelSet = new HashSet<>(toCopy.labelSet); //ToDo copy necessary?
origin = toCopy.origin;
} }
/** /**
@ -236,4 +239,20 @@ public class Net {
else else
return labelSet + "/" + pins; return labelSet + "/" + pins;
} }
/**
* Sets the origin of this net
*
* @param origin the origin
*/
public void setOrigin(File origin) {
this.origin = origin;
}
/**
* @return the origin of this net
*/
public File getOrigin() {
return origin;
}
} }

View File

@ -43,6 +43,9 @@ public class NetList implements Iterable<Net> {
found.addLabel(label); found.addLabel(label);
} }
for (Net n : netList)
n.setOrigin(circuit.getOrigin());
mergeLabels(); mergeLabels();
} }

View File

@ -316,7 +316,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
try { try {
ElementLibrary.ElementTypeDescriptionCustom description = ElementLibrary.ElementTypeDescriptionCustom description =
new ElementLibrary.ElementTypeDescriptionCustom(file, new ElementLibrary.ElementTypeDescriptionCustom(file,
attributes -> new CustomElement(circuit, library, filename), attributes -> new CustomElement(circuit, library),
circuit.getAttributes(), circuit.getInputNames()); circuit.getAttributes(), circuit.getInputNames());
description.setShortName(name); description.setShortName(name);
description.setDescription(circuit.getAttributes().get(Keys.DESCRIPTION)); description.setDescription(circuit.getAttributes().get(Keys.DESCRIPTION));