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