refactoring of DataField and DataEditor

This commit is contained in:
hneemann 2016-08-20 18:19:53 +02:00
parent 967c9c88f0
commit ee6d7483ee
12 changed files with 127 additions and 111 deletions

View File

@ -197,7 +197,7 @@
<string>1,15</string> <string>1,15</string>
</entry> </entry>
</elementAttributes> </elementAttributes>
<pos x="600" y="600"/> <pos x="700" y="600"/>
</visualElement> </visualElement>
<visualElement> <visualElement>
<elementName>Out</elementName> <elementName>Out</elementName>
@ -312,12 +312,12 @@
<p2 x="720" y="440"/> <p2 x="720" y="440"/>
</wire> </wire>
<wire> <wire>
<p1 x="600" y="600"/> <p1 x="700" y="600"/>
<p2 x="820" y="600"/> <p2 x="820" y="600"/>
</wire> </wire>
<wire> <wire>
<p1 x="540" y="600"/> <p1 x="540" y="600"/>
<p2 x="580" y="600"/> <p2 x="680" y="600"/>
</wire> </wire>
<wire> <wire>
<p1 x="520" y="280"/> <p1 x="520" y="280"/>

View File

@ -14,11 +14,10 @@ public class DataField {
/*** /***
* Simple default data field * Simple default data field
*/ */
public static final DataField DEFAULT = new DataField(0, 8); public static final DataField DEFAULT = new DataField(0);
private final int size; private final int size;
private long[] data; private long[] data;
private final int bits;
private final transient ArrayList<DataListener> listeners = new ArrayList<>(); private final transient ArrayList<DataListener> listeners = new ArrayList<>();
@ -26,16 +25,14 @@ public class DataField {
* Creates a new DataField * Creates a new DataField
* *
* @param size size * @param size size
* @param bits number of bits
*/ */
public DataField(int size, int bits) { public DataField(int size) {
this(new long[size], size, bits); this(new long[size], size);
} }
private DataField(long[] data, int size, int bits) { private DataField(long[] data, int size) {
this.size = size; this.size = size;
this.data = data; this.data = data;
this.bits = bits;
} }
/** /**
@ -44,10 +41,9 @@ public class DataField {
* *
* @param dataField the data to use * @param dataField the data to use
* @param newSize new size * @param newSize new size
* @param bits number og bits
*/ */
public DataField(DataField dataField, int newSize, int bits) { public DataField(DataField dataField, int newSize) {
this(Arrays.copyOf(dataField.data, newSize), newSize, bits); this(Arrays.copyOf(dataField.data, newSize), newSize);
} }
/** /**
@ -87,7 +83,6 @@ public class DataField {
} }
size = pos; size = pos;
} }
bits = 16;
} }
/** /**
@ -142,14 +137,7 @@ public class DataField {
if (pos == data.length) if (pos == data.length)
return this; return this;
else else
return new DataField(Arrays.copyOf(data, pos), size, bits); return new DataField(Arrays.copyOf(data, pos), size);
}
/**
* @return the number of bits
*/
public int getBits() {
return bits;
} }
/** /**

View File

@ -1,9 +1,6 @@
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;
@ -36,13 +33,13 @@ public class RAMDualPort extends Node implements Element, RAMInterface {
private final DataField memory; private final DataField memory;
private final ObservableValue output; private final ObservableValue output;
protected final int addrBits; private final int addrBits;
protected final int bits; private final int bits;
protected ObservableValue addrIn; private ObservableValue addrIn;
protected ObservableValue dataIn; private ObservableValue dataIn;
protected ObservableValue strIn; private ObservableValue strIn;
protected ObservableValue clkIn; private ObservableValue clkIn;
protected ObservableValue ldIn; private ObservableValue ldIn;
private int addr; private int addr;
private boolean lastClk = false; private boolean lastClk = false;
private boolean ld; private boolean ld;
@ -57,7 +54,7 @@ public class RAMDualPort extends Node implements Element, RAMInterface {
bits = attr.get(Keys.BITS); bits = attr.get(Keys.BITS);
output = createOutput(); output = createOutput();
addrBits = attr.get(Keys.ADDR_BITS); addrBits = attr.get(Keys.ADDR_BITS);
memory = new DataField(1 << addrBits, bits); memory = new DataField(1 << addrBits);
} }
/** /**
@ -71,11 +68,61 @@ public class RAMDualPort extends Node implements Element, RAMInterface {
@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); setAddrIn(inputs.get(0));
dataIn = inputs.get(1).checkBits(bits, this).addObserverToValue(this); setDataIn(inputs.get(1));
strIn = inputs.get(2).checkBits(1, this).addObserverToValue(this); setStrIn(inputs.get(2));
clkIn = inputs.get(3).checkBits(1, this).addObserverToValue(this); setClkIn(inputs.get(3));
ldIn = inputs.get(4).checkBits(1, this).addObserverToValue(this); setLdIn(inputs.get(4));
}
/**
* Sets the addrIn input value
*
* @param addrIn addrIn
* @throws BitsException BitsException
*/
protected void setAddrIn(ObservableValue addrIn) throws BitsException {
this.addrIn = addrIn.checkBits(addrBits, this).addObserverToValue(this);
}
/**
* Sets the dataIn input value
*
* @param dataIn dataIn
* @throws BitsException BitsException
*/
protected void setDataIn(ObservableValue dataIn) throws BitsException {
this.dataIn = dataIn.checkBits(bits, this).addObserverToValue(this);
}
/**
* Sets the strIn input value
*
* @param strIn strIn
* @throws BitsException BitsException
*/
protected void setStrIn(ObservableValue strIn) throws BitsException {
this.strIn = strIn.checkBits(1, this).addObserverToValue(this);
}
/**
* Sets the clkIn input value
*
* @param clkIn clkIn
* @throws BitsException BitsException
*/
protected void setClkIn(ObservableValue clkIn) throws BitsException {
this.clkIn = clkIn.checkBits(1, this).addObserverToValue(this);
}
/**
* Sets the ldIn input value
*
* @param ldIn ldIn
* @throws BitsException BitsException
*/
protected void setLdIn(ObservableValue ldIn) throws BitsException {
this.ldIn = ldIn.checkBits(1, this).addObserverToValue(this);
} }
@Override @Override

