fixed an ugly bug concerning mutable key default values

This commit is contained in:
hneemann 2019-08-25 09:55:44 +02:00
parent e0ebd0e0ae
commit e59be72194
16 changed files with 320 additions and 177 deletions

View File

@ -28,9 +28,9 @@
<sodipodi:namedview <sodipodi:namedview
showgrid="true" showgrid="true"
id="namedview4" id="namedview4"
inkscape:zoom="3.5454545" inkscape:zoom="3.5090909"
inkscape:cx="71.064102" inkscape:cx="100.47927"
inkscape:cy="87.435899" inkscape:cy="110"
inkscape:window-width="1680" inkscape:window-width="1680"
inkscape:window-height="993" inkscape:window-height="993"
inkscape:window-x="0" inkscape:window-x="0"
@ -45,7 +45,7 @@
id="grid2" /> id="grid2" />
</sodipodi:namedview> </sodipodi:namedview>
<path <path
style="fill:#ffffb4;fill-opacity:0.78431373;stroke:#000000;stroke-width:3" style="fill:#ffffb4;fill-opacity:0.78431373;stroke:#000000;stroke-width:4"
d="M 0,-30 80,10 V 90 L 0,130 V 60 L 30,50 0,40 Z" d="M 0,-30 80,10 V 90 L 0,130 V 60 L 30,50 0,40 Z"
id="rect6" id="rect6"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
@ -59,7 +59,7 @@
<circle <circle
style="fill:#0000b2" style="fill:#0000b2"
r="3" r="3"
cy="100.10256" cy="79.794868"
cx="0.28205127" cx="0.28205127"
id="pin+:B" /> id="pin+:B" />
<circle <circle
@ -71,7 +71,7 @@
<circle <circle
style="fill:#0000b2" style="fill:#0000b2"
r="3" r="3"
cy="120.07693" cy="99.769234"
cx="-0.2820513" cx="-0.2820513"
id="pin+:Ci" /> id="pin+:Ci" />
<circle <circle

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -17,20 +17,22 @@ import java.io.File;
public class Key<VALUE> { public class Key<VALUE> {
private final String key; private final String key;
private final VALUE def; private final VALUE def;
private final Default<VALUE> defFactory;
private final String langKey; private final String langKey;
private boolean groupEditAllowed = false; private boolean groupEditAllowed = false;
private Key dependsOn; private Key dependsOn;
private CheckEnabled checkEnabled; private CheckEnabled checkEnabled;
private boolean isSecondary;
private boolean requiresRestart = false;
// Both values are always null in digital. // Both values are always null in digital.
// Both are only used within a custom implemented component. // Both are only used within a custom implemented component.
private String name; private String name;
private String description; private String description;
private boolean isSecondary;
private boolean requiresRestart = false;
/** /**
* Creates a new Key * Creates a new Key.
* Use this constructor only if the def value is not mutable!
* *
* @param key the key * @param key the key
* @param def the default value * @param def the default value
@ -41,6 +43,23 @@ public class Key<VALUE> {
if (def == null) if (def == null)
throw new NullPointerException(); throw new NullPointerException();
this.def = def; this.def = def;
this.defFactory = null;
}
/**
* Creates a new Key.
* Use this constructor if the def value is mutable!
*
* @param key the key
* @param defFactory the factory to create a default value
*/
public Key(String key, Default<VALUE> defFactory) {
this.key = key;
langKey = "key_" + key.replace(" ", "");
if (defFactory == null)
throw new NullPointerException();
this.def = null;
this.defFactory = defFactory;
} }
/** /**
@ -68,14 +87,17 @@ public class Key<VALUE> {
* @return the default value of this key * @return the default value of this key
*/ */
public VALUE getDefault() { public VALUE getDefault() {
if (def != null)
return def; return def;
else
return defFactory.createDefault();
} }
/** /**
* @return The values class * @return The values class
*/ */
public Class getValueClass() { public Class getValueClass() {
return def.getClass(); return getDefault().getClass();
} }
@Override @Override
@ -490,4 +512,18 @@ public class Key<VALUE> {
*/ */
boolean isEnabled(T t); boolean isEnabled(T t);
} }
/**
* Used to provide a default value if the value is mutable.
*
* @param <VALUE> the type of the value
*/
public interface Default<VALUE> {
/**
* Called to create a new default value.
*
* @return the default value
*/
VALUE createDefault();
}
} }

View File

