"compName": "WireCrossPoint#43",
"pinName": ""
},
- "name": "unnamedWire#163",
+ "name": "wire_mpm_address",
"path": [
{
"x": 205.0,
package net.mograsim.logic.model.am2900.machine;
+import java.util.HashSet;
+import java.util.Set;
+
import net.mograsim.logic.core.components.CoreClock;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.types.BitVector;
private AssignableMainMemory mainMemory;
private AssignableMicroInstructionMemory instMemory;
private CoreClock clock;
+ private long activeInstructionAddress;
+
+ private final Set<ActiveMicroInstructionChangedListener> amicListeners;
public Am2900Machine(LogicModelModifiable model, Am2900MachineDefinition am2900MachineDefinition)
{
this.logicModel = model;
this.am2900 = IndirectModelComponentCreator.createComponent(logicModel,
"resloader:Am2900Loader:jsonres:net/mograsim/logic/model/am2900/components/Am2900.json", "Am2900");
+ this.amicListeners = new HashSet<>();
+
CoreModelParameters params = new CoreModelParameters();
params.gateProcessTime = 50;
params.wireTravelTime = 10;
am2900.setHighLevelState("ram.memory_binding", mainMemory);
am2900.setHighLevelState("mpm.memory_binding", instMemory);
clock = logicModel.getComponentBySubmodelPath("Am2900.Clock#0", ModelClock.class).getClock();
+ clock.registerObserver(c ->
+ {
+ if (clock.isOn())
+ {
+ long oldAddress = activeInstructionAddress;
+ activeInstructionAddress = getCurrentMicroInstructionAddress();
+ notifyActiveMicroInstructionChangedListeners(oldAddress, activeInstructionAddress);
+ }
+ });
}
@Override
{
return instMemory;
}
+
+ @Override
+ public long getActiveMicroInstructionAddress()
+ {
+ return activeInstructionAddress;
+ }
+
+ private long getCurrentMicroInstructionAddress()
+ {
+ // TODO: replace with highlevelstate
+ BitVector vector = logicModel.getWireBySubmodelPath("Am2900.wire_mpm_address").getWireValues();
+ return vector.isBinary() ? vector.getUnsignedValueLong() : -1;
+ }
+
+ @Override
+ public void addActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener)
+ {
+ amicListeners.add(listener);
+ }
+
+ @Override
+ public void removeActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener)
+ {
+ amicListeners.remove(listener);
+ }
+
+ private void notifyActiveMicroInstructionChangedListeners(long oldAddress, long newAddress)
+ {
+ amicListeners.forEach(l -> l.instructionChanged(oldAddress, newAddress));
+ }
}
\ No newline at end of file
AssignableMainMemory getMainMemory();
AssignableMicroInstructionMemory getMicroInstructionMemory();
+
+ void addActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener);
+
+ void removeActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener);
+
+ long getActiveMicroInstructionAddress();
+
+ public interface ActiveMicroInstructionChangedListener
+ {
+ public void instructionChanged(long oldAddress, long newAddress);
+ }
}
\ No newline at end of file
import java.util.Set;
import net.mograsim.machine.Memory.MemoryCellModifiedListener;
-import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener;
-public class AssignableMicroInstructionMemory
- implements MicroInstructionMemory, MemoryCellModifiedListener, ActiveMicroInstructionChangedListener
+public class AssignableMicroInstructionMemory implements MicroInstructionMemory, MemoryCellModifiedListener
{
private Set<MemoryCellModifiedListener> observers = new HashSet<>();
- private Set<ActiveMicroInstructionChangedListener> activeInstructionListeners = new HashSet<>();
+
private Set<MIMemoryReassignedListener> reassignmentListeners = new HashSet<>();
private MicroInstructionMemory real = null;
observers.remove(ob);
}
- @Override
- public void registerActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob)
- {
- activeInstructionListeners.add(ob);
- }
-
- @Override
- public void deregisterActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob)
- {
- activeInstructionListeners.remove(ob);
- }
-
private void notifyMemoryChanged(long address)
{
observers.forEach(o -> o.update(address));
}
- private void notifyActiveInstructionChanged(long address)
- {
- activeInstructionListeners.forEach(o -> o.activeMicroInstructionChanged(address));
- }
-
@Override
public MicroInstructionMemoryDefinition getDefinition()
{
notifyMemoryChanged(address);
}
- @Override
- public void setActiveInstruction(long address)
- {
- real.setActiveInstruction(address);
- }
-
- @Override
- public void activeMicroInstructionChanged(long address)
- {
- notifyActiveInstructionChanged(address);
- }
-
public void registerMemoryReassignedListener(MIMemoryReassignedListener listener)
{
reassignmentListeners.add(listener);
{
@Override
public MicroInstructionMemoryDefinition getDefinition();
-
- public void registerActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob);
-
- public void deregisterActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob);
-
- public void setActiveInstruction(long address);
-
- public static interface ActiveMicroInstructionChangedListener
- {
- public void activeMicroInstructionChanged(long address);
- }
}
package net.mograsim.machine.mi;
import java.util.HashSet;
-import java.util.Set;
import net.mograsim.machine.standard.memory.MemoryException;
private MicroInstruction[] data;
private MicroInstructionMemoryDefinition definition;
private HashSet<MemoryCellModifiedListener> observers = new HashSet<>();
- private Set<ActiveMicroInstructionChangedListener> activeInstructionListeners = new HashSet<>();
- private long activeInstruction = -1;
public StandardMicroInstructionMemory(MicroInstructionMemoryDefinition definition)
{
observers.remove(ob);
}
- @Override
- public void registerActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob)
- {
- activeInstructionListeners.add(ob);
- }
-
- @Override
- public void deregisterActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob)
- {
- activeInstructionListeners.remove(ob);
- }
-
private void notifyMemoryChanged(long address)
{
observers.forEach(ob -> ob.update(address));
}
- private void notifyActiveInstructionChanged(long address)
- {
- activeInstructionListeners.forEach(o -> o.activeMicroInstructionChanged(address));
- }
-
@Override
public MicroInstructionMemoryDefinition getDefinition()
{
return definition;
}
-
- @Override
- public void setActiveInstruction(long address)
- {
- if (address != activeInstruction)
- {
- activeInstruction = address;
- notifyActiveInstructionChanged(address);
- }
- }
-
}
return e -> data.feedSignals(Bit.U.toVector(data.width()));// TODO don't always feed U, but decide to feed X or U.
long addressed = address.getValues().getUnsignedValueLong();
BitVector storedData = memory.getCell(addressed).toBitVector();
- memory.setActiveInstruction(addressed);
return e -> data.feedSignals(storedData);
}
}
\ No newline at end of file
extension.name.1 = XML Problem
decorator.label = Resource Decorator
themeElementCategory.label = Mograsim
+themeElementCategory.label.0 = Simulation
+themeElementCategory.label.1 = Microinstructions
colorDefinition.label = Simulation Background
colorDefinition.description = The Background of the Simulation Visualisation
colorDefinition.label.0 = Simulation Foreground Color
colorDefinition.label.8 = Simulation Color Z
colorDefinition.label.9 = Simulation Color 0
colorDefinition.label.10 = Simulation text color
+colorDefinition.label.11 = Modified Cell Background Color
+colorDefinition.label.12 = Modified Cell Foreground Color
+colorDefinition.label.13 = Highlighted Cell Background Color
+colorDefinition.label.14 = Highlighted Cell Foreground Color
fontDefinition.label = Assembler Operation Style
+fontDefinition.label.0 = Table Font
view.name.0 = Simulation View
view.name.1 = Memory
wizards.newWizards.category = Mograsim
wizards.newWizards.mpm.name = Microprogram Memory
wizards.newWizards.mpm.desc = Creates a default new Microprogram Memory
-themeElementCategory.label.0 = Simulation
Bundle-Vendor.0 = Mograsim Team
\ No newline at end of file
label="%themeElementCategory.label.0"
parentId="net.mograsim.plugin.mograsim">
</themeElementCategory>
+ <themeElementCategory
+ class="net.mograsim.plugin.SimulationPreview"
+ id="net.mograsim.plugin.mi"
+ label="%themeElementCategory.label.1"
+ parentId="net.mograsim.plugin.mograsim">
+ </themeElementCategory>
<colorDefinition
categoryId="net.mograsim.logic.model"
id="net.mograsim.logic.model.color.background"
isEditable="true"
label="%fontDefinition.label">
</fontDefinition>
+ <colorDefinition
+ categoryId="net.mograsim.plugin.mi"
+ id="net.mograsim.plugin.modified_cell_bg_color"
+ isEditable="true"
+ label="%colorDefinition.label.11"
+ value="COLOR_GREEN">
+ </colorDefinition>
+ <colorDefinition
+ categoryId="net.mograsim.plugin.mi"
+ id="net.mograsim.plugin.modified_cell_fg_color"
+ isEditable="true"
+ label="%colorDefinition.label.12"
+ value="COLOR_BLACK">
+ </colorDefinition>
+ <fontDefinition
+ categoryId="net.mograsim.plugin.mi"
+ id="net.mograsim.plugin.table_font"
+ isEditable="true"
+ label="%fontDefinition.label.0">
+ </fontDefinition>
+ <colorDefinition
+ categoryId="net.mograsim.plugin.mi"
+ id="net.mograsim.plugin.highlighted_cell_bg_color"
+ isEditable="true"
+ label="%colorDefinition.label.13"
+ value="COLOR_YELLOW">
+ </colorDefinition>
+ <colorDefinition
+ categoryId="net.mograsim.plugin.mi"
+ id="net.mograsim.plugin.highlighted_cell_fg_color"
+ isEditable="true"
+ label="%colorDefinition.label.14"
+ value="COLOR_BLACK">
+ </colorDefinition>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
public SimulationViewEditor()
{
- activeMachineListener = m -> recreateContextDependentControls();
+ activeMachineListener = (oldM, newM) -> recreateContextDependentControls();
memCellListener = a -> instPreview.refresh();
clockObserver = o ->
{
canvasParent.layout();
+ // update preview
+ ((ActiveInstructionPreviewContentProvider) instPreview.getTableViewer().getContentProvider()).setMachine(machine);
+
// initialize executer
exec = new LogicExecuter(machine.getTimeline());
updateSpeedFactorFromInput(simSpeedInput.getValue());
private void addInstructionPreviewControlWidgets(Composite parent)
{
- instPreview = new InstructionTable(parent, new DisplaySettings());
+ instPreview = new InstructionTable(parent, new DisplaySettings(), getSite().getWorkbenchWindow().getWorkbench().getThemeManager());
instPreview.getTableViewer().getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- instPreview.setContentProvider(new ActiveInstructionPreviewContentProvider(instPreview.getTableViewer()));
+ ActiveInstructionPreviewContentProvider cProv;
+ instPreview.setContentProvider(cProv = new ActiveInstructionPreviewContentProvider(instPreview.getTableViewer()));
+ cProv.setMachine(machine);
}
private static void setPauseText(Button pauseButton, boolean hovered)
*/
public final void setActiveMachine(Machine machine)
{
+ Optional<Machine> oldMachine = activeMachine;
activeMachine = Optional.ofNullable(machine);
updateStatus();
- notifyActiveMachineListeners();
+ notifyActiveMachineListeners(oldMachine, activeMachine);
}
public final Optional<String> getMachineId()
{
if ((status == DEAD || status == CLOSED) && activeMachine.isPresent())
{
+ Optional<Machine> oldMachine = activeMachine;
activeMachine = Optional.empty();
- notifyActiveMachineListeners();
+ notifyActiveMachineListeners(oldMachine, activeMachine);
}
}
}
}
- private void notifyActiveMachineListeners()
+ private void notifyActiveMachineListeners(Optional<Machine> oldMachine, Optional<Machine> newMachine)
{
- machineListeners.forEach(ob -> ob.setMachine(activeMachine));
+ machineListeners.forEach(ob -> ob.setMachine(oldMachine, newMachine));
}
public void addActiveMachineListener(ActiveMachineListener ob)
{
machineListeners.add(ob);
- ob.setMachine(activeMachine);
+ ob.setMachine(Optional.empty(), activeMachine);
}
public void removeActiveMachineListener(ActiveMachineListener ob)
@FunctionalInterface
public static interface ActiveMachineListener
{
- void setMachine(Optional<Machine> machine);
+ void setMachine(Optional<Machine> oldMachine, Optional<Machine> newMachine);
}
@FunctionalInterface
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
+import net.mograsim.machine.Machine;
+import net.mograsim.machine.Machine.ActiveMicroInstructionChangedListener;
import net.mograsim.machine.mi.MicroInstructionMemory;
-import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener;
+import net.mograsim.plugin.util.SingleSWTRequest;
-public class ActiveInstructionPreviewContentProvider implements InstructionTableContentProvider, ActiveMicroInstructionChangedListener
+public class ActiveInstructionPreviewContentProvider implements InstructionTableContentProvider
{
private TableViewer viewer;
private MicroInstructionMemory memory;
private InstructionTableRow activeRow;
+ private Machine machine;
+ private SingleSWTRequest requester = new SingleSWTRequest();
+
+ private ActiveMicroInstructionChangedListener instChanged = (oldAddress, newAddress) ->
+ {
+ activeRow = new InstructionTableRow(Long.max(0, newAddress), memory);
+ requester.request(() -> updateElement(0));
+ };
public ActiveInstructionPreviewContentProvider(TableViewer viewer)
{
viewer.setItemCount(1);
}
- @Override
- public void activeMicroInstructionChanged(long address)
- {
- this.activeRow = new InstructionTableRow(address, memory);
- viewer.refresh();
- }
-
@Override
public void update(long address)
{
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
- if (oldInput != null)
- ((MicroInstructionMemory) oldInput).deregisterActiveMicroInstructionChangedListener(this);
-
memory = (MicroInstructionMemory) newInput;
- if (memory != null)
+ }
+
+ public void setMachine(Machine newMachine)
+ {
+ if (machine != null)
+ machine.removeActiveMicroInstructionChangedListener(instChanged);
+
+ machine = newMachine;
+ if (machine != null)
{
- activeMicroInstructionChanged(0);
- memory.registerActiveMicroInstructionChangedListener(this);
+ instChanged.instructionChanged(-1, 0);
+ machine.addActiveMicroInstructionChangedListener(instChanged);
}
}
--- /dev/null
+package net.mograsim.plugin.tables.mi;
+
+import org.eclipse.jface.resource.ColorRegistry;
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.themes.ITheme;
+import org.eclipse.ui.themes.IThemeManager;
+
+import net.mograsim.machine.mi.MicroInstructionMemory;
+
+public class ColorProvider
+{
+ private final TableViewer viewer;
+ private final IThemeManager themeManager;
+ private long highlightedAddress = -1;
+ private ColorRegistry cRegistry;
+ private FontRegistry fRegistry;
+ private Font boldItalic;
+
+ private final static String font = "net.mograsim.plugin.table_font",
+ colorModifBackground = "net.mograsim.plugin.modified_cell_bg_color",
+ colorModifForeground = "net.mograsim.plugin.modified_cell_fg_color",
+ colorHighlightedForeground = "net.mograsim.plugin.highlighted_cell_fg_color",
+ colorHighlightedBackground = "net.mograsim.plugin.highlighted_cell_bg_color";
+ private final IPropertyChangeListener updateListener;
+
+ public ColorProvider(TableViewer viewer, IThemeManager themeManager)
+ {
+ this.viewer = viewer;
+ this.themeManager = themeManager;
+ themeChanged(themeManager.getCurrentTheme());
+ updateListener = e ->
+ {
+ switch (e.getProperty())
+ {
+ case IThemeManager.CHANGE_CURRENT_THEME:
+ themeChanged(themeManager.getCurrentTheme());
+ //$FALL-THROUGH$
+ case font:
+ case colorModifBackground:
+ case colorModifForeground:
+ viewer.refresh();
+ break;
+ default:
+ break;
+ }
+ };
+ themeManager.addPropertyChangeListener(updateListener);
+ }
+
+ private void themeChanged(ITheme theme)
+ {
+ cRegistry = theme.getColorRegistry();
+ fRegistry = theme.getFontRegistry();
+ boldItalic = fRegistry.getDescriptor(font).setStyle(SWT.BOLD | SWT.ITALIC).createFont(Display.getDefault());
+ }
+
+ public Color getBackground(Object element, int column)
+ {
+ InstructionTableRow row = (InstructionTableRow) element;
+ if (isDefault(row, column))
+ {
+ if (isHighlighted(row))
+ return cRegistry.get(colorHighlightedBackground);
+ return viewer.getTable().getBackground();
+ }
+ return cRegistry.get(colorModifBackground);
+ }
+
+ public Color getForeground(Object element, int column)
+ {
+ InstructionTableRow row = (InstructionTableRow) element;
+ if (isDefault(row, column))
+ {
+ if (isHighlighted(row))
+ return cRegistry.get(colorHighlightedForeground);
+ return viewer.getTable().getForeground();
+ }
+ return cRegistry.get(colorModifForeground);
+ }
+
+ public Font getFont(Object element, int column)
+ {
+ InstructionTableRow row = (InstructionTableRow) element;
+ boolean modified = !isDefault(row, column), highlighted = isHighlighted(row);
+ if (modified && highlighted)
+ return boldItalic;
+ if (modified)
+ return fRegistry.getItalic(font);
+ if (highlighted)
+ return fRegistry.getBold(font);
+ return fRegistry.get(font);
+ }
+
+ private static boolean isDefault(InstructionTableRow row, int column)
+ {
+ return column == -1 ? true : row.data.getCell(row.address).getParameter(column).isDefault();
+ }
+
+ private boolean isHighlighted(InstructionTableRow row)
+ {
+ return highlightedAddress == row.address;
+ }
+
+ /**
+ * @param index Index of the row to highlight; An negative index means no row is highlighted
+ */
+ public void highlight(long row)
+ {
+ highlightedAddress = row + ((MicroInstructionMemory) viewer.getInput()).getDefinition().getMinimalAddress();
+ }
+
+ public void dispose()
+ {
+ themeManager.removePropertyChangeListener(updateListener);
+ }
+}
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.themes.IThemeManager;
import net.mograsim.machine.mi.MicroInstructionDefinition;
import net.mograsim.machine.mi.MicroInstructionMemory;
public class InstructionTable
{
- protected DisplaySettings displaySettings;
- protected LazyTableViewer viewer;
+ protected final DisplaySettings displaySettings;
+ protected final LazyTableViewer viewer;
private TableViewerColumn[] columns = new TableViewerColumn[0];
private MicroInstructionDefinition miDef;
private MicroInstructionMemory memory;
private InstructionTableContentProvider provider;
+ private final RowHighlighter highlighter;
+ private final ColorProvider cProv;
- public InstructionTable(Composite parent, DisplaySettings displaySettings)
+ public InstructionTable(Composite parent, DisplaySettings displaySettings, IThemeManager themeManager)
{
viewer = new LazyTableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
this.displaySettings = displaySettings;
+ this.cProv = new ColorProvider(viewer, themeManager);
+ this.highlighter = new RowHighlighter(viewer, cProv);
Table table = viewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
viewer.setUseHashlookup(true);
+ table.addDisposeListener(e -> dispose());
TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(viewer, new FocusCellOwnerDrawHighlighter(viewer));
TableViewerColumn col = createTableViewerColumn("Address");
columns[0] = col;
- col.setLabelProvider(new AddressLabelProvider());
+ col.setLabelProvider(new AddressLabelProvider()
+ {
+ @Override
+ public Color getBackground(Object element)
+ {
+ return cProv.getBackground(element, -1);
+ }
+
+ @Override
+ public Color getForeground(Object element)
+ {
+ return cProv.getForeground(element, -1);
+ }
+
+ @Override
+ public Font getFont(Object element)
+ {
+ return cProv.getFont(element, -1);
+ }
+ });
String[] columnTitles = new String[size];
{
case BOOLEAN_IMMEDIATE:
support = new BooleanEditingSupport(viewer, miDef, index);
- provider = new ParameterLabelProvider(index);
+ provider = new ParameterLabelProvider(cProv, index);
break;
case INTEGER_IMMEDIATE:
support = new IntegerEditingSupport(viewer, miDef, index, displaySettings, this.provider);
- provider = new IntegerColumnLabelProvider(displaySettings, index);
+ provider = new IntegerColumnLabelProvider(displaySettings, cProv, index);
break;
case MNEMONIC:
support = new MnemonicEditingSupport(viewer, miDef, index, this.provider);
- provider = new ParameterLabelProvider(index);
+ provider = new ParameterLabelProvider(cProv, index);
break;
default:
throw new IllegalStateException(
{
Display.getDefault().asyncExec(() -> viewer.refresh());
}
+
+ private void dispose()
+ {
+ cProv.dispose();
+ viewer.getTable().dispose();
+ }
+
+ public void highlight(int row)
+ {
+ highlighter.highlight(row);
+ }
}
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
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.Machine.ActiveMicroInstructionChangedListener;
import net.mograsim.machine.Memory.MemoryCellModifiedListener;
import net.mograsim.machine.mi.AssignableMicroInstructionMemory.MIMemoryReassignedListener;
import net.mograsim.machine.mi.MicroInstructionMemory;
-import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener;
import net.mograsim.machine.mi.MicroInstructionMemoryParseException;
import net.mograsim.machine.mi.MicroInstructionMemoryParser;
import net.mograsim.plugin.nature.MachineContext;
+import net.mograsim.plugin.nature.MachineContext.ActiveMachineListener;
import net.mograsim.plugin.nature.ProjectMachineContext;
import net.mograsim.plugin.tables.DisplaySettings;
-import net.mograsim.plugin.tables.LazyTableViewer;
import net.mograsim.plugin.tables.RadixSelector;
-public class InstructionView extends EditorPart implements MemoryCellModifiedListener, ActiveMicroInstructionChangedListener
+public class InstructionView extends EditorPart
{
private InstructionTableContentProvider provider;
- private int highlighted = 0;
private boolean dirty = false;
private MicroInstructionMemory memory;
private InstructionTable table;
private MachineContext context;
+ // Listeners
+ private MemoryCellModifiedListener cellModifiedListener = address ->
+ {
+ setDirty(true);
+ table.refresh();
+ };
+
+ private ActiveMicroInstructionChangedListener instChangeListener = (oldAddress, newAddress) ->
+ {
+ highlight((int) (newAddress - memory.getDefinition().getMinimalAddress()));
+ };
+
+ private MIMemoryReassignedListener reassignedListener = newAssignee ->
+ {
+ // clear highlighting if the memory is reassigned
+ if (newAssignee != memory)
+ highlight(-1);
+ };
+
+ private ActiveMachineListener activeMachineListener = (oldMachine, newMachine) ->
+ {
+ // clear highlighting if the active machine changes
+ if (newMachine.isEmpty() || !newMachine.equals(oldMachine))
+ {
+ highlight(-1);
+ oldMachine.ifPresent(m -> m.getMicroInstructionMemory().deregisterMemoryReassignedListener(reassignedListener));
+ }
+ };
+
@SuppressWarnings("unused")
@Override
public void createPartControl(Composite parent)
new RadixSelector(parent, displaySettings);
addActivationButton(parent);
-
- table = new InstructionTable(parent, displaySettings);
+ table = new InstructionTable(parent, displaySettings, getSite().getWorkbenchWindow().getWorkbench().getThemeManager());
table.setContentProvider(provider);
table.bindMicroInstructionMemory(memory);
table.getTableViewer().getTable().setLayoutData(viewerData);
}
- public void highlight(int index)
+ public void highlight(int row)
{
- Display.getDefault().asyncExec(() ->
- {
- LazyTableViewer viewer = table.getTableViewer();
- viewer.highlightRow(highlighted, false);
- highlighted = index;
- if (index != -1)
- {
- viewer.highlightRow(index, true);
- viewer.getTable()
- .showItem(viewer.getTable().getItem(Math.min((int) memory.getDefinition().getMaximalAddress(), index + 2)));
- viewer.getTable().showItem(viewer.getTable().getItem(index));
- }
- });
+ table.highlight(row);
}
private void addActivationButton(Composite parent)
activationButton.setText("Set Active");
activationButton.addListener(SWT.Selection, e -> context.getActiveMachine().ifPresent(m ->
{
- // clear highlighting if the memory is reassigned
- MIMemoryReassignedListener memReassignedListener = n ->
- {
- if (n != memory)
- highlight(-1);
- };
- m.getMicroInstructionMemory().registerMemoryReassignedListener(memReassignedListener);
- // clear highlighting if the active machine changes
- context.addActiveMachineListener(n ->
- {
- if (n.isEmpty() || n.get() != m)
- {
- highlight(-1);
- m.getMicroInstructionMemory().deregisterMemoryReassignedListener(memReassignedListener);
- }
- });
+ m.getMicroInstructionMemory().registerMemoryReassignedListener(reassignedListener);
+ context.addActiveMachineListener(activeMachineListener);
m.getMicroInstructionMemory().bind(memory);
+ m.addActiveMicroInstructionChangedListener(instChangeListener);
}));
}
{
if (this.memory != null)
{
- this.memory.deregisterCellModifiedListener(this);
- this.memory.deregisterActiveMicroInstructionChangedListener(this);
+ this.memory.deregisterCellModifiedListener(cellModifiedListener);
}
this.memory = memory;
if (memory != null)
{
- this.memory.registerCellModifiedListener(this);
- this.memory.registerActiveMicroInstructionChangedListener(this);
+ this.memory.registerCellModifiedListener(cellModifiedListener);
}
if (table != null)
table.bindMicroInstructionMemory(memory);
return false;
}
- @Override
- public void update(long address)
- {
- setDirty(true);
- table.refresh();
- }
-
private void setDirty(boolean value)
{
dirty = value;
}
@Override
- public void activeMicroInstructionChanged(long address)
+ public void dispose()
{
- highlight((int) (address - memory.getDefinition().getMinimalAddress()));
+ memory.deregisterCellModifiedListener(cellModifiedListener);
+ context.getActiveMachine().ifPresent(m ->
+ {
+ m.removeActiveMicroInstructionChangedListener(instChangeListener);
+ m.getMicroInstructionMemory().deregisterMemoryReassignedListener(reassignedListener);
+ });
+ context.removeActiveMachineListener(activeMachineListener);
+ super.dispose();
}
}
import java.math.BigInteger;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
import net.mograsim.machine.mi.parameters.IntegerImmediate;
import net.mograsim.plugin.tables.DisplaySettings;
import net.mograsim.plugin.tables.NumberColumnLabelProvider;
public class IntegerColumnLabelProvider extends NumberColumnLabelProvider
{
- private int index;
+ private final int index;
+ private final ColorProvider cProv;
- public IntegerColumnLabelProvider(DisplaySettings displaySettings, int index)
+ public IntegerColumnLabelProvider(DisplaySettings displaySettings, ColorProvider cProv, int index)
{
super(displaySettings);
+ this.cProv = cProv;
this.index = index;
}
.getExpectedBits();
}
+ @Override
+ public Color getBackground(Object element)
+ {
+ return cProv.getBackground(element, index);
+ }
+
+ @Override
+ public Color getForeground(Object element)
+ {
+ return cProv.getForeground(element, index);
+ }
+
+ @Override
+ public Font getFont(Object element)
+ {
+ return cProv.getFont(element, index);
+ }
}
package net.mograsim.plugin.tables.mi;
import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
public class ParameterLabelProvider extends ColumnLabelProvider
{
private final int index;
+ private final ColorProvider cProv;
- public ParameterLabelProvider(int index)
+ public ParameterLabelProvider(ColorProvider cProv, int index)
{
super();
this.index = index;
+ this.cProv = cProv;
}
@Override
InstructionTableRow row = (InstructionTableRow) element;
return row.data.getCell(row.address).getParameter(index).toString();
}
+
+ @Override
+ public Color getBackground(Object element)
+ {
+ return cProv.getBackground(element, index);
+ }
+
+ @Override
+ public Color getForeground(Object element)
+ {
+ return cProv.getForeground(element, index);
+ }
+
+ @Override
+ public Font getFont(Object element)
+ {
+ return cProv.getFont(element, index);
+ }
}
--- /dev/null
+package net.mograsim.plugin.tables.mi;
+
+import java.util.Optional;
+
+import org.eclipse.swt.widgets.Table;
+
+import net.mograsim.plugin.tables.LazyTableViewer;
+import net.mograsim.plugin.util.SingleSWTRequest;
+
+public class RowHighlighter
+{
+ private int highlighted = -1;
+ private LazyTableViewer viewer;
+ private ColorProvider cProv;
+ private SingleSWTRequest requester = new SingleSWTRequest();
+
+ public RowHighlighter(LazyTableViewer viewer, ColorProvider cProv)
+ {
+ this.viewer = viewer;
+ this.cProv = cProv;
+ }
+
+ public void highlight(int row)
+ {
+ requester.request(() ->
+ {
+ if (!viewer.getTable().isDisposed())
+ innerHighlight(row);
+ });
+ }
+
+ private void innerHighlight(int row)
+ {
+ Table table = viewer.getTable();
+ cProv.highlight(row);
+ if (row != -1)
+ {
+ table.showItem(table.getItem(Math.min(table.getItemCount(), row + 2)));
+ table.showItem(table.getItem(row));
+ Optional.ofNullable(table.getItem(row).getData()).ifPresent(d -> viewer.update(d, null));
+ }
+ if (highlighted != -1)
+ Optional.ofNullable(table.getItem(highlighted).getData()).ifPresent(d -> viewer.update(d, null));
+ highlighted = row;
+ }
+}
--- /dev/null
+package net.mograsim.plugin.util;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.swt.widgets.Display;
+
+public class SingleSWTRequest
+{
+ private AtomicBoolean waiting = new AtomicBoolean();
+
+ public void request(Runnable request)
+ {
+ synchronized (waiting)
+ {
+ if (!waiting.get())
+ {
+ waiting.set(true);
+ Display.getDefault().asyncExec(() ->
+ {
+ synchronized (waiting)
+ {
+ waiting.set(false);
+ request.run();
+ }
+ });
+ }
+ }
+ }
+}