Fixed #17 (Mem editors stop one address too early)
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / tables / memory / MemoryTableContentProvider.java
1 package net.mograsim.plugin.tables.memory;
2
3 import org.eclipse.jface.viewers.ILazyContentProvider;
4 import org.eclipse.jface.viewers.TableViewer;
5 import org.eclipse.jface.viewers.Viewer;
6 import org.eclipse.swt.widgets.Display;
7
8 import net.mograsim.machine.BitVectorMemory;
9 import net.mograsim.machine.BitVectorMemoryDefinition;
10 import net.mograsim.machine.Memory.MemoryCellModifiedListener;
11
12 public class MemoryTableContentProvider implements ILazyContentProvider, MemoryCellModifiedListener
13 {
14         private long lower, upper;
15         private TableViewer viewer;
16         public final static int MAX_VISIBLE_ROWS = 1_000;
17         private BitVectorMemory memory;
18
19         public void setBounds(long lower, long upper)
20         {
21                 if (memory != null)
22                 {
23                         BitVectorMemoryDefinition definition = memory.getDefinition();
24                         this.lower = Long.min(definition.getMaximalAddress(), Long.max(definition.getMinimalAddress(), lower));
25                         this.upper = Long.max(this.lower, Long.min(definition.getMaximalAddress(), upper));
26                 } else
27                 {
28                         this.lower = lower;
29                         this.upper = Long.max(this.lower, upper);
30                 }
31                 updateItemCount();
32         }
33
34         public void updateItemCount()
35         {
36                 if (viewer != null)
37                         viewer.setItemCount(getAmount());
38         }
39
40         public long getLowerBound()
41         {
42                 return lower;
43         }
44
45         public long getUpperBound()
46         {
47                 return upper;
48         }
49
50         public int getAmount()
51         {
52                 return (int) (upper - lower + 1);
53         }
54
55         @Override
56         public void updateElement(int index)
57         {
58                 if (index < getAmount())
59                 {
60                         long address = lower + index;
61                         if (address <= memory.getDefinition().getMaximalAddress())
62                                 viewer.replace(new MemoryTableRow(address, memory), index);
63                 }
64         }
65
66         @Override
67         public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
68         {
69                 this.viewer = (TableViewer) viewer;
70                 this.memory = (BitVectorMemory) newInput;
71                 if (oldInput != null)
72                         ((BitVectorMemory) oldInput).deregisterCellModifiedListener(this);
73                 if (memory != null)
74                         memory.registerCellModifiedListener(this);
75                 setBounds(0, MAX_VISIBLE_ROWS);
76         }
77
78         @Override
79         public void update(long address)
80         {
81                 // TODO check if viewer.refresh() does what we expect
82                 Display.getDefault().asyncExec(address == -1 ? viewer::refresh : () -> updateElement((int) (address - lower)));
83         }
84 }