@ -278,7 +278,7 @@ public final class Keys {
* the data key for memory * the data key for memory
*/ */
public static final Key<DataField> DATA public static final Key<DataField> DATA
= new Key<>("Data", DataField.DEFAULT); = new Key<>("Data", DataField::new);
/** /**
* flag for flipping selector pos in muxers, decoders and drivers * flag for flipping selector pos in muxers, decoders and drivers
@ -602,7 +602,7 @@ public final class Keys {
* contains the input inverter config * contains the input inverter config
*/ */
public static final Key<InverterConfig> INVERTER_CONFIG public static final Key<InverterConfig> INVERTER_CONFIG
= new Key<>("inverterConfig", new InverterConfig()); = new Key<>("inverterConfig", new InverterConfig.Builder().build());
/** /**
* Background Color of nested circuits * Background Color of nested circuits
@ -661,7 +661,7 @@ public final class Keys {
* The manager which contains all the roms data * The manager which contains all the roms data
*/ */
public static final Key<ROMManger> ROMMANAGER public static final Key<ROMManger> ROMMANAGER
= new Key<>("romContent", ROMManger.EMPTY).setSecondary(); = new Key<>("romContent", ROMManger::new).setSecondary();
/** /**
@ -707,7 +707,7 @@ public final class Keys {
* Shape used to represent a visual element * Shape used to represent a visual element
*/ */
public static final Key<CustomShapeDescription> CUSTOM_SHAPE public static final Key<CustomShapeDescription> CUSTOM_SHAPE
= new Key<>("customShape", CustomShapeDescription.EMPTY) = new Key<>("customShape", new CustomShapeDescription.Builder().build())
.setSecondary() .setSecondary()
.setDependsOn(SHAPE_TYPE, st -> st.equals(CustomCircuitShapeType.CUSTOM)); .setDependsOn(SHAPE_TYPE, st -> st.equals(CustomCircuitShapeType.CUSTOM));

View File

@ -17,15 +17,17 @@ import java.util.Arrays;
*/ */
public class DataField implements HGSArray { public class DataField implements HGSArray {
/***
* Simple default data field
*/
public static final DataField DEFAULT = new DataField(0);
private long[] data; private long[] data;
private final transient ArrayList<DataListener> listeners = new ArrayList<>(); private final transient ArrayList<DataListener> listeners = new ArrayList<>();
/**
* Creates a new DataField of size 0
*/
public DataField() {
this(0);
}
/** /**
* Creates a new DataField * Creates a new DataField
* *
@ -174,6 +176,13 @@ public class DataField implements HGSArray {
return data.length; return data.length;
} }
/**
* @return true if the data field is empty
*/
public boolean isEmpty() {
return trim() == 0;
}
/** /**
* Adds a listener to this DataField * Adds a listener to this DataField
* *
@ -247,4 +256,17 @@ public class DataField implements HGSArray {
public long[] getData() { public long[] getData() {
return data; return data;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DataField dataField = (DataField) o;
return Arrays.equals(data, dataField.data);
}
@Override
public int hashCode() {
return Arrays.hashCode(data);
}
} }

View File

@ -5,10 +5,7 @@
*/ */
package de.neemann.digital.core.memory; package de.neemann.digital.core.memory;
import de.neemann.digital.core.Node; import de.neemann.digital.core.*;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.ObservableValues;
import de.neemann.digital.core.element.Element; import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription; import de.neemann.digital.core.element.ElementTypeDescription;
@ -40,6 +37,7 @@ public class EEPROM extends Node implements Element, RAMInterface, ROMInterface
private final int bits; private final int bits;
private final int addrBits; private final int addrBits;
private final ElementAttributes attr;
private final int size; private final int size;
private final String label; private final String label;
private final ObservableValue dataOut; private final ObservableValue dataOut;
@ -65,6 +63,7 @@ public class EEPROM extends Node implements Element, RAMInterface, ROMInterface
*/ */
public EEPROM(ElementAttributes attr) { public EEPROM(ElementAttributes attr) {
super(true); super(true);
this.attr = attr;
bits = attr.get(Keys.BITS); bits = attr.get(Keys.BITS);
addrBits = attr.get(Keys.ADDR_BITS); addrBits = attr.get(Keys.ADDR_BITS);
size = 1 << addrBits; size = 1 << addrBits;
@ -77,6 +76,14 @@ public class EEPROM extends Node implements Element, RAMInterface, ROMInterface
isProgramMemory = attr.get(Keys.IS_PROGRAM_MEMORY); isProgramMemory = attr.get(Keys.IS_PROGRAM_MEMORY);
} }
@Override
public void registerNodes(Model model) {
super.registerNodes(model);
if (memory.isEmpty())
model.addObserver(event -> attr.set(Keys.DATA, memory), ModelEvent.STOPPED);
}
@Override @Override
public void setInputs(ObservableValues inputs) throws NodeException { public void setInputs(ObservableValues inputs) throws NodeException {
addrIn = inputs.get(0).checkBits(addrBits, this).addObserverToValue(this); addrIn = inputs.get(0).checkBits(addrBits, this).addObserverToValue(this);

View File

@ -5,6 +5,8 @@
*/ */
package de.neemann.digital.core.memory; package de.neemann.digital.core.memory;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.ModelEvent;
import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription; import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys; import de.neemann.digital.core.element.Keys;
@ -33,6 +35,9 @@ public class EEPROMDualPort extends RAMDualPort implements ROMInterface {
.addAttribute(Keys.LABEL) .addAttribute(Keys.LABEL)
.addAttribute(Keys.DATA); .addAttribute(Keys.DATA);
private final ElementAttributes attr;
private DataField memory;
/** /**
* Creates a new instance * Creates a new instance
* *
@ -40,11 +45,21 @@ public class EEPROMDualPort extends RAMDualPort implements ROMInterface {
*/ */
public EEPROMDualPort(ElementAttributes attr) { public EEPROMDualPort(ElementAttributes attr) {
super(attr); super(attr);
this.attr = attr;
} }
@Override @Override
protected DataField createDataField(ElementAttributes attr, int size) { protected DataField createDataField(ElementAttributes attr, int size) {
return attr.get(Keys.DATA); memory = attr.get(Keys.DATA);
return memory;
}
@Override
public void registerNodes(Model model) {
super.registerNodes(model);
if (memory.isEmpty())
model.addObserver(event -> attr.set(Keys.DATA, memory), ModelEvent.STOPPED);
} }
} }

View File

@ -10,15 +10,12 @@ import de.neemann.digital.core.Node;
import de.neemann.digital.core.memory.DataField; import de.neemann.digital.core.memory.DataField;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects;
/** /**
* The Manager to manage all necessary rom images * The Manager to manage all necessary rom images
*/ */
public class ROMManger { public class ROMManger {
/**
* The empty instance
*/
public static final ROMManger EMPTY = new ROMManger();
private final HashMap<String, DataField> roms; private final HashMap<String, DataField> roms;
@ -35,6 +32,8 @@ public class ROMManger {
* @param model the mode to use * @param model the mode to use
*/ */
public void applyTo(Model model) { public void applyTo(Model model) {
if (roms == null)
return;
for (Node n : model.findNode(n -> n instanceof ROMInterface)) { for (Node n : model.findNode(n -> n instanceof ROMInterface)) {
ROMInterface rom = (ROMInterface) n; ROMInterface rom = (ROMInterface) n;
DataField data = roms.get(rom.getLabel()); DataField data = roms.get(rom.getLabel());
@ -65,19 +64,23 @@ public class ROMManger {
roms.put(label, data); roms.put(label, data);
} }
/**
* @return returns EMPTY it this ROMManager is empty, this otherwise
*/
public ROMManger getMinimized() {
if (roms.isEmpty())
return EMPTY;
return this;
}
/** /**
* @return true if no ROM's are stored * @return true if no ROM's are stored
*/ */
public boolean isEmpty() { public boolean isEmpty() {
return roms.isEmpty(); return roms.isEmpty();
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ROMManger romManger = (ROMManger) o;
return Objects.equals(roms, romManger.roms);
}
@Override
public int hashCode() {
return Objects.hash(roms);
}
} }

View File

@ -15,29 +15,12 @@ import java.util.Objects;
/** /**
* Manages the input inverting of a component * Manages the input inverting of a component
*/ */
public class InverterConfig implements HGSMap { public final class InverterConfig implements HGSMap {
private HashSet<String> inputs; private HashSet<String> inputs;
/** private InverterConfig(HashSet<String> inputs) {
* Creates a new instance. this.inputs = inputs;
* No input is inverted.
*/
public InverterConfig() {
inputs = null;
}
/**
* Adds a signal to invert
*
* @param name the signale
* @return this for chained calls
*/
public InverterConfig add(String name) {
if (inputs == null)
inputs = new HashSet<>();
inputs.add(name);
return this;
} }
/** /**
@ -129,4 +112,35 @@ public class InverterConfig implements HGSMap {
return inputs.contains(key); return inputs.contains(key);
} }
/**
* Builder to create InverterConfig instances
*/
public static class Builder {
private HashSet<String> inputs;
/**
* Adds a signal to invert
*
* @param name the signale
* @return this for chained calls
*/
public Builder add(String name) {
if (inputs == null)
inputs = new HashSet<>();
inputs.add(name);
return this;
}
/**
* Creats the instance
*
* @return the created instance
*/
public InverterConfig build() {
return new InverterConfig(inputs);
}
}
} }

View File

@ -212,7 +212,7 @@ public final class ShapeFactory {
return new LayoutShape(customDescr, elementAttributes); return new LayoutShape(customDescr, elementAttributes);
case CUSTOM: case CUSTOM:
final CustomShapeDescription customShapeDescription = customDescr.getAttributes().get(Keys.CUSTOM_SHAPE); final CustomShapeDescription customShapeDescription = customDescr.getAttributes().get(Keys.CUSTOM_SHAPE);
if (customShapeDescription != CustomShapeDescription.EMPTY) if (!customShapeDescription.isEmpty())
return new CustomShape(customShapeDescription, elementAttributes.getLabel(), return new CustomShape(customShapeDescription, elementAttributes.getLabel(),
pt.getInputDescription(elementAttributes), pt.getInputDescription(elementAttributes),
pt.getOutputDescriptions(elementAttributes)); pt.getOutputDescriptions(elementAttributes));

View File

@ -24,95 +24,19 @@ import java.util.Iterator;
/** /**
* Is intended to be stored in a file. * Is intended to be stored in a file.
*/ */
public class CustomShapeDescription implements Iterable<CustomShapeDescription.Holder> { public final class CustomShapeDescription implements Iterable<CustomShapeDescription.Holder> {
/**
* The default empty shape instance
*/
public static final CustomShapeDescription EMPTY = new CustomShapeDescription();
private HashMap<String, Pin> pins; private final HashMap<String, Pin> pins;
private ArrayList<Holder> drawables; private final ArrayList<Holder> drawables;
private TextHolder label; private final TextHolder label;
/** /**
* Creates a new instance * Creates a new instance
*/ */
public CustomShapeDescription() { private CustomShapeDescription(HashMap<String, Pin> pins, ArrayList<Holder> drawables, TextHolder label) {
pins = new HashMap<>(); this.pins = pins;
drawables = new ArrayList<>(); this.drawables = drawables;
} this.label = label;
/**
* Adds a pin to this shape description
*
* @param name the name of the pin
* @param pos the pins position
* @param showLabel if true the label of the pin is shown
* @return this for chained calls
*/
public CustomShapeDescription addPin(String name, Vector pos, boolean showLabel) {
pins.put(name, new Pin(pos, showLabel));
return this;
}
/**
* Adds a polygon to the shape
*
* @param p1 starting point of the line
* @param p2 ending point of the line
* @param thickness the line thickness
* @param color the color to use
* @return this for chained calls
*/
public CustomShapeDescription addLine(Vector p1, Vector p2, int thickness, Color color) {
drawables.add(new LineHolder(p1, p2, thickness, color));
return this;
}
/**
* Adds a circle to the shape
*
* @param p1 upper left corner of the circles bounding box
* @param p2 lower right corner of the circles bounding box
* @param thickness the line thickness
* @param color the color to use
* @param filled true if filled
* @return this for chained calls
*/
public CustomShapeDescription addCircle(Vector p1, Vector p2, int thickness, Color color, boolean filled) {
drawables.add(new CircleHolder(p1, p2, thickness, color, filled));
return this;
}
/**
* Adds a polygon to the shape
*
* @param poly the polygon to add
* @param thickness the line thickness
* @param color the color to use
* @param filled true if filled
* @return this for chained calls
*/
public CustomShapeDescription addPolygon(Polygon poly, int thickness, Color color, boolean filled) {
drawables.add(new PolygonHolder(poly, thickness, filled, color));
return this;
}
/**
* Adds a text to the shape
*
* @param p1 position
* @param p2 second position to determin the base line orientation
* @param text the text to draw
* @param orientation the orientation of the text
* @param size the font size
* @param color the text color
* @return this for chained calls
*/
public CustomShapeDescription addText(Vector p1, Vector p2, String text, Orientation orientation, int size, Color color) {
drawables.add(new TextHolder(p1, p2, text, orientation, size, color));
return this;
} }
/** /**
@ -155,19 +79,6 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
return pins.size(); return pins.size();
} }
/**
* Sets the label positioning info.
*
* @param pos0 pos0
* @param pos1 pos1
* @param textOrientation textOrientation
* @param fontSize fontSize
* @param filled filled
*/
public void setLabel(Vector pos0, Vector pos1, Orientation textOrientation, int fontSize, Color filled) {
label = new TextHolder(pos0, pos1, "", textOrientation, fontSize, filled);
}
/** /**
* @return the TextHolder used to draw the label, maybe null * @return the TextHolder used to draw the label, maybe null
*/ */
@ -182,6 +93,13 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
return pins.values(); return pins.values();
} }
/**
* @return true if shape is empty
*/
public boolean isEmpty() {
return drawables.isEmpty() && pins.isEmpty();
}
/** /**
* Checks the compatibility of this shape to the given circuit * Checks the compatibility of this shape to the given circuit
* *
@ -201,6 +119,26 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
throw new PinException(Lang.get("err_morePinsDefinedInSVGAsNeeded")); throw new PinException(Lang.get("err_morePinsDefinedInSVGAsNeeded"));
} }
/*
* Two CustomShapeDescriptions are equal if and only if they are both empty!
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomShapeDescription customShapeDescription = (CustomShapeDescription) o;
return customShapeDescription.isEmpty() && isEmpty();
}
@Override
public int hashCode() {
if (isEmpty())
return 0;
return super.hashCode();
}
private interface Transformable { private interface Transformable {
void transform(Transform tr); void transform(Transform tr);
} }
@ -423,4 +361,117 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
pos = pos.transform(tr).round(); pos = pos.transform(tr).round();
} }
} }
/**
* Used to build a custom shape description
*/
public static final class Builder {
private final HashMap<String, Pin> pins;
private final ArrayList<Holder> drawables;
private TextHolder label;
/**
* Creates a new builder
*/
public Builder() {
pins = new HashMap<>();
drawables = new ArrayList<>();
}
/**
* Sets the label positioning info.
*
* @param pos0 pos0
* @param pos1 pos1
* @param textOrientation textOrientation
* @param fontSize fontSize
* @param filled filled
* @return this for chained calls
*/
public Builder setLabel(Vector pos0, Vector pos1, Orientation textOrientation, int fontSize, Color filled) {
label = new TextHolder(pos0, pos1, "", textOrientation, fontSize, filled);
return this;
}
/**
* Adds a pin to this shape description
*
* @param name the name of the pin
* @param pos the pins position
* @param showLabel if true the label of the pin is shown
* @return this for chained calls
*/
public Builder addPin(String name, Vector pos, boolean showLabel) {
pins.put(name, new Pin(pos, showLabel));
return this;
}
/**
* Adds a polygon to the shape
*
* @param p1 starting point of the line
* @param p2 ending point of the line
* @param thickness the line thickness
* @param color the color to use
* @return this for chained calls
*/
public Builder addLine(Vector p1, Vector p2, int thickness, Color color) {
drawables.add(new LineHolder(p1, p2, thickness, color));
return this;
}
/**
* Adds a circle to the shape
*
* @param p1 upper left corner of the circles bounding box
* @param p2 lower right corner of the circles bounding box
* @param thickness the line thickness
* @param color the color to use
* @param filled true if filled
* @return this for chained calls
*/
public Builder addCircle(Vector p1, Vector p2, int thickness, Color color, boolean filled) {
drawables.add(new CircleHolder(p1, p2, thickness, color, filled));
return this;
}
/**
* Adds a polygon to the shape
*
* @param poly the polygon to add
* @param thickness the line thickness
* @param color the color to use
* @param filled true if filled
* @return this for chained calls
*/
public Builder addPolygon(Polygon poly, int thickness, Color color, boolean filled) {
drawables.add(new PolygonHolder(poly, thickness, filled, color));
return this;
}
/**
* Adds a text to the shape
*
* @param p1 position
* @param p2 second position to determin the base line orientation
* @param text the text to draw
* @param orientation the orientation of the text
* @param size the font size
* @param color the text color
* @return this for chained calls
*/
public Builder addText(Vector p1, Vector p2, String text, Orientation orientation, int size, Color color) {
drawables.add(new TextHolder(p1, p2, text, orientation, size, color));
return this;
}
/**
* @return the {@link CustomShapeDescription}
*/
public CustomShapeDescription build() {
return new CustomShapeDescription(pins, drawables, label);
}
}
} }

View File

@ -67,9 +67,10 @@ public class SvgImporter {
NodeList gList = svg.getElementsByTagName("svg").item(0).getChildNodes(); NodeList gList = svg.getElementsByTagName("svg").item(0).getChildNodes();
Context c = new Context(); Context c = new Context();
try { try {
CustomShapeDescription csd = new CustomShapeDescription(); CustomShapeDescription.Builder builder = new CustomShapeDescription.Builder();
create(csd, gList, c); create(builder, gList, c);
CustomShapeDescription csd = builder.build();
if (csd.getPinCount() > 0) { if (csd.getPinCount() > 0) {
float xMin = Float.MAX_VALUE; float xMin = Float.MAX_VALUE;
float yMin = Float.MAX_VALUE; float yMin = Float.MAX_VALUE;
@ -86,7 +87,7 @@ public class SvgImporter {
} }
} }
private void create(CustomShapeDescription csd, NodeList gList, Context c) throws SvgException { private void create(CustomShapeDescription.Builder csd, NodeList gList, Context c) throws SvgException {
for (int i = 0; i < gList.getLength(); i++) { for (int i = 0; i < gList.getLength(); i++) {
final Node node = gList.item(i); final Node node = gList.item(i);
if (node instanceof Element) { if (node instanceof Element) {
@ -99,7 +100,7 @@ public class SvgImporter {
} }
} }
private void create(CustomShapeDescription csd, Element element, Context parent) throws SvgException { private void create(CustomShapeDescription.Builder csd, Element element, Context parent) throws SvgException {
Context c = new Context(parent, element); Context c = new Context(parent, element);
switch (element.getNodeName()) { switch (element.getNodeName()) {
case "a": case "a":
@ -150,19 +151,19 @@ public class SvgImporter {
} }
} }
private void drawTransformedPolygon(CustomShapeDescription csd, Context c, Polygon polygon) { private void drawTransformedPolygon(CustomShapeDescription.Builder csd, Context c, Polygon polygon) {
if (polygon != null) if (polygon != null)
drawPolygon(csd, c, polygon.transform(c.getTransform())); drawPolygon(csd, c, polygon.transform(c.getTransform()));
} }
private void drawPolygon(CustomShapeDescription csd, Context c, Polygon polygon) { private void drawPolygon(CustomShapeDescription.Builder csd, Context c, Polygon polygon) {
if (c.getFilled() != null && polygon.isClosed()) if (c.getFilled() != null && polygon.isClosed())
csd.addPolygon(polygon, c.getThickness(), c.getFilled(), true); csd.addPolygon(polygon, c.getThickness(), c.getFilled(), true);
if (c.getStroke() != null) if (c.getStroke() != null)
csd.addPolygon(polygon, c.getThickness(), c.getStroke(), false); csd.addPolygon(polygon, c.getThickness(), c.getStroke(), false);
} }
private void drawRect(CustomShapeDescription csd, Element element, Context c) { private void drawRect(CustomShapeDescription.Builder csd, Element element, Context c) {
VectorInterface size = new VectorFloat(c.getLength(element.getAttribute("width")), c.getLength(element.getAttribute("height"))); VectorInterface size = new VectorFloat(c.getLength(element.getAttribute("width")), c.getLength(element.getAttribute("height")));
VectorInterface pos = new VectorFloat(c.getLength(element.getAttribute("x")), c.getLength(element.getAttribute("y"))); VectorInterface pos = new VectorFloat(c.getLength(element.getAttribute("x")), c.getLength(element.getAttribute("y")));
String rxStr = element.getAttribute("rx"); String rxStr = element.getAttribute("rx");
@ -213,7 +214,7 @@ public class SvgImporter {
drawPolygon(csd, c, polygon); drawPolygon(csd, c, polygon);
} }
private void drawCircle(CustomShapeDescription csd, Element element, Context c) { private void drawCircle(CustomShapeDescription.Builder csd, Element element, Context c) {
if (element.hasAttribute("id")) { if (element.hasAttribute("id")) {
VectorInterface pos = c.v(c.getLength(element.getAttribute("cx")), c.getLength(element.getAttribute("cy"))); VectorInterface pos = c.v(c.getLength(element.getAttribute("cx")), c.getLength(element.getAttribute("cy")));
String id = element.getAttribute("id"); String id = element.getAttribute("id");
@ -279,7 +280,7 @@ public class SvgImporter {
return new Vector(Math.round(pos.getXFloat() / SIZE) * SIZE, Math.round(pos.getYFloat() / SIZE) * SIZE); return new Vector(Math.round(pos.getXFloat() / SIZE) * SIZE, Math.round(pos.getYFloat() / SIZE) * SIZE);
} }
private void drawText(CustomShapeDescription csd, Context c, Element element) throws SvgException { private void drawText(CustomShapeDescription.Builder csd, Context c, Element element) throws SvgException {
VectorFloat p = new VectorFloat(c.getLength(element.getAttribute("x")), c.getLength(element.getAttribute("y"))); VectorFloat p = new VectorFloat(c.getLength(element.getAttribute("x")), c.getLength(element.getAttribute("y")));
VectorInterface pos0 = p.transform(c.getTransform()); VectorInterface pos0 = p.transform(c.getTransform());
VectorInterface pos1 = p.add(new VectorFloat(1, 0)).transform(c.getTransform()); VectorInterface pos1 = p.add(new VectorFloat(1, 0)).transform(c.getTransform());
@ -290,7 +291,7 @@ public class SvgImporter {
drawTextElement(csd, c, element, pos0, pos1); drawTextElement(csd, c, element, pos0, pos1);
} }
private void drawTextElement(CustomShapeDescription csd, Context c, Element element, VectorInterface pos0, VectorInterface pos1) throws SvgException { private void drawTextElement(CustomShapeDescription.Builder csd, Context c, Element element, VectorInterface pos0, VectorInterface pos1) throws SvgException {
NodeList nodes = element.getElementsByTagName("*"); NodeList nodes = element.getElementsByTagName("*");
if (nodes.getLength() == 0) { if (nodes.getLength() == 0) {
String text = element.getTextContent(); String text = element.getTextContent();

View File

@ -52,7 +52,7 @@ public class CustomShapeEditor extends EditorFactory.LabelEditor<CustomShapeDesc
clear = new ToolTipAction(Lang.get("btn_clearData")) { clear = new ToolTipAction(Lang.get("btn_clearData")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
customShapeDescription = CustomShapeDescription.EMPTY; customShapeDescription = new CustomShapeDescription.Builder().build();
} }
}; };
panel.add(clear.createJButton()); panel.add(clear.createJButton());

View File

@ -1010,12 +1010,12 @@ public final class EditorFactory {
} }
private InverterConfig getInverterConfig() { private InverterConfig getInverterConfig() {
InverterConfig ic = new InverterConfig(); InverterConfig.Builder ic = new InverterConfig.Builder();
for (JCheckBox cb : boxes) { for (JCheckBox cb : boxes) {
if (cb.isSelected()) if (cb.isSelected())
ic.add(cb.getText()); ic.add(cb.getText());
} }
return ic; return ic.build();
} }
} }

View File

@ -206,7 +206,7 @@ public class ROMEditorDialog extends JDialog {
for (RomHolder rh : romlist) for (RomHolder rh : romlist)
rm.addRom(rh.ri.getLabel(), rh.data); rm.addRom(rh.ri.getLabel(), rh.data);
return rm.getMinimized(); return rm;
} }
} }

View File

@ -17,12 +17,6 @@ import java.util.ArrayList;
* The test data. * The test data.
*/ */
public class TestCaseDescription { public class TestCaseDescription {
/**
* the default instance
*/
public static final TestCaseDescription DEFAULT = new TestCaseDescription("");
private String dataString; private String dataString;
private transient LineEmitter lines; private transient LineEmitter lines;
private transient ArrayList<String> names; private transient ArrayList<String> names;

View File

@ -18,7 +18,7 @@ public class TestCaseElement implements Element {
/** /**
* the used {@link ElementAttributes} key * the used {@link ElementAttributes} key
*/ */
public static final Key<TestCaseDescription> TESTDATA = new Key<>("Testdata", TestCaseDescription.DEFAULT); public static final Key<TestCaseDescription> TESTDATA = new Key<>("Testdata", () -> new TestCaseDescription(""));
/** /**
* The TestCaseElement description * The TestCaseElement description