refactoring of IntFormat enums to call instances

This commit is contained in:
hneemann 2021-01-22 10:57:59 +01:00
parent 14d2ed774d
commit 91fce3079b
15 changed files with 198 additions and 108 deletions

View File

@ -8,57 +8,85 @@ package de.neemann.digital.core;
/**
* The int format used to format numbers
*/
public enum IntFormat {
public class IntFormat {
/**
* the default format
*/
def(v -> {
public static final IntFormat DEF = new IntFormat("def", v -> {
final long value = v.getValue();
if (value >= 0 && value < 10)
return Long.toString(value);
else
return "0x" + toShortHex(value, true);
}, bits -> (bits - 1) / 4 + 3),
}, bits -> (bits - 1) / 4 + 3) {
@Override
public String formatToView(Value inValue) {
if (inValue.isHighZ())
return inValue.toString();
else
return toShortHex(inValue.getValue(), false);
}
};
/**
* decimal
*/
dec(v -> Long.toString(v.getValue()), IntFormat::decStrLen),
public static final IntFormat DEC = new IntFormat("dec", v -> Long.toString(v.getValue()), IntFormat::decStrLen);
/**
* decimal signed
*/
decSigned(v -> Long.toString(v.getValueSigned()), bits -> decStrLen(bits - 1) + 1, true),
public static final IntFormat DEC_SIGNED = new IntFormat("decSigned", v -> Long.toString(v.getValueSigned()), bits -> decStrLen(bits - 1) + 1, true);
/**
* hexadecimal
*/
hex(v -> "0x" + toHex(v), bits -> (bits - 1) / 4 + 3),
public static final IntFormat HEX = new IntFormat("hex", v -> "0x" + toHex(v), bits -> (bits - 1) / 4 + 3);
/**
* binary
*/
bin(v -> "0b" + toBin(v), bits -> bits + 2),
public static final IntFormat BIN = new IntFormat("bin", v -> "0b" + toBin(v), bits -> bits + 2);
/**
* octal
*/
oct(v -> "0" + toOct(v), bits -> (bits - 1) / 3 + 3),
public static final IntFormat OCT = new IntFormat("oct", v -> "0" + toOct(v), bits -> (bits - 1) / 3 + 3);
/**
* ascii format
*/
ascii(v -> "'" + (char) v.getValue() + "'", bits -> 3);
public static final IntFormat ASCII = new IntFormat("ascii", v -> "'" + (char) v.getValue() + "'", bits -> 3);
/**
* All the available formats
*/
public static final IntFormat[] VALUES = new IntFormat[]{DEF, DEC, DEC_SIGNED, HEX, BIN, OCT, ASCII};
private final String name;
private final EditFormat format;
private final StrLen strLen;
private final boolean signed;
IntFormat(EditFormat format, StrLen strLen) {
this(format, strLen, false);
IntFormat(String name, EditFormat format, StrLen strLen) {
this(name, format, strLen, false);
}
IntFormat(EditFormat format, StrLen strLen, boolean signed) {
IntFormat(String name, EditFormat format, StrLen strLen, boolean signed) {
this.name = name;
this.format = format;
this.strLen = strLen;
this.signed = signed;
}
/**
* Returns the format instance matching th given name
*
* @param name the name of the format
* @return the format
*/
public static IntFormat getFromName(String name) {
for (IntFormat f : VALUES)
if (f.getName().equals(name))
return f;
return DEF;
}
/**
* Formats the value.
* Uses this method to create a string which is only shown to the user.
@ -70,11 +98,8 @@ public enum IntFormat {
public String formatToView(Value inValue) {
if (inValue.isHighZ())
return inValue.toString();
if (this.equals(def))
return toShortHex(inValue.getValue(), false);
return formatToEdit(inValue);
else
return formatToEdit(inValue);
}
/**
@ -102,6 +127,18 @@ public enum IntFormat {
return strLen.strLen(bits);
}
/**
* @return the name of this format
*/
public String getName() {
return name;
}
@Override
public String toString() {
return getName();
}
private static int decStrLen(int bits) {
if (bits == 64)
return 20;
@ -155,7 +192,7 @@ public enum IntFormat {
private static final int BUF = 16;
private static String toShortHex(long value, boolean omitPrefix) {
static String toShortHex(long value, boolean omitPrefix) {
if (value == 0)
return "0";
@ -198,6 +235,17 @@ public enum IntFormat {
return signed;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
return o != null && getClass() == o.getClass();
}
@Override
public int hashCode() {
return getClass().hashCode();
}
private interface StrLen {
int strLen(int bits);
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 Helmut Neemann.
* Use of this source code is governed by the GPL v3 license
* that can be found in the LICENSE file.
*/
package de.neemann.digital.core;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
/**
* Converter to write a polygon to a xml file
*/
public class IntFormatConverter implements Converter {
@Override
public boolean canConvert(Class aClass) {
return aClass.equals(IntFormat.class);
}
@Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) {
writer.setValue(o.toString());
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) {
return IntFormat.getFromName(reader.getValue());
}
}

View File

@ -12,7 +12,7 @@ public final class Signal implements Comparable<Signal> {
private final String name;
private final ObservableValue value;
private final Setter setter;
private IntFormat format = IntFormat.def;
private IntFormat format = IntFormat.DEF;
private String pinNumber;
private ObservableValue bidirectionalReader;
private boolean showInGraph;

View File

@ -430,7 +430,7 @@ public class Key<VALUE> {
*
* @param <E> the enum type
*/
public static final class KeyEnum<E extends Enum> extends Key<E> {
public static final class KeyEnum<E> extends Key<E> {
private final E[] values;
private final String[] names;
@ -458,7 +458,7 @@ public class Key<VALUE> {
* @return the language key
*/
public String getLangKey(E value) {
return getLangKey() + "_" + value.name();
return getLangKey() + "_" + value.toString();
}
/**

View File

@ -498,7 +498,7 @@ public final class Keys {
* output format for numbers
*/
public static final Key<IntFormat> INT_FORMAT
= new Key.KeyEnum<>("intFormat", IntFormat.def, IntFormat.values()).setSecondary();
= new Key.KeyEnum<>("intFormat", IntFormat.DEF, IntFormat.VALUES).setSecondary();
/**
* width of the terminal

View File

@ -31,6 +31,6 @@ public interface RAMInterface extends ProgramMemory, Countable {
* @return the integer format to be used to visualize the values
*/
default IntFormat getIntFormat() {
return IntFormat.hex;
return IntFormat.HEX;
}
}

View File

@ -316,9 +316,9 @@ public class ValueTable extends Observable implements Iterable<TestRow> {
*/
public ColumnInfo(IntFormat format, int bits) {
if (format == null)
format = IntFormat.def;
if (format.equals(IntFormat.def) && (bits > 3))
format = IntFormat.hex;
format = IntFormat.DEF;
if (format.equals(IntFormat.DEF) && (bits > 3))
format = IntFormat.HEX;
this.format = format;
this.bits = bits;
}

View File

@ -102,6 +102,7 @@ public class Circuit implements Copyable<Circuit> {
xStream.alias("shapeType", CustomCircuitShapeType.class);
xStream.alias("transform", TransformHolder.class);
xStream.registerConverter(new PolygonConverter());
xStream.registerConverter(new IntFormatConverter());
return xStream;
}

View File

@ -62,8 +62,8 @@ public class DataEditor extends JDialog {
this.dataBits = dataBits;
this.addrBits = addrBits;
dataFormat = intFormat;
if (intFormat.equals(IntFormat.ascii) || intFormat.equals(IntFormat.bin))
addrFormat = IntFormat.def;
if (intFormat.equals(IntFormat.ASCII) || intFormat.equals(IntFormat.BIN))
addrFormat = IntFormat.DEF;
else
addrFormat = intFormat;

View File

@ -97,7 +97,7 @@ public final class EditorFactory {
if (fac == null) {
if (key instanceof Key.KeyEnum)
return new EnumEditor((Enum) value, key);
return new EnumEditor(value, key);
throw new RuntimeException("no editor found for " + key.getValueClass().getSimpleName());
}
@ -758,19 +758,19 @@ public final class EditorFactory {
}
}
private static class EnumEditor<E extends Enum> extends LabelEditor<E> {
private static class EnumEditor<E> extends LabelEditor<E> {
private final JComboBox comboBox;
private final E[] values;
private final String[] names;
public EnumEditor(Enum value, Key<E> key) {
public EnumEditor(E value, Key<E> key) {
if (!(key instanceof Key.KeyEnum))
throw new RuntimeException("wrong enum type");
this.names = ((Key.KeyEnum<E>) key).getNames();
this.values = ((Key.KeyEnum<E>) key).getValues();
comboBox = new JComboBox<>(names);
comboBox.setSelectedIndex(value.ordinal());
comboBox.setSelectedIndex(indexOf(value));
}
@Override
@ -785,7 +785,14 @@ public final class EditorFactory {
@Override
public void setValue(E value) {
comboBox.setSelectedIndex(value.ordinal());
comboBox.setSelectedIndex(indexOf(value));
}
private int indexOf(E value) {
for (int i = 0; i < values.length; i++)
if (value == values[i])
return i;
return 0;
}
@Override

View File

@ -20,6 +20,8 @@ import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Arrays;
import static de.neemann.digital.core.IntFormat.*;
/**
* Dialog to edit a single value.
* Used to enter a multi bit input value.
@ -57,19 +59,16 @@ public final class SingleValueDialog extends JDialog implements ModelStateObserv
}
private static InMode getByFormat(IntFormat format) {
switch (format) {
case decSigned:
case dec:
return SingleValueDialog.InMode.DECIMAL;
case oct:
return SingleValueDialog.InMode.OCTAL;
case bin:
return SingleValueDialog.InMode.BIN;
case ascii:
return SingleValueDialog.InMode.ASCII;
default:
return SingleValueDialog.InMode.HEX;
if (DEC_SIGNED.equals(format) || DEC.equals(format)) {
return InMode.DECIMAL;
} else if (OCT.equals(format)) {
return InMode.OCTAL;
} else if (IntFormat.BIN.equals(format)) {
return InMode.BIN;
} else if (IntFormat.ASCII.equals(format)) {
return InMode.ASCII;
}
return InMode.HEX;
}
}

View File

@ -10,40 +10,40 @@ import junit.framework.TestCase;
public class IntFormatTest extends TestCase {
public void testHex() throws Exception {
assertEquals("0x1", IntFormat.hex.formatToView(new Value(1, 1)));
assertEquals("0x1", IntFormat.hex.formatToView(new Value(1, 2)));
assertEquals("0x1", IntFormat.hex.formatToView(new Value(1, 3)));
assertEquals("0x1", IntFormat.hex.formatToView(new Value(1, 4)));
assertEquals("0xF", IntFormat.hex.formatToView(new Value(-1, 4)));
assertEquals("0x01", IntFormat.hex.formatToView(new Value(1, 5)));
assertEquals("0x1F", IntFormat.hex.formatToView(new Value(-1, 5)));
assertEquals("0xFFF", IntFormat.hex.formatToView(new Value(-1, 12)));
assertEquals("0x1FFF", IntFormat.hex.formatToView(new Value(-1, 13)));
assertEquals("0x3FFF", IntFormat.hex.formatToView(new Value(-1, 14)));
assertEquals("0x7FFF", IntFormat.hex.formatToView(new Value(-1, 15)));
assertEquals("0xFFFF", IntFormat.hex.formatToView(new Value(-1, 16)));
assertEquals("0xFEDCBA9876543210", IntFormat.hex.formatToView(new Value(0xFEDCBA9876543210L, 64)));
assertEquals("0x1", IntFormat.HEX.formatToView(new Value(1, 1)));
assertEquals("0x1", IntFormat.HEX.formatToView(new Value(1, 2)));
assertEquals("0x1", IntFormat.HEX.formatToView(new Value(1, 3)));
assertEquals("0x1", IntFormat.HEX.formatToView(new Value(1, 4)));
assertEquals("0xF", IntFormat.HEX.formatToView(new Value(-1, 4)));
assertEquals("0x01", IntFormat.HEX.formatToView(new Value(1, 5)));
assertEquals("0x1F", IntFormat.HEX.formatToView(new Value(-1, 5)));
assertEquals("0xFFF", IntFormat.HEX.formatToView(new Value(-1, 12)));
assertEquals("0x1FFF", IntFormat.HEX.formatToView(new Value(-1, 13)));
assertEquals("0x3FFF", IntFormat.HEX.formatToView(new Value(-1, 14)));
assertEquals("0x7FFF", IntFormat.HEX.formatToView(new Value(-1, 15)));
assertEquals("0xFFFF", IntFormat.HEX.formatToView(new Value(-1, 16)));
assertEquals("0xFEDCBA9876543210", IntFormat.HEX.formatToView(new Value(0xFEDCBA9876543210L, 64)));
}
public void testBin() {
assertEquals("0b1", IntFormat.bin.formatToView(new Value(1, 1)));
assertEquals("0b01", IntFormat.bin.formatToView(new Value(1, 2)));
assertEquals("0b001", IntFormat.bin.formatToView(new Value(1, 3)));
assertEquals("0b111", IntFormat.bin.formatToView(new Value(-1, 3)));
assertEquals("0b1111111111111111111111111111111111111111111111111111111111111111", IntFormat.bin.formatToView(new Value(-1, 64)));
assertEquals("0b1000111111111111111111111111111111111111111111111111111111111111", IntFormat.bin.formatToView(new Value(0x8fffffffffffffffL, 64)));
assertEquals("0b1", IntFormat.BIN.formatToView(new Value(1, 1)));
assertEquals("0b01", IntFormat.BIN.formatToView(new Value(1, 2)));
assertEquals("0b001", IntFormat.BIN.formatToView(new Value(1, 3)));
assertEquals("0b111", IntFormat.BIN.formatToView(new Value(-1, 3)));
assertEquals("0b1111111111111111111111111111111111111111111111111111111111111111", IntFormat.BIN.formatToView(new Value(-1, 64)));
assertEquals("0b1000111111111111111111111111111111111111111111111111111111111111", IntFormat.BIN.formatToView(new Value(0x8fffffffffffffffL, 64)));
}
public void testDec() throws Exception {
assertEquals("3", IntFormat.dec.formatToView(new Value(-1, 2)));
assertEquals("-1", IntFormat.decSigned.formatToView(new Value(-1, 2)));
assertEquals("3", IntFormat.DEC.formatToView(new Value(-1, 2)));
assertEquals("-1", IntFormat.DEC_SIGNED.formatToView(new Value(-1, 2)));
}
public void testDef() throws Exception {
assertEquals("3", IntFormat.def.formatToView(new Value(3, 64)));
assertEquals("0x113", IntFormat.def.formatToView(new Value(0x113, 64)));
assertEquals("1A3", IntFormat.def.formatToView(new Value(0x1A3, 64)));
assertEquals("FFFFFFFFFFFFFFFF", IntFormat.def.formatToView(new Value(-1, 64)));
assertEquals("3", IntFormat.DEF.formatToView(new Value(3, 64)));
assertEquals("0x113", IntFormat.DEF.formatToView(new Value(0x113, 64)));
assertEquals("1A3", IntFormat.DEF.formatToView(new Value(0x1A3, 64)));
assertEquals("FFFFFFFFFFFFFFFF", IntFormat.DEF.formatToView(new Value(-1, 64)));
}
/**
@ -51,8 +51,8 @@ public class IntFormatTest extends TestCase {
* back to the same value by {@link Bits#decode(String)}
*/
public void testBitDecodeConstraint() throws Bits.NumberFormatException {
for (IntFormat f : IntFormat.values()) {
if (f == IntFormat.ascii) {
for (IntFormat f : IntFormat.VALUES) {
if (f == IntFormat.ASCII) {
checkConstraint(f, tableAscii); // ascii supports only 16 bit
} else {
checkConstraint(f, table);
@ -83,45 +83,45 @@ public class IntFormatTest extends TestCase {
for (Value val : table) {
final String str = format.formatToEdit(val);
final Value conv = new Value(Bits.decode(str), val.getBits());
assertTrue(format.name() + ":" + val + " != " + conv, val.isEqual(conv));
assertTrue(format.getName() + ":" + val + " != " + conv, val.isEqual(conv));
}
}
public void testStrLen() {
assertEquals(6,IntFormat.hex.strLen(16));
assertEquals(6,IntFormat.hex.strLen(15));
assertEquals(6,IntFormat.hex.strLen(14));
assertEquals(6,IntFormat.hex.strLen(13));
assertEquals(5,IntFormat.hex.strLen(12));
assertEquals(6, IntFormat.HEX.strLen(16));
assertEquals(6, IntFormat.HEX.strLen(15));
assertEquals(6, IntFormat.HEX.strLen(14));
assertEquals(6, IntFormat.HEX.strLen(13));
assertEquals(5, IntFormat.HEX.strLen(12));
assertEquals(18,IntFormat.bin.strLen(16));
assertEquals(17,IntFormat.bin.strLen(15));
assertEquals(16,IntFormat.bin.strLen(14));
assertEquals(18, IntFormat.BIN.strLen(16));
assertEquals(17, IntFormat.BIN.strLen(15));
assertEquals(16, IntFormat.BIN.strLen(14));
assertEquals(3,IntFormat.dec.strLen(8));
assertEquals(3,IntFormat.dec.strLen(9));
assertEquals(4,IntFormat.dec.strLen(10));
assertEquals(19, IntFormat.dec.strLen(60));
assertEquals(19, IntFormat.dec.strLen(61));
assertEquals(19, IntFormat.dec.strLen(62));
assertEquals(19, IntFormat.dec.strLen(63));
assertEquals(20, IntFormat.dec.strLen(64));
assertEquals(3, IntFormat.DEC.strLen(8));
assertEquals(3, IntFormat.DEC.strLen(9));
assertEquals(4, IntFormat.DEC.strLen(10));
assertEquals(19, IntFormat.DEC.strLen(60));
assertEquals(19, IntFormat.DEC.strLen(61));
assertEquals(19, IntFormat.DEC.strLen(62));
assertEquals(19, IntFormat.DEC.strLen(63));
assertEquals(20, IntFormat.DEC.strLen(64));
assertEquals(4,IntFormat.decSigned.strLen(8));
assertEquals(4,IntFormat.decSigned.strLen(9));
assertEquals(4,IntFormat.decSigned.strLen(10));
assertEquals(5,IntFormat.decSigned.strLen(11));
assertEquals(20, IntFormat.decSigned.strLen(62));
assertEquals(20, IntFormat.decSigned.strLen(63));
assertEquals(20, IntFormat.decSigned.strLen(64));
assertEquals(4, IntFormat.DEC_SIGNED.strLen(8));
assertEquals(4, IntFormat.DEC_SIGNED.strLen(9));
assertEquals(4, IntFormat.DEC_SIGNED.strLen(10));
assertEquals(5, IntFormat.DEC_SIGNED.strLen(11));
assertEquals(20, IntFormat.DEC_SIGNED.strLen(62));
assertEquals(20, IntFormat.DEC_SIGNED.strLen(63));
assertEquals(20, IntFormat.DEC_SIGNED.strLen(64));
assertEquals(4,IntFormat.oct.strLen(4));
assertEquals(4,IntFormat.oct.strLen(5));
assertEquals(4,IntFormat.oct.strLen(6));
assertEquals(5,IntFormat.oct.strLen(7));
assertEquals(5,IntFormat.oct.strLen(8));
assertEquals(5,IntFormat.oct.strLen(9));
assertEquals(6,IntFormat.oct.strLen(10));
assertEquals(4, IntFormat.OCT.strLen(4));
assertEquals(4, IntFormat.OCT.strLen(5));
assertEquals(4, IntFormat.OCT.strLen(6));
assertEquals(5, IntFormat.OCT.strLen(7));
assertEquals(5, IntFormat.OCT.strLen(8));
assertEquals(5, IntFormat.OCT.strLen(9));
assertEquals(6, IntFormat.OCT.strLen(10));
}
}

View File

@ -20,6 +20,6 @@ public class ValueTest extends TestCase {
public void testFromInValue() throws Bits.NumberFormatException {
assertEquals("5", new Value(new InValue("5"), 4).toString());
assertEquals("Z", new Value(new InValue("z"), 4).toString());
assertEquals("Z", IntFormat.hex.formatToEdit(new Value(new InValue("z"), 4)));
assertEquals("Z", IntFormat.HEX.formatToEdit(new Value(new InValue("z"), 4)));
}
}

View File

@ -44,9 +44,9 @@ public class ValueTableTest extends TestCase {
public void testCSV2() throws Exception {
StringWriter sw = new StringWriter();
ValueTable.ColumnInfo[] infos = new ValueTable.ColumnInfo[]{
new ValueTable.ColumnInfo(IntFormat.hex, 4),
new ValueTable.ColumnInfo(IntFormat.oct, 4),
new ValueTable.ColumnInfo(IntFormat.bin, 4),
new ValueTable.ColumnInfo(IntFormat.HEX, 4),
new ValueTable.ColumnInfo(IntFormat.OCT, 4),
new ValueTable.ColumnInfo(IntFormat.BIN, 4),
};
t.saveCSV(new BufferedWriter(sw), infos);
assertEquals("\"step\",\"A\",\"B\",\"C\"\n" +

View File

@ -10,6 +10,7 @@ import de.neemann.digital.core.element.Key;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.graphics.GraphicSVG;
import de.neemann.digital.gui.components.EditorFactory;
import junit.framework.TestCase;
import java.lang.reflect.Field;
@ -28,7 +29,7 @@ public class TestKeyConsistence extends TestCase {
if (key instanceof Key.KeyEnum) {
Key.KeyEnum ke = (Key.KeyEnum) key;
for (Enum v : ke.getValues())
for (Object v : ke.getValues())
checkKey(ke.getLangKey(v));
}
}