mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-03 07:05:24 +02:00
[179102] Added logic to handle ModelProxyInstalledEvent. This logic now selects the top stack frame when the debug view is first opened.
This commit is contained in:
parent
c61de9929c
commit
a12a4967e3
13 changed files with 362 additions and 207 deletions
|
@ -70,7 +70,7 @@ public class LaunchRootVMNode extends RootVMNode
|
|||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return super.isDeltaEvent(rootObject, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
|||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||
|
@ -30,6 +30,7 @@ import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
|
|||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.ModelProxyInstalledEvent;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode;
|
||||
|
@ -118,31 +119,39 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
return;
|
||||
}
|
||||
|
||||
getServicesTracker().getService(IStack.class).getTopFrame(
|
||||
execDmc,
|
||||
new DataRequestMonitor<IFrameDMContext>(getExecutor(), null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!getStatus().isOK()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
IVMContext topFrameVmc = createVMContext(getData());
|
||||
|
||||
update.setChild(topFrameVmc, 0);
|
||||
// If there are old frames cached, use them and only substitute the top frame object. Otherwise, create
|
||||
// an array of VMCs with just the top frame.
|
||||
if (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) {
|
||||
fCachedOldFrameVMCs[0] = topFrameVmc;
|
||||
for (int i = 0; i < fCachedOldFrameVMCs.length; i++)
|
||||
update.setChild(fCachedOldFrameVMCs[i], i);
|
||||
} else {
|
||||
update.setChild(topFrameVmc, 0);
|
||||
}
|
||||
update.done();
|
||||
try {
|
||||
getSession().getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
getServicesTracker().getService(IStack.class).getTopFrame(
|
||||
execDmc,
|
||||
new DataRequestMonitor<IFrameDMContext>(getExecutor(), null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!getStatus().isOK()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
IVMContext topFrameVmc = createVMContext(getData());
|
||||
|
||||
update.setChild(topFrameVmc, 0);
|
||||
// If there are old frames cached, use them and only substitute the top frame object. Otherwise, create
|
||||
// an array of VMCs with just the top frame.
|
||||
if (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) {
|
||||
fCachedOldFrameVMCs[0] = topFrameVmc;
|
||||
for (int i = 0; i < fCachedOldFrameVMCs.length; i++)
|
||||
update.setChild(fCachedOldFrameVMCs[i], i);
|
||||
} else {
|
||||
update.setChild(topFrameVmc, 0);
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException e) {
|
||||
update.done();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -209,7 +218,7 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
|
||||
final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class);
|
||||
IRunControl runControlService = getServicesTracker().getService(IRunControl.class);
|
||||
IStepQueueManager stepQueueMgrService = getServicesTracker().getService(IStepQueueManager.class);
|
||||
StepQueueManager stepQueueMgrService = getServicesTracker().getService(StepQueueManager.class);
|
||||
if (execDmc == null || runControlService == null || stepQueueMgrService == null) return;
|
||||
|
||||
String imageKey = null;
|
||||
|
@ -271,6 +280,31 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void getContextsForEvent(final VMDelta parentDelta, Object e, final DataRequestMonitor<IVMContext[]> rm) {
|
||||
if (e instanceof ModelProxyInstalledEvent) {
|
||||
// Retrieve the list of stack frames, and mark the top frame to be selected.
|
||||
getElementsTopStackFrameOnly(
|
||||
new VMChildrenUpdate(
|
||||
parentDelta, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getExecutor(), null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (getStatus().isOK() && getData().size() != 0) {
|
||||
rm.setData(new IVMContext[] { (IVMContext)getData().get(0) });
|
||||
} else {
|
||||
// In case of errors, return an empty set of frames.
|
||||
rm.setData(new IVMContext[0]);
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
super.getContextsForEvent(parentDelta, e, rm);
|
||||
}
|
||||
|
||||
public int getDeltaFlags(Object e) {
|
||||
// This node generates delta if the timers have changed, or if the
|
||||
// label has changed.
|
||||
|
@ -282,9 +316,12 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
} else {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
} else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) {
|
||||
} else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (e instanceof ModelProxyInstalledEvent) {
|
||||
return IModelDelta.SELECT | IModelDelta.EXPAND;
|
||||
}
|
||||
|
||||
return IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
||||
|
@ -300,8 +337,10 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, execDmc, execDmc, parent, nodeOffset, rm);
|
||||
} else if (e instanceof IResumedDMEvent) {
|
||||
buildDeltaForResumedEvent((IResumedDMEvent)e, parent, nodeOffset, rm);
|
||||
} else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) {
|
||||
buildDeltaForSteppingTimedOutEvent((IStepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm);
|
||||
} else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
|
||||
buildDeltaForSteppingTimedOutEvent((StepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm);
|
||||
} else if (e instanceof ModelProxyInstalledEvent) {
|
||||
buildDeltaForModelProxyInstalledEvent(parent, nodeOffset, rm);
|
||||
} else {
|
||||
rm.done();
|
||||
}
|
||||
|
@ -372,9 +411,27 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
rm.done();
|
||||
}
|
||||
|
||||
private void buildDeltaForSteppingTimedOutEvent(final IStepQueueManager.ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) {
|
||||
private void buildDeltaForSteppingTimedOutEvent(final StepQueueManager.ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) {
|
||||
// Repaint the stack frame images to have the running symbol.
|
||||
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
||||
rm.done();
|
||||
}
|
||||
|
||||
private void buildDeltaForModelProxyInstalledEvent(final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) {
|
||||
// Retrieve the list of stack frames, and mark the top frame to be selected.
|
||||
getElementsTopStackFrameOnly(
|
||||
new VMChildrenUpdate(
|
||||
parentDelta, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getExecutor(), null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (getStatus().isOK() && getData().size() != 0) {
|
||||
parentDelta.addNode( getData().get(0), 0, IModelDelta.SELECT | IModelDelta.EXPAND);
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,7 +10,12 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.ui.viewmodel;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.dd.dsf.ui.DsfUIPlugin;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
|
||||
|
@ -46,8 +51,9 @@ abstract public class AbstractVMNode implements IVMNode {
|
|||
fDisposed = true;
|
||||
}
|
||||
|
||||
public IVMContext getContextFromEvent(Object event) {
|
||||
return null;
|
||||
public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor<IVMContext[]> rm) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
|
||||
protected boolean isDisposed() {
|
||||
|
|
|
@ -322,7 +322,7 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
* overrides this method to optionally return the results for an update from
|
||||
* a cache.
|
||||
*/
|
||||
protected void updateNode(final IVMNode node, IHasChildrenUpdate[] updates) {
|
||||
public void updateNode(final IVMNode node, IHasChildrenUpdate[] updates) {
|
||||
IHasChildrenUpdate[] updateProxies = new IHasChildrenUpdate[updates.length];
|
||||
for (int i = 0; i < updates.length; i++) {
|
||||
final IHasChildrenUpdate update = updates[i];
|
||||
|
@ -340,7 +340,7 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) {
|
||||
updateNode(
|
||||
node,
|
||||
new VMChildrenUpdate[] { new VMChildrenUpdate(
|
||||
new VMChildrenUpdate(
|
||||
update, -1, -1,
|
||||
new ViewerDataRequestMonitor<List<Object>>(getExecutor(), update) {
|
||||
@Override
|
||||
|
@ -349,7 +349,7 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
update.done();
|
||||
}
|
||||
})
|
||||
});
|
||||
);
|
||||
|
||||
} else {
|
||||
update.setStatus(getStatus());
|
||||
|
@ -370,13 +370,11 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
* overrides this method to optionally return the results for an update from
|
||||
* a cache.
|
||||
*/
|
||||
protected void updateNode(final IVMNode node, IChildrenCountUpdate[] updates) {
|
||||
IChildrenCountUpdate[] updateProxies = new IChildrenCountUpdate[updates.length];
|
||||
for (int i = 0; i < updates.length; i++) {
|
||||
final IChildrenCountUpdate update = updates[i];
|
||||
updateProxies[i] = new VMChildrenCountUpdate(
|
||||
public void updateNode(final IVMNode node, final IChildrenCountUpdate update) {
|
||||
node.update(new IChildrenCountUpdate[] {
|
||||
new VMChildrenCountUpdate(
|
||||
update,
|
||||
new ViewerDataRequestMonitor<Integer>(getExecutor(), updates[i]) {
|
||||
new ViewerDataRequestMonitor<Integer>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
update.setChildCount(getData());
|
||||
|
@ -388,7 +386,7 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) {
|
||||
updateNode(
|
||||
node,
|
||||
new VMChildrenUpdate[] { new VMChildrenUpdate(
|
||||
new VMChildrenUpdate(
|
||||
update, -1, -1,
|
||||
new ViewerDataRequestMonitor<List<Object>>(getExecutor(), update) {
|
||||
@Override
|
||||
|
@ -397,14 +395,13 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
update.done();
|
||||
}
|
||||
})
|
||||
});
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
node.update(updateProxies);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -415,8 +412,8 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
* overrides this method to optionally return the results for an update from
|
||||
* a cache.
|
||||
*/
|
||||
protected void updateNode(IVMNode node, IChildrenUpdate[] updates) {
|
||||
node.update(updates);
|
||||
public void updateNode(IVMNode node, IChildrenUpdate update) {
|
||||
node.update(new IChildrenUpdate[] { update });
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
|
|||
update.setChildCount(0);
|
||||
update.done();
|
||||
} else if (childNodes.length == 1) {
|
||||
getVMProvider().updateNode(childNodes[0], new IChildrenCountUpdate[] { update } );
|
||||
getVMProvider().updateNode(childNodes[0], update);
|
||||
} else {
|
||||
getChildrenCountsForNode(
|
||||
update,
|
||||
|
@ -208,7 +208,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
|
|||
// Invalid update, just mark done.
|
||||
update.done();
|
||||
} else if (childNodes.length == 1) {
|
||||
getVMProvider().updateNode(childNodes[0], new IChildrenUpdate[] { update });
|
||||
getVMProvider().updateNode(childNodes[0], update);
|
||||
} else {
|
||||
getChildrenCountsForNode(
|
||||
update,
|
||||
|
@ -261,23 +261,22 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
|
|||
final int nodeIndex = i;
|
||||
getVMProvider().updateNode(
|
||||
childNodes[i],
|
||||
new IChildrenCountUpdate[] {
|
||||
new VMChildrenCountUpdate(
|
||||
update,
|
||||
childrenCountMultiReqMon.add(
|
||||
new DataRequestMonitor<Integer>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
counts[nodeIndex] = getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
super.handleCompleted();
|
||||
childrenCountMultiReqMon.requestMonitorDone(this);
|
||||
}
|
||||
}))
|
||||
});
|
||||
new VMChildrenCountUpdate(
|
||||
update,
|
||||
childrenCountMultiReqMon.add(
|
||||
new DataRequestMonitor<Integer>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
counts[nodeIndex] = getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
super.handleCompleted();
|
||||
childrenCountMultiReqMon.requestMonitorDone(this);
|
||||
}
|
||||
}))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,21 +314,19 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
|
|||
if (elementsLength > 0) {
|
||||
getVMProvider().updateNode(
|
||||
nodes[i],
|
||||
new IChildrenUpdate[] {
|
||||
new VMChildrenUpdate(
|
||||
update, elementsStartIdx, elementsLength,
|
||||
elementsMultiRequestMon.add(new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (getStatus().isOK()) {
|
||||
for (int i = 0; i < elementsLength; i++) {
|
||||
update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i);
|
||||
}
|
||||
new VMChildrenUpdate(
|
||||
update, elementsStartIdx, elementsLength,
|
||||
elementsMultiRequestMon.add(new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (getStatus().isOK()) {
|
||||
for (int i = 0; i < elementsLength; i++) {
|
||||
update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i);
|
||||
}
|
||||
elementsMultiRequestMon.requestMonitorDone(this);
|
||||
}
|
||||
}))
|
||||
}
|
||||
elementsMultiRequestMon.requestMonitorDone(this);
|
||||
}
|
||||
}))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,8 @@ import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
|
|||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.debug.internal.ui.DebugUIPlugin;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
|
||||
|
@ -182,6 +181,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
*/
|
||||
public void installed(Viewer viewer) {
|
||||
fViewer = viewer;
|
||||
fProvider.handleEvent(new ModelProxyInstalledEvent(this, viewer, fRootElement));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -262,8 +262,8 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
|
||||
// If no child nodes have deltas we can stop here.
|
||||
if (childNodesWithDeltaFlags.size() == 0) {
|
||||
rm.done();
|
||||
rm.setData(viewRootDelta);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -284,19 +284,26 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
protected void buildChildDeltas(final IVMNode node, final Object event, final VMDelta parentDelta,
|
||||
final int nodeOffset, final RequestMonitor rm)
|
||||
{
|
||||
final IVMContext vmc = node.getContextFromEvent(event);
|
||||
|
||||
if (vmc != null) {
|
||||
buildChildDeltasForEventContext(vmc, node, event, parentDelta, nodeOffset, rm);
|
||||
} else {
|
||||
// The DMC for this node was not found in the event. Call the
|
||||
// super-class to resort to the default behavior which may add a
|
||||
// delta for every element in this node.
|
||||
buildChildDeltasForAllContexts(node, event, parentDelta, nodeOffset, rm);
|
||||
}
|
||||
node.getContextsForEvent(
|
||||
parentDelta,
|
||||
event,
|
||||
new DataRequestMonitor<IVMContext[]>(getVMProvider().getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (getStatus().isOK()) {
|
||||
assert getData() != null;
|
||||
buildChildDeltasForEventContext(getData(), node, event, parentDelta, nodeOffset, rm);
|
||||
} else if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) {
|
||||
// The DMC for this node was not found in the event. Call the
|
||||
// super-class to resort to the default behavior which may add a
|
||||
// delta for every element in this node.
|
||||
buildChildDeltasForAllContexts(node, event, parentDelta, nodeOffset, rm);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void buildChildDeltasForEventContext(final IVMContext vmc, final IVMNode node, final Object event,
|
||||
protected void buildChildDeltasForEventContext(final IVMContext[] vmcs, final IVMNode node, final Object event,
|
||||
final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor)
|
||||
{
|
||||
final Map<IVMNode,Integer> childNodeDeltas = getChildNodesWithDeltaFlags(node, parentDelta, event);
|
||||
|
@ -324,31 +331,34 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
// elements and then finding the DMC that the event is for.
|
||||
getVMProvider().updateNode(
|
||||
node,
|
||||
new IChildrenUpdate[] {
|
||||
new VMChildrenUpdate(
|
||||
parentDelta, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isDisposed()) return;
|
||||
|
||||
// Check for an empty list of elements. If it's empty then we
|
||||
// don't have to call the children nodes, so return here.
|
||||
// No need to propagate error, there's no means or need to display it.
|
||||
if (!getStatus().isOK() || getData().isEmpty()) {
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the index.
|
||||
new VMChildrenUpdate(
|
||||
parentDelta, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isDisposed()) return;
|
||||
|
||||
// Check for an empty list of elements. If it's empty then we
|
||||
// don't have to call the children nodes, so return here.
|
||||
// No need to propagate error, there's no means or need to display it.
|
||||
if (!getStatus().isOK() || getData().isEmpty()) {
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
||||
CountingRequestMonitor countingRm =
|
||||
new CountingRequestMonitor(getVMProvider().getExecutor(), requestMonitor);
|
||||
|
||||
int count = 0;
|
||||
for (IVMContext vmc : vmcs) {
|
||||
// Find the index of the vmc in the full list of elements.
|
||||
int i;
|
||||
for (i = 0; i < getData().size(); i++) {
|
||||
if (vmc.equals(getData().get(i))) break;
|
||||
}
|
||||
if (i == getData().size()) {
|
||||
// Element not found, no need to generate the delta.
|
||||
requestMonitor.done();
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Optimization: Try to find a delta with a matching element, if found use it.
|
||||
|
@ -359,18 +369,27 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
delta = parentDelta.addNode(vmc, elementIndex, IModelDelta.NO_CHANGE);
|
||||
}
|
||||
|
||||
callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, requestMonitor);
|
||||
callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, countingRm);
|
||||
count++;
|
||||
}
|
||||
})
|
||||
});
|
||||
countingRm.setDoneCount(count);
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
// Optimization: Try to find a delta with a matching element, if found use it.
|
||||
// Otherwise create a new delta for the event element.
|
||||
VMDelta delta = (VMDelta)parentDelta.getChildDelta(vmc);
|
||||
if (delta == null) {
|
||||
delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE);
|
||||
CountingRequestMonitor countingRm =
|
||||
new CountingRequestMonitor(getVMProvider().getExecutor(), requestMonitor);
|
||||
int count = 0;
|
||||
for (IVMContext vmc : vmcs) {
|
||||
// Optimization: Try to find a delta with a matching element, if found use it.
|
||||
// Otherwise create a new delta for the event element.
|
||||
VMDelta delta = (VMDelta)parentDelta.getChildDelta(vmc);
|
||||
if (delta == null) {
|
||||
delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE);
|
||||
}
|
||||
callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, requestMonitor);
|
||||
count++;
|
||||
}
|
||||
callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, requestMonitor);
|
||||
countingRm.setDoneCount(count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,49 +433,48 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
// each element as the parent of their delta.
|
||||
getVMProvider().updateNode(
|
||||
node,
|
||||
new IChildrenUpdate[] {
|
||||
new VMChildrenUpdate(
|
||||
parentDelta, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (fDisposed) return;
|
||||
|
||||
// Check for an empty list of elements. If it's empty then we
|
||||
// don't have to call the children nodes, so return here.
|
||||
// No need to propagate error, there's no means or need to display it.
|
||||
if (!getStatus().isOK() || getData().size() == 0) {
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
||||
final MultiRequestMonitor<RequestMonitor> elementsDeltasMultiRequestMon =
|
||||
new MultiRequestMonitor<RequestMonitor>(getVMProvider().getExecutor(), null) {
|
||||
new VMChildrenUpdate(
|
||||
parentDelta, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (fDisposed) return;
|
||||
|
||||
// Check for an empty list of elements. If it's empty then we
|
||||
// don't have to call the children nodes, so return here.
|
||||
// No need to propagate error, there's no means or need to display it.
|
||||
if (!getStatus().isOK() || getData().size() == 0) {
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
||||
final MultiRequestMonitor<RequestMonitor> elementsDeltasMultiRequestMon =
|
||||
new MultiRequestMonitor<RequestMonitor>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isDisposed()) return;
|
||||
requestMonitor.done();
|
||||
}
|
||||
};
|
||||
|
||||
// For each element from this node, create a new delta,
|
||||
// and then call all the child nodes to build their delta.
|
||||
for (int i = 0; i < getData().size(); i++) {
|
||||
int elementIndex = nodeOffset >= 0 ? nodeOffset + i : -1;
|
||||
VMDelta delta =
|
||||
parentDelta.addNode(getData().get(i), elementIndex, IModelDelta.NO_CHANGE);
|
||||
callChildNodesToBuildDelta(
|
||||
node, childNodesWithDeltaFlags, delta, event,
|
||||
elementsDeltasMultiRequestMon.add(new RequestMonitor(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isDisposed()) return;
|
||||
requestMonitor.done();
|
||||
elementsDeltasMultiRequestMon.requestMonitorDone(this);
|
||||
}
|
||||
};
|
||||
|
||||
// For each element from this node, create a new delta,
|
||||
// and then call all the child nodes to build their delta.
|
||||
for (int i = 0; i < getData().size(); i++) {
|
||||
int elementIndex = nodeOffset >= 0 ? nodeOffset + i : -1;
|
||||
VMDelta delta =
|
||||
parentDelta.addNode(getData().get(i), elementIndex, IModelDelta.NO_CHANGE);
|
||||
callChildNodesToBuildDelta(
|
||||
node, childNodesWithDeltaFlags, delta, event,
|
||||
elementsDeltasMultiRequestMon.add(new RequestMonitor(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
elementsDeltasMultiRequestMon.requestMonitorDone(this);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}));
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -568,19 +586,18 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
final int nodeIndex = i;
|
||||
getVMProvider().updateNode(
|
||||
childNodes[i],
|
||||
new IChildrenCountUpdate[] {
|
||||
new VMChildrenCountUpdate(
|
||||
delta, getVMProvider().getPresentationContext(),
|
||||
childrenCountMultiRequestMon.add(
|
||||
new DataRequestMonitor<Integer>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
counts[nodeIndex] = getData();
|
||||
childrenCountMultiRequestMon.requestMonitorDone(this);
|
||||
}
|
||||
})
|
||||
)
|
||||
});
|
||||
new VMChildrenCountUpdate(
|
||||
delta, getVMProvider().getPresentationContext(),
|
||||
childrenCountMultiRequestMon.add(
|
||||
new DataRequestMonitor<Integer>(getVMProvider().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
counts[nodeIndex] = getData();
|
||||
childrenCountMultiRequestMon.requestMonitorDone(this);
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
Map<IVMNode, Integer> data = new HashMap<IVMNode, Integer>();
|
||||
|
|
|
@ -15,17 +15,32 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
|||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
|
||||
|
||||
/**
|
||||
*
|
||||
* View Model extension to the platform IModelProxy interface. This extension
|
||||
* allows the IVMProvider implementation to delegate the model proxy implementation
|
||||
* into a separate object.
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public interface IVMModelProxy extends IModelProxy {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the root element that this model proxy was created for.
|
||||
*/
|
||||
public Object getRootElement();
|
||||
|
||||
/**
|
||||
* Returns whether the given event applies to the root element and the
|
||||
* nodes in this model proxy.
|
||||
*/
|
||||
public boolean isDeltaEvent(Object event);
|
||||
|
||||
/**
|
||||
* Creates a model delta for the given event.
|
||||
*/
|
||||
public void createDelta(final Object event, final DataRequestMonitor<IModelDelta> rm);
|
||||
|
||||
/**
|
||||
* Sends the given delta to this model proxy's listeners.
|
||||
*/
|
||||
public void fireModelChanged(IModelDelta delta);
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.dd.dsf.ui.viewmodel;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider;
|
||||
|
@ -92,20 +93,21 @@ public interface IVMNode extends IElementContentProvider
|
|||
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor);
|
||||
|
||||
/**
|
||||
* Returns the view model element for the given data model event. This method
|
||||
* Retireves the view model elements for the given data model event. This method
|
||||
* is optional and it allows the view model provider to optimize event processing
|
||||
* by avoiding the need to retrieve all possible elements for the given node.
|
||||
* </p>
|
||||
* For example: If a threads node implementation is given a thread stopped event in
|
||||
* for this method, and the stopped event included a reference to the thread. Then
|
||||
* this method, and the stopped event included a reference to the thread. Then
|
||||
* the implementation should create a view model context for that thread and return it
|
||||
* here.
|
||||
*
|
||||
* @param parentDelta The parent delta in the processing of this event.
|
||||
* @param event The event to check for the data model object.
|
||||
* @return A view model object if it can be calculated, <code>null</code>
|
||||
* if it cannot.
|
||||
* @param Request monitor for the array of elements corresponding to the
|
||||
* given event.
|
||||
*/
|
||||
public IVMContext getContextFromEvent(Object event);
|
||||
public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor<IVMContext[]> rm);
|
||||
|
||||
/**
|
||||
* Releases the resources held by this node.
|
||||
|
|
|
@ -3,8 +3,11 @@ package org.eclipse.dd.dsf.ui.viewmodel;
|
|||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider;
|
||||
|
@ -39,6 +42,12 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvi
|
|||
public interface IVMProvider
|
||||
extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory, IViewerInputProvider
|
||||
{
|
||||
/**
|
||||
* Returns the presentation context of the viewer that this provider
|
||||
* is configured for.
|
||||
*/
|
||||
public IPresentationContext getPresentationContext();
|
||||
|
||||
/**
|
||||
* Returns the VM Adapter associated with the provider.
|
||||
*/
|
||||
|
@ -66,10 +75,26 @@ public interface IVMProvider
|
|||
public IVMNode[] getAllVMNodes();
|
||||
|
||||
/**
|
||||
* Returns the presentation context of the viewer that this provider
|
||||
* is configured for.
|
||||
* Calls the given view model node to perform the given updates. This
|
||||
* method is different than calling the IVMNode update method directly in that
|
||||
* it allows the provider to do additional processing on the update such as caching.
|
||||
*/
|
||||
public IPresentationContext getPresentationContext();
|
||||
public void updateNode(final IVMNode node, IHasChildrenUpdate[] updates);
|
||||
|
||||
/**
|
||||
* Calls the given view model node to perform the given updates. This
|
||||
* method is different than calling the IVMNode update method directly in that
|
||||
* it allows the provider to do additional processing on the update such as caching.
|
||||
*/
|
||||
public void updateNode(final IVMNode node, IChildrenCountUpdate updates);
|
||||
|
||||
/**
|
||||
* Calls the given view model node to perform the given updates. This
|
||||
* method is different than calling the IVMNode update method directly in that
|
||||
* it allows the provider to do additional processing on the update such as caching.
|
||||
*/
|
||||
public void updateNode(IVMNode node, IChildrenUpdate updates);
|
||||
|
||||
|
||||
/**
|
||||
* Cleans up the resources associated with this provider.
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package org.eclipse.dd.dsf.ui.viewmodel;
|
||||
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
|
||||
/**
|
||||
* Event generated by an IModelProxy implementation when it is installed
|
||||
* into a viewer.
|
||||
*/
|
||||
public class ModelProxyInstalledEvent {
|
||||
private final IModelProxy fProxy;
|
||||
private final Viewer fViewer;
|
||||
private final Object fRootElement;
|
||||
|
||||
public ModelProxyInstalledEvent(IModelProxy proxy, Viewer viewer, Object rootElement) {
|
||||
fProxy = proxy;
|
||||
fViewer = viewer;
|
||||
fRootElement = rootElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IModelProxy that generated this event.
|
||||
*/
|
||||
public IModelProxy getModelProxy() {
|
||||
return fProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element that this model proxy was registered for.
|
||||
*/
|
||||
public Object getRootElement() {
|
||||
return fRootElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the viewer that installed this model proxy.
|
||||
*/
|
||||
public Viewer getViewer() {
|
||||
return fViewer;
|
||||
}
|
||||
}
|
|
@ -45,6 +45,9 @@ public class RootVMNode extends AbstractVMNode implements IRootVMNode {
|
|||
* event should be processed to generate a delta.
|
||||
*/
|
||||
public boolean isDeltaEvent(Object rootObject, Object event) {
|
||||
if (event instanceof ModelProxyInstalledEvent) {
|
||||
return rootObject.equals( ((ModelProxyInstalledEvent)event).getRootElement() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.concurrent.RejectedExecutionException;
|
|||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
|
@ -28,6 +29,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext;
|
|||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
|
||||
|
@ -129,15 +131,17 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode
|
|||
}
|
||||
|
||||
@Override
|
||||
public IVMContext getContextFromEvent(Object event) {
|
||||
public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor<IVMContext[]> rm) {
|
||||
if (event instanceof IDMEvent<?>) {
|
||||
IDMEvent<?> dmEvent = (IDMEvent<?>)event;
|
||||
IDMContext dmc = DMContexts.getAncestorOfType(dmEvent.getDMContext(), fDMCClassType);
|
||||
if (dmc != null) {
|
||||
return createVMContext(dmc);
|
||||
rm.setData(new IVMContext[] { createVMContext(dmc) });
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
super.getContextsForEvent(parentDelta, event, rm);
|
||||
}
|
||||
|
||||
protected AbstractDMVMProvider getDMVMProvider() {
|
||||
|
|
|
@ -285,7 +285,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void updateNode(IVMNode node, IHasChildrenUpdate[] updates) {
|
||||
public void updateNode(IVMNode node, IHasChildrenUpdate[] updates) {
|
||||
LinkedList <IHasChildrenUpdate> missUpdates = new LinkedList<IHasChildrenUpdate>();
|
||||
for(final IHasChildrenUpdate update : updates) {
|
||||
ElementDataKey key = makeEntryKey(node, update);
|
||||
|
@ -316,20 +316,14 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void updateNode(IVMNode node, IChildrenCountUpdate[] updates) {
|
||||
// Given our knowledge of DefaultVMContentProviderStragety, make an
|
||||
// assumption about the updates argument: there should always be
|
||||
// exactly one update in this array.
|
||||
assert updates.length == 1;
|
||||
final IChildrenCountUpdate update = updates[0];
|
||||
|
||||
public void updateNode(IVMNode node, final IChildrenCountUpdate update) {
|
||||
ElementDataKey key = makeEntryKey(node, update);
|
||||
final ElementDataEntry entry = getElementDataEntry(key);
|
||||
if(entry.fChildrenCount != null) {
|
||||
update.setChildCount(entry.fChildrenCount.intValue());
|
||||
update.done();
|
||||
} else {
|
||||
updates[0] = new VMChildrenCountUpdate(update, new DataRequestMonitor<Integer>(getExecutor(), null) {
|
||||
IChildrenCountUpdate updateProxy = new VMChildrenCountUpdate(update, new DataRequestMonitor<Integer>(getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if(getStatus().isOK()) {
|
||||
|
@ -341,17 +335,12 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
update.done();
|
||||
}
|
||||
});
|
||||
super.updateNode(node, updates);
|
||||
super.updateNode(node, updateProxy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateNode(IVMNode node, IChildrenUpdate[] updates) {
|
||||
// Given our knowledge of DefaultVMContentProviderStragety, make an
|
||||
// assumption about the updates argument: there should always be
|
||||
// exactly one update in this array.
|
||||
assert updates.length == 1;
|
||||
final IChildrenUpdate update = updates[0];
|
||||
public void updateNode(IVMNode node, final IChildrenUpdate update) {
|
||||
|
||||
ElementDataKey key = makeEntryKey(node, update);
|
||||
|
||||
|
@ -360,7 +349,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
// We need to retrieve all the children if we don't have any children information.
|
||||
// Or if the client requested all children (offset = -1, length -1) and we have not
|
||||
// retrieved that before.
|
||||
updates[0] = new VMChildrenUpdate(
|
||||
IChildrenUpdate updateProxy = new VMChildrenUpdate(
|
||||
update, update.getOffset(), update.getLength(),
|
||||
new DataRequestMonitor<List<Object>>(getExecutor(), null)
|
||||
{
|
||||
|
@ -396,7 +385,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
update.done();
|
||||
}
|
||||
});
|
||||
super.updateNode(node, updates);
|
||||
super.updateNode(node, updateProxy);
|
||||
} else if (update.getOffset() < 0 ) {
|
||||
// The update requested all children. Fill in all children assuming that
|
||||
// the children array is complete.
|
||||
|
@ -450,7 +439,9 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}));
|
||||
}
|
||||
|
||||
super.updateNode( node, partialUpdates.toArray(new IChildrenUpdate[partialUpdates.size()]) );
|
||||
for (IChildrenUpdate partialUpdate : partialUpdates) {
|
||||
super.updateNode(node, partialUpdate);
|
||||
}
|
||||
multiRm.setDoneCount(partialUpdates.size());
|
||||
} else {
|
||||
// we have all of the children in cache; return from cache
|
||||
|
|
Loading…
Add table
Reference in a new issue