package jetbrains.mps.debug.api; /*Generated by MPS */ import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import org.jetbrains.annotations.Nullable; import jetbrains.mps.debug.api.programState.IThread; import org.jetbrains.annotations.NotNull; import java.util.List; import jetbrains.mps.debug.api.programState.IStackFrame; import java.util.Collections; import jetbrains.mps.debug.api.programState.IWatchable; import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes; import com.intellij.openapi.application.ApplicationManager; import org.apache.log4j.Level; public abstract class AbstractUiState { private static final Logger LOG = LogManager.getLogger(AbstractUiState.class); protected static final int NO_FRAME = -1; protected final AbstractDebugSession myAbstractDebugSession; protected AbstractUiState(AbstractDebugSession session) { myAbstractDebugSession = session; } @Nullable public abstract IThread getThread(); @NotNull public abstract List<? extends IThread> getThreads(); @Nullable public abstract IStackFrame getStackFrame(); public abstract boolean isPausedOnBreakpoint(); protected abstract AbstractUiState selectThreadInternal(@Nullable IThread thread); protected abstract AbstractUiState selectFrameInternal(int frame); protected int findStackFrameIndex() { IThread thread = getThread(); if (thread == null) { return NO_FRAME; } if (thread.getFramesCount() > 0) { return myAbstractDebugSession.getDebuggableFramesSelector().findDeepestDebuggableFrameIndex(thread.getFrames()); } return NO_FRAME; } public void selectThread(@Nullable IThread thread) { AbstractUiState newState = selectThreadInternal(thread); if (newState != this) { myAbstractDebugSession.trySetState(this, newState); } } public void selectFrame(int frame) { AbstractUiState newState = selectFrameInternal(frame); if (newState != this) { myAbstractDebugSession.trySetState(this, newState); } } @NotNull public List<IStackFrame> getStackFrames() { IThread thread = getThread(); if (thread != null) { return thread.getFrames(); } return Collections.emptyList(); } public int getStackFramesCount() { IThread thread = getThread(); if (thread != null) { return thread.getFramesCount(); } return 0; } @Nullable public IStackFrame getStackFrame(int index) { assert index >= 0; List<IStackFrame> frames = getStackFrames(); if (index >= frames.size()) { return null; } return frames.get(index); } @NotNull public List<IWatchable> getWatchables() { IStackFrame stackFrame = getStackFrame(); if (stackFrame != null) { return stackFrame.getVisibleWatchables(); } return Collections.emptyList(); } /** * It it a fact that we can not run evaluation (i.e. whatever code that executes something on virtual machine under debug) in EDT since it can and will slow down or even freeze ui. * And we also should have a list of threads on the virtual machine that do evaluation in order to skip events from them in the vm manager thread * (like when we are evaluating a method we should not stop on breakpoints in it). * So we need to have a special way to evaluate and here it is. * * Default implementation just sends a given command to a thread from thread pull (thanks, captain). * Custom debugger implelemntation may create their own special thread for that. */ public void invokeEvaluation(final _FunctionTypes._void_P0_E0 command) { ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { public void run() { try { command.invoke(); } catch (Throwable t) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("", t); } } } }); } }