blob: de56eaa9d7d78872fc9762d4d1ba380d1b631a1e [file] [log] [blame]
package org.eclipse.dltk.internal.debug.core.model;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.dltk.dbgp.IDbgpStatus;
import org.eclipse.dltk.dbgp.exceptions.DbgpException;
import org.eclipse.dltk.internal.debug.core.model.operations.DbgpDebugger;
import org.eclipse.dltk.internal.debug.core.model.operations.IDbgpDebuggerFeedback;
public class ScriptThreadStateManager implements IDbgpDebuggerFeedback {
public static interface IStateChangeHandler {
void handleSuspend(int detail);
void handleResume(int detail);
void handleTermination(DbgpException e);
}
private IStateChangeHandler handler;
private final DbgpDebugger engine;
// Abilities of debugging engine
private boolean canSuspend;
// Number of suspends
private int suspendCount;
// States
private boolean stepping;
private boolean suspended;
private boolean terminated;
protected void handleStatus(DbgpException exception, IDbgpStatus status,
int suspendDetail) {
if (exception != null) {
setTerminated(exception);
}
if( status == null ) {
setTerminated(null);
return;
}
if (status.isBreak()) {
setSuspended(true, suspendDetail);
} else if (status.isStopping()) {
// Temporary solution!
try {
terminate();
} catch (DebugException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (status.isStopped()) {
setTerminated(null);
}
}
// State management
protected void setSuspended(boolean value, int detail) {
suspended = value;
if (value) {
++suspendCount;
}
if (value) {
handler.handleSuspend(detail);
} else {
handler.handleResume(detail);
}
}
private void setTerminated(DbgpException e) {
terminated = true;
handler.handleTermination(e);
}
private boolean canStep() {
return !terminated && suspended;
}
private void beginStep(int detail) {
stepping = true;
setSuspended(false, detail);
}
private void endStep(DbgpException execption, IDbgpStatus status) {
stepping = false;
handleStatus(execption, status, DebugEvent.STEP_END);
}
public ScriptThreadStateManager(ScriptThread thread) {
this.handler = thread;
this.engine = new DbgpDebugger(thread, this);
canSuspend = true; // engine.isSupportsAsync();
this.suspendCount = 0;
this.suspended = true;
this.terminated = false;
this.stepping = this.suspended;
}
public DbgpDebugger getEngine() {
return engine;
}
// Stepping
public boolean isStepping() {
return !terminated && stepping;
}
// StepInto
public boolean canStepInto() {
return canStep();
}
public void endStepInto(DbgpException e, IDbgpStatus status) {
endStep(e, status);
}
public void stepInto() throws DebugException {
beginStep(DebugEvent.STEP_INTO);
engine.stepInto();
}
// StepOver
public boolean canStepOver() {
return canStep();
}
public void endStepOver(DbgpException e, IDbgpStatus status) {
endStep(e, status);
}
public void stepOver() throws DebugException {
beginStep(DebugEvent.STEP_OVER);
engine.stepOver();
}
// StepReturn
public boolean canStepReturn() {
return canStep();
}
public void endStepReturn(DbgpException e, IDbgpStatus status) {
endStep(e, status);
}
public void stepReturn() throws DebugException {
beginStep(DebugEvent.STEP_RETURN);
engine.stepReturn();
}
// Suspend
public boolean isSuspended() {
return suspended;
}
public boolean canSuspend() {
return canSuspend && !terminated && !suspended;
}
public void endSuspend(DbgpException e, IDbgpStatus status) {
handleStatus(e, status, DebugEvent.CLIENT_REQUEST);
}
public void suspend() throws DebugException {
setSuspended(true, DebugEvent.CLIENT_REQUEST);
engine.suspend();
}
public int getSuspendCount() {
return suspendCount;
}
// Resume
public boolean canResume() {
return !terminated && suspended;
}
public void endResume(DbgpException e, IDbgpStatus status) {
handleStatus(e, status, DebugEvent.BREAKPOINT);
}
public void resume() throws DebugException {
setSuspended(false, DebugEvent.CLIENT_REQUEST);
engine.resume();
}
// Terminate
public boolean isTerminated() {
return terminated;
}
public boolean canTerminate() {
return !terminated;
}
public void endTerminate(DbgpException e, IDbgpStatus status) {
handleStatus(e, status, DebugEvent.CLIENT_REQUEST);
}
public void terminate() throws DebugException {
engine.terminate();
}
}