Refactored MemoryView for extensibility
authorFabian Stemmler <stemmler@in.tum.de>
Sat, 31 Aug 2019 14:51:33 +0000 (16:51 +0200)
committerFabian Stemmler <stemmler@in.tum.de>
Sat, 31 Aug 2019 14:51:33 +0000 (16:51 +0200)
15 files changed:
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryCellEditingSupport.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableContentProvider.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableRow.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryView.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberCellEditorValidator.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberVerifyListener.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditingSupport.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditorValidator.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberColumnLabelProvider.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/DisplaySettings.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryCellEditingSupport.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableContentProvider.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableRow.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/NumberVerifyListener.java [new file with mode: 0644]

diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryCellEditingSupport.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryCellEditingSupport.java
deleted file mode 100644 (file)
index 10498f6..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import java.math.BigInteger;
-
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.jface.viewers.EditingSupport;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TextCellEditor;
-
-import net.mograsim.plugin.asm.AsmNumberUtil;
-import net.mograsim.plugin.memory.MemoryView.DisplaySettings;
-
-public class MemoryCellEditingSupport extends EditingSupport
-{
-       private final TableViewer viewer;
-       private final CellEditor editor;
-       private final DisplaySettings displaySettings;
-
-       public MemoryCellEditingSupport(TableViewer viewer, DisplaySettings displaySettings)
-       {
-               super(viewer);
-               this.viewer = viewer;
-               this.displaySettings = displaySettings;
-               editor = new TextCellEditor(viewer.getTable());
-               editor.setValidator(new NumberCellEditorValidator());
-       }
-
-       @Override
-       protected boolean canEdit(Object element)
-       {
-               return true;
-       }
-
-       @Override
-       protected CellEditor getCellEditor(Object element)
-       {
-               return editor;
-       }
-
-       @Override
-       protected Object getValue(Object element)
-       {
-               MemoryTableRow row = (MemoryTableRow) element;
-               return AsmNumberUtil.toString(row.getMemory().getCellAsBigInteger(row.address), displaySettings.getDataNumberType());
-       }
-
-       @Override
-       protected void setValue(Object element, Object userInput)
-       {
-               MemoryTableRow row = (MemoryTableRow) element;
-               try
-               {
-                       row.getMemory().setCellAsBigInteger(row.address, AsmNumberUtil.valueOf((String) userInput));
-               }
-               catch (@SuppressWarnings("unused") NumberFormatException e)
-               {
-                       row.getMemory().setCellAsBigInteger(row.address, BigInteger.valueOf(0));
-               }
-               viewer.update(element, null);
-       }
-}
\ No newline at end of file
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableContentProvider.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableContentProvider.java
deleted file mode 100644 (file)
index 9f2a9e1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import org.eclipse.jface.viewers.ILazyContentProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.widgets.Display;
-
-import net.mograsim.machine.MainMemory;
-import net.mograsim.machine.MemoryObserver;
-
-public class MemoryTableContentProvider implements ILazyContentProvider, MemoryObserver
-{
-       private long lower;
-       private TableViewer viewer;
-       private final static int limit = 10_000;
-       private int amount = 0;
-       private MainMemory memory;
-
-       public void setLowerBound(long lower)
-       {
-               if (memory != null)
-                       this.lower = Long.min(memory.getDefinition().getMaximalAddress(), Long.max(memory.getDefinition().getMinimalAddress(), lower));
-               else
-                       this.lower = lower;
-               updateItemCount();
-       }
-
-       public void updateItemCount()
-       {
-               if (memory != null)
-               {
-                       long size = memory.getDefinition().getMaximalAddress() - lower;
-                       viewer.setItemCount(size > amount ? amount : (int) size);
-               } else
-                       viewer.setItemCount(0);
-       }
-
-       public long getLowerBound()
-       {
-               return lower;
-       }
-
-       public void setAmount(int amount)
-       {
-               this.amount = Integer.min(amount, limit);
-               updateItemCount();
-       }
-
-       public int getAmount()
-       {
-               return amount;
-       }
-
-       @Override
-       public void updateElement(int index)
-       {
-               long address = lower + index;
-               if (address <= memory.getDefinition().getMaximalAddress())
-                       viewer.replace(new MemoryTableRow(address, memory), index);
-       }
-
-       @Override
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
-       {
-               this.viewer = (TableViewer) viewer;
-               this.memory = (MainMemory) newInput;
-               if (oldInput != null)
-                       ((MainMemory) oldInput).deregisterObserver(this);
-               if (memory != null)
-                       memory.registerObserver(this);
-               setLowerBound(0L);
-       }
-
-       @Override
-       public void update(long address)
-       {
-               Display.getDefault().asyncExec(() -> updateElement((int) (address - lower)));
-       }
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableRow.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableRow.java
deleted file mode 100644 (file)
index fa5b626..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import net.mograsim.machine.MainMemory;
-
-public class MemoryTableRow
-{
-       public final long address;
-       private final MainMemory memory;
-
-       public MemoryTableRow(long address, MainMemory memory)
-       {
-               this.address = address;
-               this.memory = memory;
-       }
-
-       public MainMemory getMemory()
-       {
-               return memory;
-       }
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryView.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryView.java
deleted file mode 100644 (file)
index 5254745..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.part.ViewPart;
-
-import net.mograsim.machine.DefaultMainMemoryDefinition;
-import net.mograsim.machine.MainMemory;
-import net.mograsim.machine.standard.memory.WordAddressableMemory;
-import net.mograsim.plugin.asm.AsmNumberUtil;
-import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
-
-public class MemoryView extends ViewPart
-{
-       private TableViewer viewer;
-       private MemoryTableContentProvider provider;
-       private DisplaySettings displaySettings;
-       private String addressFormat;
-
-       @Override
-       public void createPartControl(Composite parent)
-       {
-               provider = new MemoryTableContentProvider();
-               displaySettings = new DisplaySettings();
-               displaySettings.setDataNumberType(NumberType.HEXADECIMAL);
-
-               GridLayout layout = new GridLayout(6, false);
-               parent.setLayout(layout);
-               Label fromLabel = new Label(parent, SWT.NONE);
-               fromLabel.setText("Address: ");
-               Text fromText = new Text(parent, SWT.BORDER | SWT.SEARCH);
-               fromText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
-               VerifyListener vl = new NumberVerifyListener();
-               fromText.addVerifyListener(vl);
-               fromText.setText("0");
-               fromText.addModifyListener(e ->
-               {
-                       try
-                       {
-                               provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue());
-                               viewer.refresh();
-                       }
-                       catch (@SuppressWarnings("unused") NumberFormatException ex)
-                       {
-                               // Nothing to do here
-                       }
-               });
-
-               Label amountLabel = new Label(parent, SWT.NONE);
-               amountLabel.setText("Number of cells: ");
-               Text amountText = new Text(parent, SWT.BORDER | SWT.SEARCH);
-               amountText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
-               amountText.addVerifyListener(vl);
-               amountText.setText("0");
-               amountText.addModifyListener(e ->
-               {
-                       try
-                       {
-                               provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue());
-                               viewer.refresh();
-                       }
-                       catch (@SuppressWarnings("unused") NumberFormatException ex)
-                       {
-                               // Nothing to do here
-                       }
-               });
-
-               setupRadixSelector(parent);
-
-               createViewer(parent);
-       }
-
-       private void setupRadixSelector(Composite parent)
-       {
-               Label radixLabel = new Label(parent, SWT.NONE);
-               radixLabel.setText("Radix: ");
-               Combo selectRadix = new Combo(parent, SWT.READ_ONLY);
-
-               String entries[] = new String[] { "Binary", "Octal", "Decimal", "Hexadecimal" };
-               NumberType corTypes[] = new NumberType[] { NumberType.BINARY, NumberType.OCTAL, NumberType.DECIMAL, NumberType.HEXADECIMAL };
-               selectRadix.setItems(entries);
-               selectRadix.addSelectionListener(new SelectionListener()
-               {
-                       @Override
-                       public void widgetSelected(SelectionEvent e)
-                       {
-                               int index = selectRadix.getSelectionIndex();
-                               if (index == -1)
-                                       displaySettings.setDataNumberType(NumberType.HEXADECIMAL);
-                               else
-                               {
-                                       displaySettings.setDataNumberType(corTypes[index]);
-                               }
-                               viewer.refresh();
-                       }
-
-                       @Override
-                       public void widgetDefaultSelected(SelectionEvent e)
-                       {
-                               widgetSelected(e);
-                       }
-               });
-       }
-
-       private void createViewer(Composite parent)
-       {
-               viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
-               createColumns();
-               Table table = viewer.getTable();
-               table.setHeaderVisible(true);
-               table.setLinesVisible(true);
-               viewer.setUseHashlookup(true);
-               viewer.setContentProvider(provider);
-               setMemoryBinding(new WordAddressableMemory(new DefaultMainMemoryDefinition(8, 8, 8L, Long.MAX_VALUE)));
-               getSite().setSelectionProvider(viewer);
-
-               GridData gd = new GridData();
-               gd.verticalAlignment = GridData.FILL;
-               gd.horizontalSpan = 6;
-               gd.grabExcessHorizontalSpace = true;
-               gd.grabExcessVerticalSpace = true;
-               gd.horizontalAlignment = GridData.FILL;
-               viewer.getControl().setLayoutData(gd);
-       }
-
-       private void createColumns()
-       {
-               String[] titles = { "Address", "Data" };
-               int[] bounds = { 100, 100 };
-
-               TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0]);
-               col.setLabelProvider(new ColumnLabelProvider()
-               {
-                       @Override
-                       public String getText(Object element)
-                       {
-                               MemoryTableRow row = (MemoryTableRow) element;
-                               return String.format(addressFormat, row.address);// TODO: make the string length dependent on memory address length
-                       }
-               });
-
-               col = createTableViewerColumn(titles[1], bounds[1]);
-               col.setLabelProvider(new ColumnLabelProvider()
-               {
-                       @Override
-                       public String getText(Object element)
-                       {
-                               MemoryTableRow row = (MemoryTableRow) element;
-                               return AsmNumberUtil.toString(row.getMemory().getCellAsBigInteger(row.address), displaySettings.getDataNumberType());
-                       }
-               });
-               col.setEditingSupport(new MemoryCellEditingSupport(viewer, displaySettings));
-       }
-
-       private TableViewerColumn createTableViewerColumn(String title, int bound)
-       {
-               TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
-               TableColumn column = viewerColumn.getColumn();
-               column.setText(title);
-               column.setWidth(bound);
-               column.setResizable(true);
-               column.setMoveable(false);
-               return viewerColumn;
-       }
-
-       @Override
-       public void setFocus()
-       {
-               viewer.getControl().setFocus();
-       }
-
-       public void setMemoryBinding(MainMemory m)
-       {
-               int hexAddressLength = Long.toUnsignedString(m.getDefinition().getMaximalAddress(), 16).length();
-               addressFormat = "0x%0" + hexAddressLength + "X";
-               viewer.setInput(m);
-       }
-
-       public static class DisplaySettings
-       {
-               private AsmNumberUtil.NumberType dataNumberType;
-
-               public AsmNumberUtil.NumberType getDataNumberType()
-               {
-                       return dataNumberType;
-               }
-
-               public void setDataNumberType(AsmNumberUtil.NumberType dataNumberType)
-               {
-                       this.dataNumberType = dataNumberType;
-               }
-       }
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberCellEditorValidator.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberCellEditorValidator.java
deleted file mode 100644 (file)
index 236eaa0..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import org.eclipse.jface.viewers.ICellEditorValidator;
-
-import net.mograsim.plugin.asm.AsmNumberUtil;
-
-public class NumberCellEditorValidator implements ICellEditorValidator
-{
-
-       @Override
-       public String isValid(Object value)
-       {
-               return AsmNumberUtil.NumberType.NONE.equals(AsmNumberUtil.getType((String) value)) ? (String) value + "is not a valid number"
-                               : null;
-       }
-
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberVerifyListener.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberVerifyListener.java
deleted file mode 100644 (file)
index 4e5d11c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.widgets.Text;
-
-import net.mograsim.plugin.asm.AsmNumberUtil;
-import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
-
-public class NumberVerifyListener implements VerifyListener
-{
-
-       @Override
-       public void verifyText(VerifyEvent e)
-       {
-               String text = computeModifiedText(e);
-               e.doit = !NumberType.NONE.equals(AsmNumberUtil.prefixOfType(text));
-       }
-
-       private static String computeModifiedText(VerifyEvent e)
-       {
-               String modifiedText = ((Text) e.getSource()).getText();
-               modifiedText = modifiedText.substring(0, e.start).concat(e.text).concat(modifiedText.substring(e.end));
-               return modifiedText;
-       }
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditingSupport.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditingSupport.java
new file mode 100644 (file)
index 0000000..7bba426
--- /dev/null
@@ -0,0 +1,63 @@
+package net.mograsim.plugin.tables;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+
+import net.mograsim.plugin.asm.AsmNumberUtil;
+import net.mograsim.plugin.tables.memory.DisplaySettings;
+
+public abstract class NumberCellEditingSupport extends EditingSupport
+{
+       private final TableViewer viewer;
+       private final CellEditor editor;
+       private final DisplaySettings displaySettings;
+
+       public NumberCellEditingSupport(TableViewer viewer, DisplaySettings displaySettings)
+       {
+               super(viewer);
+               this.viewer = viewer;
+               this.displaySettings = displaySettings;
+               editor = new TextCellEditor(viewer.getTable());
+               editor.setValidator(new NumberCellEditorValidator());
+       }
+
+       @Override
+       final protected boolean canEdit(Object element)
+       {
+               return true;
+       }
+
+       @Override
+       final protected CellEditor getCellEditor(Object element)
+       {
+               return editor;
+       }
+
+       @Override
+       final protected Object getValue(Object element)
+       {
+               return AsmNumberUtil.toString(getAsBigInteger(element), displaySettings.getDataNumberType());
+       }
+
+       @Override
+       final protected void setValue(Object element, Object userInput)
+       {
+               try
+               {
+                       setAsBigInteger(element, AsmNumberUtil.valueOf((String) userInput));
+               }
+               catch (@SuppressWarnings("unused") NumberFormatException e)
+               {
+                       setAsBigInteger(element, BigInteger.valueOf(0));
+               }
+               viewer.update(element, null);
+       }
+
+       protected abstract void setAsBigInteger(Object element, BigInteger value);
+
+       protected abstract BigInteger getAsBigInteger(Object element);
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditorValidator.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditorValidator.java
new file mode 100644 (file)
index 0000000..e0b445d
--- /dev/null
@@ -0,0 +1,17 @@
+package net.mograsim.plugin.tables;
+
+import org.eclipse.jface.viewers.ICellEditorValidator;
+
+import net.mograsim.plugin.asm.AsmNumberUtil;
+
+public class NumberCellEditorValidator implements ICellEditorValidator
+{
+
+       @Override
+       public String isValid(Object value)
+       {
+               return AsmNumberUtil.NumberType.NONE.equals(AsmNumberUtil.getType((String) value)) ? (String) value + "is not a valid number"
+                               : null;
+       }
+
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberColumnLabelProvider.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberColumnLabelProvider.java
new file mode 100644 (file)
index 0000000..35f032a
--- /dev/null
@@ -0,0 +1,26 @@
+package net.mograsim.plugin.tables;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+
+import net.mograsim.plugin.asm.AsmNumberUtil;
+import net.mograsim.plugin.tables.memory.DisplaySettings;
+
+public abstract class NumberColumnLabelProvider extends ColumnLabelProvider
+{
+       private DisplaySettings displaySettings;
+
+       public NumberColumnLabelProvider(DisplaySettings displaySettings)
+       {
+               this.displaySettings = displaySettings;
+       }
+
+       @Override
+       public String getText(Object element)
+       {
+               return AsmNumberUtil.toString(getAsBigInteger(element), displaySettings.getDataNumberType());
+       }
+
+       public abstract BigInteger getAsBigInteger(Object element);
+}
\ No newline at end of file
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/DisplaySettings.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/DisplaySettings.java
new file mode 100644 (file)
index 0000000..8816a52
--- /dev/null
@@ -0,0 +1,23 @@
+package net.mograsim.plugin.tables.memory;
+
+import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
+
+public class DisplaySettings
+{
+       private NumberType dataNumberType;
+
+       public DisplaySettings(NumberType dataNumberType)
+       {
+               this.dataNumberType = dataNumberType;
+       }
+
+       public NumberType getDataNumberType()
+       {
+               return dataNumberType;
+       }
+
+       public void setDataNumberType(NumberType dataNumberType)
+       {
+               this.dataNumberType = dataNumberType;
+       }
+}
\ No newline at end of file
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryCellEditingSupport.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryCellEditingSupport.java
new file mode 100644 (file)
index 0000000..94f1821
--- /dev/null
@@ -0,0 +1,29 @@
+package net.mograsim.plugin.tables.memory;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.viewers.TableViewer;
+
+import net.mograsim.plugin.tables.NumberCellEditingSupport;
+
+public class MemoryCellEditingSupport extends NumberCellEditingSupport
+{
+       public MemoryCellEditingSupport(TableViewer viewer, DisplaySettings displaySettings)
+       {
+               super(viewer, displaySettings);
+       }
+
+       @Override
+       protected void setAsBigInteger(Object element, BigInteger value)
+       {
+               MemoryTableRow row = (MemoryTableRow) element;
+               row.getMemory().setCellAsBigInteger(row.address, value);
+       }
+
+       @Override
+       protected BigInteger getAsBigInteger(Object element)
+       {
+               MemoryTableRow row = (MemoryTableRow) element;
+               return row.getMemory().getCellAsBigInteger(row.address);
+       }
+}
\ No newline at end of file
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableContentProvider.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableContentProvider.java
new file mode 100644 (file)
index 0000000..aaecc75
--- /dev/null
@@ -0,0 +1,79 @@
+package net.mograsim.plugin.tables.memory;
+
+import org.eclipse.jface.viewers.ILazyContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Display;
+
+import net.mograsim.machine.MainMemory;
+import net.mograsim.machine.MemoryObserver;
+
+public class MemoryTableContentProvider implements ILazyContentProvider, MemoryObserver
+{
+       private long lower;
+       private TableViewer viewer;
+       private final static int limit = 10_000;
+       private int amount = 0;
+       private MainMemory memory;
+
+       public void setLowerBound(long lower)
+       {
+               if (memory != null)
+                       this.lower = Long.min(memory.getDefinition().getMaximalAddress(), Long.max(memory.getDefinition().getMinimalAddress(), lower));
+               else
+                       this.lower = lower;
+               updateItemCount();
+       }
+
+       public void updateItemCount()
+       {
+               if (memory != null)
+               {
+                       long size = memory.getDefinition().getMaximalAddress() - lower;
+                       viewer.setItemCount(size > amount ? amount : (int) size);
+               } else
+                       viewer.setItemCount(0);
+       }
+
+       public long getLowerBound()
+       {
+               return lower;
+       }
+
+       public void setAmount(int amount)
+       {
+               this.amount = Integer.min(amount, limit);
+               updateItemCount();
+       }
+
+       public int getAmount()
+       {
+               return amount;
+       }
+
+       @Override
+       public void updateElement(int index)
+       {
+               long address = lower + index;
+               if (address <= memory.getDefinition().getMaximalAddress())
+                       viewer.replace(new MemoryTableRow(address, memory), index);
+       }
+
+       @Override
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
+       {
+               this.viewer = (TableViewer) viewer;
+               this.memory = (MainMemory) newInput;
+               if (oldInput != null)
+                       ((MainMemory) oldInput).deregisterObserver(this);
+               if (memory != null)
+                       memory.registerObserver(this);
+               setLowerBound(0L);
+       }
+
+       @Override
+       public void update(long address)
+       {
+               Display.getDefault().asyncExec(() -> updateElement((int) (address - lower)));
+       }
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableRow.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableRow.java
new file mode 100644 (file)
index 0000000..6f1c353
--- /dev/null
@@ -0,0 +1,20 @@
+package net.mograsim.plugin.tables.memory;
+
+import net.mograsim.machine.MainMemory;
+
+public class MemoryTableRow
+{
+       public final long address;
+       private final MainMemory memory;
+
+       public MemoryTableRow(long address, MainMemory memory)
+       {
+               this.address = address;
+               this.memory = memory;
+       }
+
+       public MainMemory getMemory()
+       {
+               return memory;
+       }
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java
new file mode 100644 (file)
index 0000000..98983a6
--- /dev/null
@@ -0,0 +1,194 @@
+package net.mograsim.plugin.tables.memory;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.part.ViewPart;
+
+import net.mograsim.machine.MainMemory;
+import net.mograsim.machine.MainMemoryDefinition;
+import net.mograsim.machine.standard.memory.WordAddressableMemory;
+import net.mograsim.plugin.asm.AsmNumberUtil;
+import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
+import net.mograsim.plugin.tables.NumberColumnLabelProvider;
+
+public class MemoryView extends ViewPart
+{
+       private TableViewer viewer;
+       private MemoryTableContentProvider provider;
+       private DisplaySettings displaySettings;
+       private String addressFormat;
+
+       @Override
+       public void createPartControl(Composite parent)
+       {
+               provider = new MemoryTableContentProvider();
+               displaySettings = new DisplaySettings(NumberType.HEXADECIMAL);
+
+               GridLayout layout = new GridLayout(6, false);
+               parent.setLayout(layout);
+               Label fromLabel = new Label(parent, SWT.NONE);
+               fromLabel.setText("Address: ");
+               Text fromText = new Text(parent, SWT.BORDER | SWT.SEARCH);
+               fromText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
+               VerifyListener vl = new NumberVerifyListener();
+               fromText.addVerifyListener(vl);
+               fromText.setText("0");
+               fromText.addModifyListener(e ->
+               {
+                       try
+                       {
+                               provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue());
+                               viewer.refresh();
+                       }
+                       catch (@SuppressWarnings("unused") NumberFormatException ex)
+                       {
+                               // Nothing to do here
+                       }
+               });
+
+               Label amountLabel = new Label(parent, SWT.NONE);
+               amountLabel.setText("Number of cells: ");
+               Text amountText = new Text(parent, SWT.BORDER | SWT.SEARCH);
+               amountText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
+               amountText.addVerifyListener(vl);
+               amountText.setText("0");
+               amountText.addModifyListener(e ->
+               {
+                       try
+                       {
+                               provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue());
+                               viewer.refresh();
+                       }
+                       catch (@SuppressWarnings("unused") NumberFormatException ex)
+                       {
+                               // Nothing to do here
+                       }
+               });
+
+               setupRadixSelector(parent);
+
+               createViewer(parent);
+       }
+
+       private void setupRadixSelector(Composite parent)
+       {
+               Label radixLabel = new Label(parent, SWT.NONE);
+               radixLabel.setText("Radix: ");
+               Combo selectRadix = new Combo(parent, SWT.READ_ONLY);
+
+               String entries[] = new String[] { "Binary", "Octal", "Decimal", "Hexadecimal" };
+               NumberType corTypes[] = new NumberType[] { NumberType.BINARY, NumberType.OCTAL, NumberType.DECIMAL, NumberType.HEXADECIMAL };
+               selectRadix.setItems(entries);
+               selectRadix.addSelectionListener(new SelectionListener()
+               {
+                       @Override
+                       public void widgetSelected(SelectionEvent e)
+                       {
+                               int index = selectRadix.getSelectionIndex();
+                               if (index == -1)
+                                       displaySettings.setDataNumberType(NumberType.HEXADECIMAL);
+                               else
+                               {
+                                       displaySettings.setDataNumberType(corTypes[index]);
+                               }
+                               viewer.refresh();
+                       }
+
+                       @Override
+                       public void widgetDefaultSelected(SelectionEvent e)
+                       {
+                               widgetSelected(e);
+                       }
+               });
+       }
+
+       private void createViewer(Composite parent)
+       {
+               viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
+               createColumns();
+               Table table = viewer.getTable();
+               table.setHeaderVisible(true);
+               table.setLinesVisible(true);
+               viewer.setUseHashlookup(true);
+               viewer.setContentProvider(provider);
+               setMemoryBinding(new WordAddressableMemory(MainMemoryDefinition.create(8, 8, 8L, Long.MAX_VALUE)));
+               getSite().setSelectionProvider(viewer);
+
+               GridData gd = new GridData();
+               gd.verticalAlignment = GridData.FILL;
+               gd.horizontalSpan = 6;
+               gd.grabExcessHorizontalSpace = true;
+               gd.grabExcessVerticalSpace = true;
+               gd.horizontalAlignment = GridData.FILL;
+               viewer.getControl().setLayoutData(gd);
+       }
+
+       private void createColumns()
+       {
+               String[] titles = { "Address", "Data" };
+               int[] bounds = { 100, 100 };
+
+               TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0]);
+               col.setLabelProvider(new ColumnLabelProvider()
+               {
+                       @Override
+                       public String getText(Object element)
+                       {
+                               MemoryTableRow row = (MemoryTableRow) element;
+                               return String.format(addressFormat, row.address);
+                       }
+               });
+
+               col = createTableViewerColumn(titles[1], bounds[1]);
+               col.setLabelProvider(new NumberColumnLabelProvider(displaySettings)
+               {
+                       @Override
+                       public BigInteger getAsBigInteger(Object element)
+                       {
+                               MemoryTableRow row = (MemoryTableRow) element;
+                               return row.getMemory().getCellAsBigInteger(row.address);
+                       }
+
+               });
+               col.setEditingSupport(new MemoryCellEditingSupport(viewer, displaySettings));
+       }
+
+       private TableViewerColumn createTableViewerColumn(String title, int bound)
+       {
+               TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
+               TableColumn column = viewerColumn.getColumn();
+               column.setText(title);
+               column.setWidth(bound);
+               column.setResizable(true);
+               column.setMoveable(false);
+               return viewerColumn;
+       }
+
+       @Override
+       public void setFocus()
+       {
+               viewer.getControl().setFocus();
+       }
+
+       public void setMemoryBinding(MainMemory m)
+       {
+               int hexAddressLength = Long.toUnsignedString(m.getDefinition().getMaximalAddress(), 16).length();
+               addressFormat = "0x%0" + hexAddressLength + "X";
+               viewer.setInput(m);
+       }
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/NumberVerifyListener.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/NumberVerifyListener.java
new file mode 100644 (file)
index 0000000..54d7176
--- /dev/null
@@ -0,0 +1,26 @@
+package net.mograsim.plugin.tables.memory;
+
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.widgets.Text;
+
+import net.mograsim.plugin.asm.AsmNumberUtil;
+import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
+
+public class NumberVerifyListener implements VerifyListener
+{
+
+       @Override
+       public void verifyText(VerifyEvent e)
+       {
+               String text = computeModifiedText(e);
+               e.doit = !NumberType.NONE.equals(AsmNumberUtil.prefixOfType(text));
+       }
+
+       private static String computeModifiedText(VerifyEvent e)
+       {
+               String modifiedText = ((Text) e.getSource()).getText();
+               modifiedText = modifiedText.substring(0, e.start).concat(e.text).concat(modifiedText.substring(e.end));
+               return modifiedText;
+       }
+}