Highlighting Instructions is now based on the selected DebugTarget
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / launch / MachineDebugTarget.java
index 357fe82..03fe7fd 100644 (file)
@@ -1,6 +1,8 @@
 package net.mograsim.plugin.launch;
 
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
 
 import org.eclipse.core.resources.IMarkerDelta;
 import org.eclipse.core.runtime.IStatus;
@@ -21,34 +23,35 @@ import org.eclipse.debug.core.model.IProcess;
 import org.eclipse.debug.core.model.IStepFilters;
 import org.eclipse.debug.core.model.IThread;
 
+import net.mograsim.logic.model.LogicExecuter;
 import net.mograsim.machine.Machine;
+import net.mograsim.machine.MachineDefinition;
 import net.mograsim.plugin.MograsimActivator;
+import net.mograsim.plugin.launch.MachineLaunchConfigType.MachineLaunchParams;
 
 public class MachineDebugTarget extends PlatformObject implements IDebugTarget, IMemoryBlockRetrievalExtension
 {
-       private final MachineProcess process;
+       private final ILaunch launch;
+       private final Machine machine;
+       private final LogicExecuter exec;
 
-       public MachineDebugTarget(MachineProcess process)
+       private boolean running;
+
+       private final List<Consumer<Double>> executionSpeedListeners;
+
+       private final MachineLaunchParams launchParams;
+
+       public MachineDebugTarget(ILaunch launch, MachineLaunchParams launchParams, MachineDefinition machineDefinition)
        {
-               this.process = process;
+               this.launch = launch;
+               this.machine = machineDefinition.createNew();
+               this.exec = new LogicExecuter(machine.getTimeline());
 
-               DebugPlugin.getDefault().addDebugEventListener(es -> Arrays.stream(es).filter(e -> e.getSource() == process).forEach(e ->
-               {
-                       switch (e.getKind())
-                       {
-                       case DebugEvent.RESUME:
-                               fireResumeEvent(e.getDetail());
-                               break;
-                       case DebugEvent.SUSPEND:
-                               fireSuspendEvent(e.getDetail());
-                               break;
-                       case DebugEvent.TERMINATE:
-                               fireTerminateEvent();
-                               break;
-                       default:
-                               // ignore
-                       }
-               }));
+               this.executionSpeedListeners = new ArrayList<>();
+               this.launchParams = launchParams;
+
+               exec.startLiveExecution();
+               running = true;
 
                getLaunch().addDebugTarget(this);
                fireCreationEvent();
@@ -56,13 +59,13 @@ public class MachineDebugTarget extends PlatformObject implements IDebugTarget,
 
        public Machine getMachine()
        {
-               return process.getMachine();
+               return machine;
        }
 
        @Override
        public String getName() throws DebugException
        {
-               return process.getName();
+               return "Mograsim machine \"" + machine.getDefinition().getId() + '"';
        }
 
        @Override
@@ -80,60 +83,91 @@ public class MachineDebugTarget extends PlatformObject implements IDebugTarget,
        @Override
        public ILaunch getLaunch()
        {
-               return process.getLaunch();
+               return launch;
+       }
+
+       public MachineLaunchParams getLaunchParams()
+       {
+               return launchParams;
+       }
+
+       public double getExecutionSpeed()
+       {
+               return exec.getSpeedFactor();
        }
 
        public void setExecutionSpeed(double speed)
        {
-               process.setExecutionSpeed(speed);
+               if (getExecutionSpeed() != speed)
+               {
+                       exec.setSpeedFactor(speed);
+                       callExecutionSpeedListener(speed);
+               }
        }
 
        @Override
        public boolean isSuspended()
        {
-               return process.isSuspended();
+               return exec.isPaused();
        }
 
        @Override
        public boolean canSuspend()
        {
-               return process.canSuspend();
+               return !isTerminated() && !isSuspended();
        }
 
        @Override
        public void suspend() throws DebugException
        {
-               process.suspend();
+               if (isTerminated())
+                       throwDebugException("Can't suspend a terminated MachineProcess");
+               if (isSuspended())
+                       throwDebugException("Can't suspend a suspended MachineProcess");
+
+               exec.pauseLiveExecution();
+               fireSuspendEvent(DebugEvent.CLIENT_REQUEST);
        }
 
        @Override
        public boolean canResume()
        {
-               return process.canResume();
+               return !isTerminated() && isSuspended();
        }
 
        @Override
        public void resume() throws DebugException
        {
-               process.resume();
+               if (isTerminated())
+                       throwDebugException("Can't resume a terminated MachineProcess");
+               if (!isSuspended())
+                       throwDebugException("Can't resume a non-suspended MachineProcess");
+
+               exec.unpauseLiveExecution();
+               fireResumeEvent(DebugEvent.CLIENT_REQUEST);
        }
 
        @Override
        public boolean isTerminated()
        {
-               return process.isTerminated();
+               return !running;
        }
 
        @Override
        public boolean canTerminate()
        {
-               return process.canTerminate();
+               return !isTerminated();
        }
 
        @Override
        public void terminate() throws DebugException
        {
-               process.terminate();
+               if (isTerminated())
+                       return;
+
+               exec.stopLiveExecution();
+               running = false;
+               fireTerminateEvent();
        }
 
        @Override
@@ -199,9 +233,9 @@ public class MachineDebugTarget extends PlatformObject implements IDebugTarget,
        }
 
        @Override
-       public MachineProcess getProcess()
+       public IProcess getProcess()
        {
-               return process;
+               return null;
        }
 
        @Override
@@ -216,6 +250,21 @@ public class MachineDebugTarget extends PlatformObject implements IDebugTarget,
                return new IThread[0];
        }
 
+       public void addExecutionSpeedListener(Consumer<Double> executionSpeedListener)
+       {
+               executionSpeedListeners.add(executionSpeedListener);
+       }
+
+       public void removeExecutionSpeedListener(Consumer<Double> executionSpeedListener)
+       {
+               executionSpeedListeners.remove(executionSpeedListener);
+       }
+
+       private void callExecutionSpeedListener(double executionSpeed)
+       {
+               executionSpeedListeners.forEach(l -> l.accept(executionSpeed));
+       }
+
        @SuppressWarnings("unchecked")
        @Override
        public <T> T getAdapter(Class<T> adapter)
@@ -234,9 +283,6 @@ public class MachineDebugTarget extends PlatformObject implements IDebugTarget,
                if (adapter == ILaunch.class)
                        return (T) getLaunch();
 
-               if (adapter == IProcess.class)
-                       return (T) getProcess();
-
                // CONTEXTLAUNCHING
                if (adapter == ILaunchConfiguration.class)
                        return (T) getLaunch().getLaunchConfiguration();
@@ -289,4 +335,10 @@ public class MachineDebugTarget extends PlatformObject implements IDebugTarget,
        {
                DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
        }
+
+       private static void throwDebugException(String message) throws DebugException
+       {
+               throw new DebugException(
+                               new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, message, null));
+       }
 }
\ No newline at end of file