From 59e4f0d9447e3c764c83e7edabfcbf5c3c24a97b Mon Sep 17 00:00:00 2001 From: Daniel Kirschten Date: Thu, 26 Sep 2019 18:16:11 +0200 Subject: [PATCH] Made MemoryView to an Editor --- .../model/am2900/machine/Am2900Machine.java | 8 +- .../src/net/mograsim/machine/Machine.java | 6 +- .../standard/memory/AssignableMainMemory.java | 105 ++++++++ plugins/net.mograsim.plugin.core/plugin.xml | 17 ++ .../mograsim/plugin/editors/MemoryEditor.java | 242 ++++++++++++++++++ .../plugin/tables/memory/MemoryView.java | 181 ------------- 6 files changed, 371 insertions(+), 188 deletions(-) create mode 100644 plugins/net.mograsim.machine/src/net/mograsim/machine/standard/memory/AssignableMainMemory.java create mode 100644 plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/MemoryEditor.java delete mode 100644 plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java diff --git a/plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java b/plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java index f0bbb229..ac1b2373 100644 --- a/plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java +++ b/plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java @@ -12,7 +12,6 @@ import net.mograsim.logic.model.modeladapter.LogicCoreAdapter; import net.mograsim.logic.model.serializing.IndirectModelComponentCreator; import net.mograsim.machine.Machine; import net.mograsim.machine.MachineDefinition; -import net.mograsim.machine.MainMemory; import net.mograsim.machine.Register; import net.mograsim.machine.mi.AssignableMicroInstructionMemory; import net.mograsim.machine.mi.MicroInstruction; @@ -20,6 +19,7 @@ import net.mograsim.machine.mi.MicroInstructionDefinition; import net.mograsim.machine.mi.StandardMicroInstructionMemory; import net.mograsim.machine.mi.parameters.MicroInstructionParameter; import net.mograsim.machine.mi.parameters.ParameterClassification; +import net.mograsim.machine.standard.memory.AssignableMainMemory; import net.mograsim.machine.standard.memory.WordAddressableMemory; public class Am2900Machine implements Machine @@ -28,7 +28,7 @@ public class Am2900Machine implements Machine private LogicModelModifiable logicModel; private ModelComponent am2900; private Timeline timeline; - private MainMemory mainMemory; + private AssignableMainMemory mainMemory; private AssignableMicroInstructionMemory instMemory; private CoreClock clock; @@ -41,7 +41,7 @@ public class Am2900Machine implements Machine CoreModelParameters params = new CoreModelParameters(); params.gateProcessTime = 50; params.wireTravelTime = 10; - mainMemory = new WordAddressableMemory(am2900MachineDefinition.getMainMemoryDefinition()); + mainMemory = new AssignableMainMemory(new WordAddressableMemory(am2900MachineDefinition.getMainMemoryDefinition())); instMemory = new AssignableMicroInstructionMemory( new StandardMicroInstructionMemory(am2900MachineDefinition.getMicroInstructionMemoryDefinition())); timeline = LogicCoreAdapter.convert(logicModel, params); @@ -105,7 +105,7 @@ public class Am2900Machine implements Machine } @Override - public MainMemory getMainMemory() + public AssignableMainMemory getMainMemory() { return mainMemory; } diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/Machine.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/Machine.java index f9d851dc..df99984a 100644 --- a/plugins/net.mograsim.machine/src/net/mograsim/machine/Machine.java +++ b/plugins/net.mograsim.machine/src/net/mograsim/machine/Machine.java @@ -5,6 +5,7 @@ import net.mograsim.logic.core.timeline.Timeline; import net.mograsim.logic.core.types.BitVector; import net.mograsim.logic.model.model.LogicModel; import net.mograsim.machine.mi.AssignableMicroInstructionMemory; +import net.mograsim.machine.standard.memory.AssignableMainMemory; public interface Machine { @@ -22,8 +23,7 @@ public interface Machine Timeline getTimeline(); - MainMemory getMainMemory(); + AssignableMainMemory getMainMemory(); AssignableMicroInstructionMemory getMicroInstructionMemory(); - -} +} \ No newline at end of file diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/standard/memory/AssignableMainMemory.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/standard/memory/AssignableMainMemory.java new file mode 100644 index 00000000..38b17abc --- /dev/null +++ b/plugins/net.mograsim.machine/src/net/mograsim/machine/standard/memory/AssignableMainMemory.java @@ -0,0 +1,105 @@ +package net.mograsim.machine.standard.memory; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.Set; + +import net.mograsim.logic.core.types.BitVector; +import net.mograsim.machine.MainMemory; +import net.mograsim.machine.MainMemoryDefinition; +import net.mograsim.machine.Memory.MemoryCellModifiedListener; + +public class AssignableMainMemory implements MainMemory, MemoryCellModifiedListener +{ + private Set observers = new HashSet<>(); + private Set reassignmentListeners = new HashSet<>(); + private MainMemory real = null; + + public AssignableMainMemory(MainMemory mainMemory) + { + real = mainMemory; + real.registerCellModifiedListener(this); + } + + public void bind(MainMemory real) + { + this.real.deregisterCellModifiedListener(this); + this.real = real; + real.registerCellModifiedListener(this); + notifyMemoryChanged(-1); + notifyMemoryReassigned(real); + } + + @Override + public BitVector getCell(long address) + { + return real.getCell(address); + } + + @Override + public BigInteger getCellAsBigInteger(long address) + { + return real.getCellAsBigInteger(address); + } + + @Override + public void setCell(long address, BitVector data) + { + real.setCell(address, data); + } + + @Override + public void setCellAsBigInteger(long address, BigInteger word) + { + real.setCellAsBigInteger(address, word); + } + + @Override + public void registerCellModifiedListener(MemoryCellModifiedListener ob) + { + observers.add(ob); + } + + @Override + public void deregisterCellModifiedListener(MemoryCellModifiedListener ob) + { + observers.remove(ob); + } + + private void notifyMemoryChanged(long address) + { + observers.forEach(o -> o.update(address)); + } + + @Override + public MainMemoryDefinition getDefinition() + { + return real.getDefinition(); + } + + @Override + public void update(long address) + { + notifyMemoryChanged(address); + } + + public void registerMemoryReassignedListener(MainMemoryReassignedListener listener) + { + reassignmentListeners.add(listener); + } + + public void deregisterMemoryReassignedListener(MainMemoryReassignedListener listener) + { + reassignmentListeners.remove(listener); + } + + private void notifyMemoryReassigned(MainMemory newAssignee) + { + reassignmentListeners.forEach(l -> l.reassigned(newAssignee)); + } + + public static interface MainMemoryReassignedListener + { + public void reassigned(MainMemory newAssignee); + } +} diff --git a/plugins/net.mograsim.plugin.core/plugin.xml b/plugins/net.mograsim.plugin.core/plugin.xml index 965c2607..79cd428f 100644 --- a/plugins/net.mograsim.plugin.core/plugin.xml +++ b/plugins/net.mograsim.plugin.core/plugin.xml @@ -41,6 +41,14 @@ name="Registers / Latches state" priority="high"> + + @@ -94,6 +102,15 @@ name="Simulation View Editor"> + + + + diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/MemoryEditor.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/MemoryEditor.java new file mode 100644 index 00000000..2b028522 --- /dev/null +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/MemoryEditor.java @@ -0,0 +1,242 @@ +package net.mograsim.plugin.editors; + +import java.io.ByteArrayInputStream; +import java.math.BigInteger; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +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.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.EditorPart; + +import net.mograsim.machine.MainMemory; +import net.mograsim.machine.mi.MicroInstructionMemoryParseException; +import net.mograsim.machine.standard.memory.WordAddressableMemory; +import net.mograsim.plugin.asm.AsmNumberUtil; +import net.mograsim.plugin.nature.MachineContext; +import net.mograsim.plugin.nature.ProjectMachineContext; +import net.mograsim.plugin.tables.AddressLabelProvider; +import net.mograsim.plugin.tables.DisplaySettings; +import net.mograsim.plugin.tables.LazyTableViewer; +import net.mograsim.plugin.tables.NumberColumnLabelProvider; +import net.mograsim.plugin.tables.RadixSelector; +import net.mograsim.plugin.tables.memory.MemoryCellEditingSupport; +import net.mograsim.plugin.tables.memory.MemoryTableContentProvider; +import net.mograsim.plugin.tables.memory.MemoryTableRow; +import net.mograsim.plugin.tables.memory.NumberVerifyListener; + +public class MemoryEditor extends EditorPart +{ + private MachineContext context; + + private MainMemory memory; + + private LazyTableViewer viewer; + private MemoryTableContentProvider provider; + private DisplaySettings displaySettings; + + @Override + public void createPartControl(Composite parent) + { + provider = new MemoryTableContentProvider(); + displaySettings = new DisplaySettings(); + + parent.setLayout(new GridLayout(7, false)); + + createHeader(parent); + createViewer(parent); + + displaySettings.addObserver(() -> viewer.refresh()); + } + + @SuppressWarnings("unused") // RadixSelector and exceptions + private void createHeader(Composite parent) + { + Label fromLabel = new Label(parent, SWT.NONE); + fromLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + fromLabel.setText("Address: "); + + Text fromText = new Text(parent, SWT.BORDER); + fromText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + NumberVerifyListener vl = new NumberVerifyListener(); + fromText.addVerifyListener(vl); + fromText.setText("0"); + fromText.addModifyListener(e -> + { + try + { + provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue()); + viewer.refresh(); + } + catch (NumberFormatException x) + { + // Nothing to do here + } + }); + Label amountLabel = new Label(parent, SWT.NONE); + amountLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + amountLabel.setText("Number of cells: "); + Text amountText = new Text(parent, SWT.BORDER); + amountText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + amountText.addVerifyListener(vl); + amountText.setText("0"); + amountText.addModifyListener(e -> + { + try + { + provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue()); + viewer.refresh(); + } + catch (NumberFormatException x) + { + // Nothing to do here + } + }); + new RadixSelector(parent, displaySettings); + + addActivationButton(parent); + } + + private void addActivationButton(Composite parent) + { + Button activationButton = new Button(parent, SWT.PUSH); + activationButton.setText("Set Active"); + activationButton.addListener(SWT.Selection, e -> context.getActiveMachine().ifPresent(m -> m.getMainMemory().bind(memory))); + } + + private void createViewer(Composite parent) + { + viewer = new LazyTableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL); + createColumns(); + Table table = viewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + viewer.setUseHashlookup(true); + viewer.setContentProvider(provider); + getSite().setSelectionProvider(viewer);// TODO what does this? + viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 7, 1)); + if (memory != null) + viewer.setInput(memory); + } + + private void createColumns() + { + TableViewerColumn addrCol = createTableViewerColumn("Address", 100); + addrCol.setLabelProvider(new AddressLabelProvider()); + + TableViewerColumn dataCol = createTableViewerColumn("Data", 100); + dataCol.setLabelProvider(new NumberColumnLabelProvider(displaySettings) + { + @Override + public BigInteger getAsBigInteger(Object element) + { + MemoryTableRow row = (MemoryTableRow) element; + return row.getMemory().getCellAsBigInteger(row.address); + } + + @Override + public int getBitLength(Object element) + { + return ((MemoryTableRow) element).getMemory().getDefinition().getCellWidth(); + } + }); + dataCol.setEditingSupport(new MemoryCellEditingSupport(viewer, displaySettings)); + } + + private TableViewerColumn createTableViewerColumn(String title, int width) + { + TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE); + TableColumn column = viewerColumn.getColumn(); + column.setText(title); + column.setWidth(width); + column.setResizable(true); + column.setMoveable(false); + return viewerColumn; + } + + @Override + public void init(IEditorSite site, IEditorInput input) throws PartInitException + { + if (input instanceof IFileEditorInput) + { + IFileEditorInput fileInput = (IFileEditorInput) input; + context = ProjectMachineContext.getMachineContextOf(fileInput.getFile().getProject()); + context.activateMachine(); + + setPartName(fileInput.getName()); + open(fileInput.getFile()); + } else + throw new IllegalArgumentException("MemoryEditor can only be used with Files"); + + setSite(site); + setInput(input); + } + + @Override + public void doSave(IProgressMonitor monitor) + { + IEditorInput input = getEditorInput(); + if (input instanceof IFileEditorInput) + SafeRunnable.getRunner().run(() -> save(((IFileEditorInput) input).getFile(), monitor)); + } + + private void save(IFile file, IProgressMonitor monitor) throws CoreException + { + file.setContents(new ByteArrayInputStream("actual contents will go here".getBytes()), 0, monitor); + } + + private void open(IFile file) + { + // TODO actually parse the file + memory = new WordAddressableMemory(context.getMachineDefinition() + .orElseThrow(() -> new MicroInstructionMemoryParseException("No MachineDefinition assigned!")).getMainMemoryDefinition()); + if (viewer != null) + viewer.setInput(memory); + } + + @Override + public void doSaveAs() + { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isDirty() + { + // TODO + return false; + } + + @Override + public boolean isSaveAsAllowed() + { + return false; + } + + @Override + public void setFocus() + { + viewer.getTable().setFocus(); + } + + @Override + public void dispose() + { + // TODO Auto-generated method stub + super.dispose(); + } +} \ No newline at end of file diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java deleted file mode 100644 index e490bd0c..00000000 --- a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java +++ /dev/null @@ -1,181 +0,0 @@ -package net.mograsim.plugin.tables.memory; - -import java.math.BigInteger; -import java.util.Optional; - -import org.eclipse.jface.viewers.TableViewerColumn; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -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.Machine; -import net.mograsim.machine.MainMemory; -import net.mograsim.machine.MainMemoryDefinition; -import net.mograsim.machine.standard.memory.WordAddressableMemory; -import net.mograsim.plugin.MachineContext; -import net.mograsim.plugin.MachineContext.ContextObserver; -import net.mograsim.plugin.asm.AsmNumberUtil; -import net.mograsim.plugin.tables.AddressLabelProvider; -import net.mograsim.plugin.tables.DisplaySettings; -import net.mograsim.plugin.tables.LazyTableViewer; -import net.mograsim.plugin.tables.NumberColumnLabelProvider; -import net.mograsim.plugin.tables.RadixSelector; - -public class MemoryView extends ViewPart implements ContextObserver -{ - private LazyTableViewer viewer; - private MemoryTableContentProvider provider; - private DisplaySettings displaySettings; - - @Override - public void createPartControl(Composite parent) - { - provider = new MemoryTableContentProvider(); - displaySettings = new DisplaySettings(); - - GridLayout layout = new GridLayout(6, false); - parent.setLayout(layout); - - createHeader(parent); - createViewer(parent); - - displaySettings.addObserver(() -> viewer.refresh()); - - setupContextBinding(); - } - - @SuppressWarnings("unused") - private void createHeader(Composite parent) - { - 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 (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 (NumberFormatException ex) - { - // Nothing to do here - } - }); - new RadixSelector(parent, displaySettings); - } - - private void createViewer(Composite parent) - { - viewer = new LazyTableViewer(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); - bindMainMemory(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 AddressLabelProvider()); - - 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); - } - - @Override - public int getBitLength(Object element) - { - return ((MemoryTableRow) element).getMemory().getDefinition().getCellWidth(); - } - - }); - 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(); - } - - private void bindMainMemory(MainMemory m) - { - viewer.setInput(m); - } - - private void setupContextBinding() - { - MachineContext.getInstance().registerObserver(this); - setMachine(Optional.ofNullable(MachineContext.getInstance().getMachine())); - } - - @Override - public void setMachine(Optional machine) - { - if (machine.isPresent()) - bindMainMemory(machine.get().getMainMemory()); - } -} -- 2.17.1