/*******************************************************************************
* Copyright (c) 2016 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch;
import java.util.List;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.StackFramesVMNode;
import org.eclipse.cdt.dsf.gdb.internal.service.IGDBFocusSynchronizer.IGDBFocusChangedEvent;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
public class GdbStackFramesVMNode extends StackFramesVMNode {
public GdbStackFramesVMNode(AbstractDMVMProvider provider, DsfSession session) {
super(provider, session);
}
@Override
public int getDeltaFlags(Object e) {
if (e instanceof IGDBFocusChangedEvent) {
return IModelDelta.SELECT;
}
return super.getDeltaFlags(e);
}
@Override
public void buildDelta(final Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) {
if (e instanceof IGDBFocusChangedEvent) {
buildDeltaForFocusChangedEvent((IGDBFocusChangedEvent)e, parentDelta, rm);
}
else {
super.buildDelta(e, parentDelta, nodeOffset, rm);
}
}
private void buildDeltaForFocusChangedEvent(IGDBFocusChangedEvent event, VMDelta parentDelta, RequestMonitor rm) {
getSession().getExecutor().execute(new Runnable() {
@Override
public void run() {
IDMContext ctx = event.getDMContext();
// Is IGDBFocusChangedEvent pertinent for this VMNode?
if (ctx instanceof IFrameDMContext) {
IFrameDMContext newFrameFocus = (IFrameDMContext)ctx;
IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(newFrameFocus, IMIExecutionDMContext.class);
if (execDmc == null) {
rm.done();
return;
}
IRunControl runControl = getServicesTracker().getService(IRunControl.class);
if (runControl == null) {
// Required services have not initialized yet. Ignore the event.
rm.done();
return;
}
if (runControl.isSuspended(execDmc) || runControl.isStepping(execDmc)) {
// find the VMC index for the frame that switched, so we can select it correctly.
getVMCIndexForDmc(
GdbStackFramesVMNode.this,
newFrameFocus,
parentDelta,
new DataRequestMonitor<Integer>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
// change to frameOffset
final int frameOffset = getData();
// Retrieve the list of stack frames
getVMProvider().updateNode(GdbStackFramesVMNode.this,
new VMChildrenUpdate(parentDelta,
getVMProvider().getPresentationContext(), -1,
-1, new DataRequestMonitor<List<Object>>(
getExecutor(), rm) {
@Override
public void handleSuccess() {
final List<Object> data = getData();
if (data != null && data.size() != 0) {
// create the delta to select the
// current stack frame
parentDelta.addNode(
data.get(frameOffset),
frameOffset,
IModelDelta.SELECT | IModelDelta.FORCE
);
}
rm.done();
}
}));
}
});
} else {
// thread is running - no delta to produce for the stack frame node
rm.done();
}
} else {
// context not a frame - nothing to do here
rm.done();
}
}
});
}
}