8c0685dc897dca4ba408c1e995529803d344415c
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / launch / MachineRegister.java
1 package net.mograsim.plugin.launch;
2
3 import java.util.Arrays;
4 import java.util.function.Consumer;
5
6 import org.eclipse.core.runtime.PlatformObject;
7 import org.eclipse.core.runtime.Status;
8 import org.eclipse.debug.core.DebugEvent;
9 import org.eclipse.debug.core.DebugException;
10 import org.eclipse.debug.core.DebugPlugin;
11 import org.eclipse.debug.core.ILaunch;
12 import org.eclipse.debug.core.model.IDebugElement;
13 import org.eclipse.debug.core.model.IDebugTarget;
14 import org.eclipse.debug.core.model.IRegister;
15 import org.eclipse.debug.core.model.IRegisterGroup;
16 import org.eclipse.debug.core.model.IValue;
17 import org.eclipse.swt.SWT;
18
19 import net.mograsim.logic.core.types.BitVector;
20 import net.mograsim.machine.Machine;
21 import net.mograsim.machine.Register;
22 import net.mograsim.plugin.MograsimActivator;
23
24 public class MachineRegister extends PlatformObject implements IRegister
25 {
26         private final MachineRegisterGroup registerGroup;
27         private final Register machineRegister;
28
29         private final Consumer<BitVector> registerListener;
30
31         public MachineRegister(MachineRegisterGroup registerGroup, Register machineRegister)
32         {
33                 this.registerGroup = registerGroup;
34                 this.machineRegister = machineRegister;
35
36                 this.registerListener = v -> fireChangeEvent();
37                 getMachine().addRegisterListener(machineRegister, registerListener);
38
39                 DebugPlugin.getDefault().addDebugEventListener(es -> Arrays.stream(es).filter(e -> e.getKind() == DebugEvent.TERMINATE).filter(e ->
40                 {
41                         Object source = e.getSource();
42                         if (!(source instanceof IDebugElement))
43                                 return false;
44                         return ((IDebugElement) source).getDebugTarget() == getDebugTarget();
45                 }).forEach(e -> getMachine().removeRegisterListener(machineRegister, registerListener)));
46         }
47
48         public Machine getMachine()
49         {
50                 return registerGroup.getMachine();
51         }
52
53         @Override
54         public IValue getValue() throws DebugException
55         {
56                 return new MachineValue(this);
57         }
58
59         @Override
60         public String getName() throws DebugException
61         {
62                 return machineRegister.id();// TODO name
63         }
64
65         @Override
66         public String getReferenceTypeName() throws DebugException
67         {
68                 return "BitVector";
69         }
70
71         @Override
72         public boolean hasValueChanged() throws DebugException
73         {
74                 // TODO
75                 return false;
76         }
77
78         @Override
79         public String getModelIdentifier()
80         {
81                 return MograsimActivator.PLUGIN_ID;
82         }
83
84         @Override
85         public IDebugTarget getDebugTarget()
86         {
87                 return registerGroup.getDebugTarget();
88         }
89
90         @Override
91         public ILaunch getLaunch()
92         {
93                 return registerGroup.getLaunch();
94         }
95
96         public String getValueString()
97         {
98                 return getMachine().getRegister(machineRegister).toString();
99         }
100
101         @Override
102         public void setValue(String expression) throws DebugException
103         {
104                 // TODO exception handling
105                 getMachine().setRegister(machineRegister, BitVector.parse(expression));
106         }
107
108         @Override
109         public void setValue(IValue value) throws DebugException
110         {
111                 if (!"Bitvector".equals(value.getReferenceTypeName()))
112                         throw new DebugException(new Status(SWT.ERROR, MograsimActivator.PLUGIN_ID, ""));
113                 setValue(value.getValueString());
114         }
115
116         @Override
117         public boolean supportsValueModification()
118         {
119                 return true;
120         }
121
122         @Override
123         public boolean verifyValue(String expression) throws DebugException
124         {
125                 // TODO do this prettier; also check length too
126                 try
127                 {
128                         BitVector.parse(expression);
129                 }
130                 catch (@SuppressWarnings("unused") Exception e)
131                 {
132                         return false;
133                 }
134                 return true;
135         }
136
137         @Override
138         public boolean verifyValue(IValue value) throws DebugException
139         {
140                 return verifyValue(value.getValueString());
141         }
142
143         @Override
144         public IRegisterGroup getRegisterGroup() throws DebugException
145         {
146                 return registerGroup;
147         }
148
149         /**
150          * Fires a change event for this debug element.
151          */
152         private void fireChangeEvent()
153         {
154                 fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
155         }
156
157         /**
158          * Fires a debug event.
159          *
160          * @param event debug event to fire
161          */
162         private static void fireEvent(DebugEvent event)
163         {
164                 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
165         }
166 }