View File

@ -56,11 +56,11 @@ public class RAMSinglePort extends RAMDualPort {
@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); setAddrIn(inputs.get(0));
strIn = inputs.get(1).checkBits(1, this).addObserverToValue(this); setStrIn(inputs.get(1));
clkIn = inputs.get(2).checkBits(1, this).addObserverToValue(this); setClkIn(inputs.get(2));
ldIn = inputs.get(3).checkBits(1, this).addObserverToValue(this); setLdIn(inputs.get(3));
dataIn = inputs.get(4).checkBits(bits, this).addObserverToValue(this); // additional input to read the port setDataIn(inputs.get(4)); // additional input to read the port
} }
} }

View File

@ -2,6 +2,8 @@ package de.neemann.digital.draw.shapes;
import de.neemann.digital.core.Observer; import de.neemann.digital.core.Observer;
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.Keys;
import de.neemann.digital.core.element.PinDescriptions; import de.neemann.digital.core.element.PinDescriptions;
import de.neemann.digital.core.memory.DataField; import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.core.memory.RAMInterface; import de.neemann.digital.core.memory.RAMInterface;
@ -14,19 +16,24 @@ import java.awt.*;
/** /**
* The RAM shape * The RAM shape
*
* @author hneemann * @author hneemann
*/ */
public class RAMShape extends GenericShape { public class RAMShape extends GenericShape {
private final int bits;
private final int size;
/** /**
* Creates a new instance * Creates a new instance
* *
* @param name name of the element * @param attr the label to use
* @param inputs the inputs * @param inputs the inputs
* @param outputs the outputs * @param outputs the outputs
* @param label the label to use
*/ */
public RAMShape(String name, PinDescriptions inputs, PinDescriptions outputs, String label) { public RAMShape(ElementAttributes attr, PinDescriptions inputs, PinDescriptions outputs) {
super(name, inputs, outputs, label, true); super("RAM", inputs, outputs, attr.getLabel(), true);
bits = attr.get(Keys.BITS);
size = 1 << attr.get(Keys.ADDR_BITS);
} }
@Override @Override
@ -36,7 +43,7 @@ public class RAMShape extends GenericShape {
public boolean clicked(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync) { public boolean clicked(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync) {
if (element instanceof RAMInterface) { if (element instanceof RAMInterface) {
DataField dataField = ((RAMInterface) element).getMemory(); DataField dataField = ((RAMInterface) element).getMemory();
new DataEditor(cc, dataField, modelSync).showDialog(); new DataEditor(cc, dataField, size, bits, true, modelSync).showDialog();
} }
return false; return false;
} }

View File

@ -69,8 +69,8 @@ public final class ShapeFactory {
} }
map.put(RAMDualPort.DESCRIPTION.getName(), (attr, inputs, outputs) -> new RAMShape("RAM", RAMDualPort.DESCRIPTION.getInputDescription(attr), RAMDualPort.DESCRIPTION.getOutputDescriptions(attr), attr.getLabel())); map.put(RAMDualPort.DESCRIPTION.getName(), (attr, inputs, outputs) -> new RAMShape(attr, RAMDualPort.DESCRIPTION.getInputDescription(attr), RAMDualPort.DESCRIPTION.getOutputDescriptions(attr)));
map.put(RAMSinglePort.DESCRIPTION.getName(), (attr, inputs, outputs) -> new RAMShape("RAM", RAMSinglePort.DESCRIPTION.getInputDescription(attr), RAMSinglePort.DESCRIPTION.getOutputDescriptions(attr), attr.getLabel())); map.put(RAMSinglePort.DESCRIPTION.getName(), (attr, inputs, outputs) -> new RAMShape(attr, RAMSinglePort.DESCRIPTION.getInputDescription(attr), RAMSinglePort.DESCRIPTION.getOutputDescriptions(attr)));
map.put(In.DESCRIPTION.getName(), InputShape::new); map.put(In.DESCRIPTION.getName(), InputShape::new);
map.put(Reset.DESCRIPTION.getName(), ResetShape::new); map.put(Reset.DESCRIPTION.getName(), ResetShape::new);

View File

@ -1,7 +1,5 @@
package de.neemann.digital.gui.components; package de.neemann.digital.gui.components;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.memory.DataField; import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.gui.sync.Sync; import de.neemann.digital.gui.sync.Sync;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
@ -24,7 +22,7 @@ import java.util.ArrayList;
* @author hneemann * @author hneemann
*/ */
public class DataEditor extends JDialog { public class DataEditor extends JDialog {
private final DataField dataField; private final DataField localDataField;
private boolean ok = false; private boolean ok = false;
/** /**
@ -33,71 +31,44 @@ public class DataEditor extends JDialog {
* @param parent the parent * @param parent the parent
* @param dataField the data to edit * @param dataField the data to edit
*/ */
public DataEditor(JComponent parent, DataField dataField, Sync modelSync) { public DataEditor(JComponent parent, DataField dataField, int size, int bits, boolean modelIsRunning, Sync modelSync) {
this(parent, dataField, null, modelSync); super(SwingUtilities.windowForComponent(parent), Lang.get("key_Data"), modelIsRunning ? ModalityType.MODELESS : ModalityType.APPLICATION_MODAL);
}
/**
* Creates a new instance
*
* @param parent the parent
* @param dataField the data to edit
* @param attr uset to get bit sizes
*/
public DataEditor(JComponent parent, DataField dataField, ElementAttributes attr, Sync modelSync) {
super(SwingUtilities.windowForComponent(parent), Lang.get("key_Data"), attr == null ? ModalityType.MODELESS : ModalityType.APPLICATION_MODAL);
setDefaultCloseOperation(DISPOSE_ON_CLOSE); setDefaultCloseOperation(DISPOSE_ON_CLOSE);
int size; if (modelIsRunning)
int bits; localDataField = dataField;
boolean register; else
if (attr != null) { localDataField = new DataField(dataField, size);
bits = attr.getBits();
if (attr.contains(Keys.ADDR_BITS))
size = 1 << attr.get(Keys.ADDR_BITS);
else
size = 1 << attr.get(Keys.INPUT_COUNT);
this.dataField = new DataField(dataField, size, bits);
register = false;
} else {
this.dataField = dataField;
size = this.dataField.size();
bits = this.dataField.getBits();
register = true;
}
int cols = 16; int cols = 16;
if (size <= 16) cols = 1; if (size <= 16) cols = 1;
else if (size <= 128) cols = 8; else if (size <= 128) cols = 8;
MyTableModel dm = new MyTableModel(this.dataField, cols, modelSync); MyTableModel dm = new MyTableModel(this.localDataField, cols, modelSync);
JTable table = new JTable(dm); JTable table = new JTable(dm);
table.setDefaultRenderer(MyLong.class, new MyLongRenderer(bits)); table.setDefaultRenderer(MyLong.class, new MyLongRenderer(bits));
getContentPane().add(new JScrollPane(table)); getContentPane().add(new JScrollPane(table));
if (register) { if (modelIsRunning) {
this.dataField.addListener(dm); dataField.addListener(dm);
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter() {
@Override @Override
public void windowClosed(WindowEvent e) { public void windowClosed(WindowEvent e) {
DataEditor.this.dataField.removeListener(dm); dataField.removeListener(dm);
} }
}); });
} else {
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttons.add(new JButton(new AbstractAction(Lang.get("ok")) {
@Override
public void actionPerformed(ActionEvent e) {
ok = true;
dispose();
}
}));
getContentPane().add(buttons, BorderLayout.SOUTH);
} }
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttons.add(new JButton(new AbstractAction(Lang.get("ok")) {
@Override
public void actionPerformed(ActionEvent e) {
ok = true;
dispose();
}
}));
getContentPane().add(buttons, BorderLayout.SOUTH);
setPreferredSize(new Dimension((cols + 1) * 50, getPreferredSize().height)); setPreferredSize(new Dimension((cols + 1) * 50, getPreferredSize().height));
pack(); pack();
@ -108,8 +79,8 @@ public class DataEditor extends JDialog {
/** /**
* @return the data field * @return the data field
*/ */
public DataField getDataField() { public DataField getModifiedDataField() {
return dataField; return localDataField;
} }
/** /**
@ -174,7 +145,7 @@ public class DataEditor extends JDialog {
@Override @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
modelSync.access(()->{ modelSync.access(() -> {
dataField.setData(rowIndex * cols + (columnIndex - 1), ((MyLong) aValue).getValue()); dataField.setData(rowIndex * cols + (columnIndex - 1), ((MyLong) aValue).getValue());
}); });
} }

View File

@ -2,6 +2,7 @@ package de.neemann.digital.gui.components;
import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.Key; import de.neemann.digital.core.element.Key;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.Rotation; import de.neemann.digital.core.element.Rotation;
import de.neemann.digital.core.io.IntFormat; import de.neemann.digital.core.io.IntFormat;
import de.neemann.digital.core.memory.DataField; import de.neemann.digital.core.memory.DataField;
@ -236,9 +237,11 @@ public final class EditorFactory {
panel.add(new ToolTipAction(Lang.get("btn_edit")) { panel.add(new ToolTipAction(Lang.get("btn_edit")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
DataEditor de = new DataEditor(panel, data, attr, NoSync.INST); int bits = attr.get(Keys.BITS);
int size = 1 << attr.get(Keys.ADDR_BITS);
DataEditor de = new DataEditor(panel, data, size, bits, false, NoSync.INST);
if (de.showDialog()) { if (de.showDialog()) {
data = de.getDataField(); data = de.getModifiedDataField();
} }
} }
}.createJButton()); }.createJButton());

View File

@ -67,7 +67,7 @@ public class GraphicCard extends Node implements Element, RAMInterface {
width = attr.get(Keys.GRAPHIC_WIDTH); width = attr.get(Keys.GRAPHIC_WIDTH);
height = attr.get(Keys.GRAPHIC_HEIGHT); height = attr.get(Keys.GRAPHIC_HEIGHT);
bankSize = width * height; bankSize = width * height;
memory = new DataField(bankSize * 2, 8); memory = new DataField(bankSize * 2);
dataOut = new ObservableValue("D", 16, true) dataOut = new ObservableValue("D", 16, true)
.setDescription(Lang.get("elem_RAMSinglePort_pin_d")) .setDescription(Lang.get("elem_RAMSinglePort_pin_d"))

View File

@ -10,7 +10,7 @@ import java.io.StringReader;
public class DataFieldTest extends TestCase { public class DataFieldTest extends TestCase {
public void testGetMinimized() throws Exception { public void testGetMinimized() throws Exception {
DataField data = new DataField(100, 8); DataField data = new DataField(100);
data.setData(9, 1); data.setData(9, 1);
data = data.getMinimized(); data = data.getMinimized();
assertEquals(1, data.getDataWord(9)); assertEquals(1, data.getDataWord(9));
@ -19,7 +19,7 @@ public class DataFieldTest extends TestCase {
} }
public void testGrow() throws Exception { public void testGrow() throws Exception {
DataField data = new DataField(100, 8); DataField data = new DataField(100);
data.setData(9, 1); data.setData(9, 1);
data = data.getMinimized(); data = data.getMinimized();
assertEquals(1, data.getDataWord(9)); assertEquals(1, data.getDataWord(9));

View File

@ -20,7 +20,7 @@ public class LUTTest extends TestCase {
ObservableValue c = new ObservableValue("c", 1); ObservableValue c = new ObservableValue("c", 1);
Model model = new Model(); Model model = new Model();
DataField data = new DataField(8, 8); DataField data = new DataField(8);
data.setData(3, 1); data.setData(3, 1);
data.setData(7, 1); data.setData(7, 1);
LookUpTable out = model.add(new LookUpTable( LookUpTable out = model.add(new LookUpTable(

View File

@ -19,7 +19,7 @@ public class ROMTest extends TestCase {
ObservableValue sel = new ObservableValue("sel", 1); ObservableValue sel = new ObservableValue("sel", 1);
Model model = new Model(); Model model = new Model();
DataField data = new DataField(8, 8); DataField data = new DataField(8);
data.setData(3, 17); data.setData(3, 17);
data.setData(7, 200); data.setData(7, 200);
ROM out = model.add(new ROM( ROM out = model.add(new ROM(