Reworked some parts of the MachineContext to make its status clear.
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / tables / mi / InstructionView.java
1 package net.mograsim.plugin.tables.mi;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5
6 import org.eclipse.core.resources.IFile;
7 import org.eclipse.core.runtime.CoreException;
8 import org.eclipse.core.runtime.IProgressMonitor;
9 import org.eclipse.swt.SWT;
10 import org.eclipse.swt.layout.GridData;
11 import org.eclipse.swt.layout.GridLayout;
12 import org.eclipse.swt.widgets.Button;
13 import org.eclipse.swt.widgets.Composite;
14 import org.eclipse.swt.widgets.Display;
15 import org.eclipse.ui.IEditorInput;
16 import org.eclipse.ui.IEditorSite;
17 import org.eclipse.ui.IFileEditorInput;
18 import org.eclipse.ui.PartInitException;
19 import org.eclipse.ui.part.EditorPart;
20
21 import net.mograsim.machine.Memory.MemoryCellModifiedListener;
22 import net.mograsim.machine.mi.MicroInstructionMemory;
23 import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener;
24 import net.mograsim.machine.mi.MicroInstructionMemoryParseException;
25 import net.mograsim.machine.mi.MicroInstructionMemoryParser;
26 import net.mograsim.plugin.nature.MachineContext;
27 import net.mograsim.plugin.nature.ProjectMachineContext;
28 import net.mograsim.plugin.tables.DisplaySettings;
29 import net.mograsim.plugin.tables.LazyTableViewer;
30 import net.mograsim.plugin.tables.RadixSelector;
31
32 public class InstructionView extends EditorPart implements MemoryCellModifiedListener, ActiveMicroInstructionChangedListener
33 {
34         private InstructionTableContentProvider provider;
35         private int highlighted = 0;
36         private boolean dirty = false;
37         private MicroInstructionMemory memory;
38         private InstructionTable table;
39         private MachineContext context;
40
41         @SuppressWarnings("unused")
42         @Override
43         public void createPartControl(Composite parent)
44         {
45                 provider = new InstructionTableLazyContentProvider();
46                 GridLayout layout = new GridLayout(3, false);
47                 parent.setLayout(layout);
48
49                 DisplaySettings displaySettings = new DisplaySettings();
50                 new RadixSelector(parent, displaySettings);
51
52                 addActivationButton(parent);
53
54                 table = new InstructionTable(parent, displaySettings);
55                 table.setContentProvider(provider);
56                 table.bindMicroInstructionMemory(memory);
57
58                 GridData viewerData = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
59                 viewerData.horizontalSpan = 3;
60                 table.getTableViewer().getTable().setLayoutData(viewerData);
61         }
62
63         public void highlight(int index)
64         {
65                 Display.getDefault().asyncExec(() ->
66                 {
67                         LazyTableViewer viewer = table.getTableViewer();
68                         viewer.highlightRow(highlighted, false);
69                         highlighted = index;
70                         viewer.highlightRow(index, true);
71                         viewer.getTable().showItem(viewer.getTable().getItem(Math.min((int) memory.getDefinition().getMaximalAddress(), index + 2)));
72                         viewer.getTable().showItem(viewer.getTable().getItem(index));
73                 });
74         }
75
76         private void addActivationButton(Composite parent)
77         {
78                 Button activationButton = new Button(parent, SWT.PUSH);
79                 activationButton.setText("Set Active");
80                 activationButton.addListener(SWT.Selection,
81                                 e -> context.getActiveMachine().ifPresent(m -> m.getMicroInstructionMemory().bind(memory)));
82         }
83
84         public void bindMicroInstructionMemory(MicroInstructionMemory memory)
85         {
86                 if (this.memory != null)
87                 {
88                         this.memory.deregisterCellModifiedListener(this);
89                         this.memory.deregisterActiveMicroInstructionChangedListener(this);
90                 }
91                 this.memory = memory;
92                 if (memory != null)
93                 {
94                         this.memory.registerCellModifiedListener(this);
95                         this.memory.registerActiveMicroInstructionChangedListener(this);
96                 }
97                 if (table != null)
98                         table.bindMicroInstructionMemory(memory);
99         }
100
101         private void open(IFile file) throws IOException, MicroInstructionMemoryParseException, CoreException
102         {
103                 bindMicroInstructionMemory(MicroInstructionMemoryParser.parseMemory(
104                                 context.getMachineDefinition().orElseThrow(() -> new MicroInstructionMemoryParseException("No MachineDefinition assigned!"))
105                                                 .getMicroInstructionMemoryDefinition(),
106                                 file.getContents()));
107         }
108
109         private void save(IFile file, IProgressMonitor progressMonitor) throws IOException, CoreException, MicroInstructionMemoryParseException
110         {
111                 if (memory == null)
112                 {
113                         throw new MicroInstructionMemoryParseException(
114                                         "Failed to write MicroprogrammingMemory to File. No MicroprogrammingMemory assigned.");
115                 }
116                 try (InputStream toWrite = MicroInstructionMemoryParser.write(memory))
117                 {
118                         file.setContents(toWrite, 0, progressMonitor);
119                 }
120         }
121
122         @Override
123         public void setFocus()
124         {
125                 table.getTableViewer().getControl().setFocus();
126         }
127
128         @Override
129         public void doSave(IProgressMonitor progressMonitor)
130         {
131                 IEditorInput input = getEditorInput();
132                 if (input instanceof IFileEditorInput)
133                 {
134                         IFileEditorInput pathInput = (IFileEditorInput) input;
135                         try
136                         {
137                                 save(pathInput.getFile(), progressMonitor);
138                                 setDirty(false);
139                         }
140                         catch (Exception e)
141                         {
142                                 e.printStackTrace();
143                                 progressMonitor.setCanceled(true);
144                         }
145                 } else
146                         progressMonitor.setCanceled(true);
147         }
148
149         @Override
150         public void doSaveAs()
151         {
152 //              openSaveAsDialog();
153         }
154
155 //      private void openSaveAsDialog()
156 //      {
157 //              FileDialog d = new FileDialog(table.getTableViewer().getTable().getShell(), SWT.SAVE);
158 //              d.open();
159 //              String filename = d.getFileName();
160 //              if (!filename.equals(""))
161 //              {
162 //                      save(d.getFilterPath() + File.separator + filename);
163 //                      setDirty(false);
164 //              }
165 //      }
166
167         @Override
168         public void init(IEditorSite site, IEditorInput input) throws PartInitException
169         {
170                 setSite(site);
171                 setInput(input);
172                 try
173                 {
174                         if (input instanceof IFileEditorInput)
175                         {
176                                 IFileEditorInput fileInput = (IFileEditorInput) input;
177                                 context = ProjectMachineContext.getMachineContextOf(fileInput.getFile().getProject());
178                                 context.activateMachine();
179                                 setPartName(fileInput.getName());
180                                 open(fileInput.getFile());
181                         }
182                 }
183                 catch (Exception e)
184                 {
185                         throw new PartInitException("Failed to read input!", e);
186                 }
187
188         }
189
190         @Override
191         public boolean isDirty()
192         {
193                 return dirty;
194         }
195
196         @Override
197         public boolean isSaveAsAllowed()
198         {
199                 return false;
200         }
201
202         @Override
203         public void update(long address)
204         {
205                 setDirty(true);
206                 table.refresh();
207         }
208
209         private void setDirty(boolean value)
210         {
211                 dirty = value;
212                 firePropertyChange(PROP_DIRTY);
213         }
214
215         @Override
216         public void activeMicroInstructionChanged(long address)
217         {
218                 highlight((int) (address - memory.getDefinition().getMinimalAddress()));
219         }
220 }