1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-16 21:45:22 +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:
Pawel Piech 2008-02-12 23:13:12 +00:00
parent c61de9929c
commit a12a4967e3
13 changed files with 362 additions and 207 deletions

View file

@ -70,7 +70,7 @@ public class LaunchRootVMNode extends RootVMNode
return false; return false;
} }
} }
return true; return super.isDeltaEvent(rootObject, e);
} }
@Override @Override

View file

@ -19,7 +19,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IStack; 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.IContainerSuspendedDMEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; 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.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; 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.VMChildrenUpdate;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode;
@ -118,31 +119,39 @@ public class StackFramesVMNode extends AbstractDMVMNode
return; return;
} }
getServicesTracker().getService(IStack.class).getTopFrame( try {
execDmc, getSession().getExecutor().execute(new DsfRunnable() {
new DataRequestMonitor<IFrameDMContext>(getExecutor(), null) { public void run() {
@Override getServicesTracker().getService(IStack.class).getTopFrame(
public void handleCompleted() { execDmc,
if (!getStatus().isOK()) { new DataRequestMonitor<IFrameDMContext>(getExecutor(), null) {
handleFailedUpdate(update); @Override
return; public void handleCompleted() {
} if (!getStatus().isOK()) {
handleFailedUpdate(update);
IVMContext topFrameVmc = createVMContext(getData()); return;
}
update.setChild(topFrameVmc, 0);
// If there are old frames cached, use them and only substitute the top frame object. Otherwise, create IVMContext topFrameVmc = createVMContext(getData());
// an array of VMCs with just the top frame.
if (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) { update.setChild(topFrameVmc, 0);
fCachedOldFrameVMCs[0] = topFrameVmc; // If there are old frames cached, use them and only substitute the top frame object. Otherwise, create
for (int i = 0; i < fCachedOldFrameVMCs.length; i++) // an array of VMCs with just the top frame.
update.setChild(fCachedOldFrameVMCs[i], i); if (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) {
} else { fCachedOldFrameVMCs[0] = topFrameVmc;
update.setChild(topFrameVmc, 0); for (int i = 0; i < fCachedOldFrameVMCs.length; i++)
} update.setChild(fCachedOldFrameVMCs[i], i);
update.done(); } 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); final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class);
IRunControl runControlService = getServicesTracker().getService(IRunControl.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; if (execDmc == null || runControlService == null || stepQueueMgrService == null) return;
String imageKey = null; 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) { public int getDeltaFlags(Object e) {
// This node generates delta if the timers have changed, or if the // This node generates delta if the timers have changed, or if the
// label has changed. // label has changed.
@ -282,9 +316,12 @@ public class StackFramesVMNode extends AbstractDMVMNode
} else { } else {
return IModelDelta.CONTENT; return IModelDelta.CONTENT;
} }
} else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { } else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
return IModelDelta.CONTENT; return IModelDelta.CONTENT;
} else if (e instanceof ModelProxyInstalledEvent) {
return IModelDelta.SELECT | IModelDelta.EXPAND;
} }
return IModelDelta.NO_CHANGE; return IModelDelta.NO_CHANGE;
} }
@ -300,8 +337,10 @@ public class StackFramesVMNode extends AbstractDMVMNode
buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, execDmc, execDmc, parent, nodeOffset, rm); buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, execDmc, execDmc, parent, nodeOffset, rm);
} else if (e instanceof IResumedDMEvent) { } else if (e instanceof IResumedDMEvent) {
buildDeltaForResumedEvent((IResumedDMEvent)e, parent, nodeOffset, rm); buildDeltaForResumedEvent((IResumedDMEvent)e, parent, nodeOffset, rm);
} else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { } else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
buildDeltaForSteppingTimedOutEvent((IStepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm); buildDeltaForSteppingTimedOutEvent((StepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm);
} else if (e instanceof ModelProxyInstalledEvent) {
buildDeltaForModelProxyInstalledEvent(parent, nodeOffset, rm);
} else { } else {
rm.done(); rm.done();
} }
@ -372,9 +411,27 @@ public class StackFramesVMNode extends AbstractDMVMNode
rm.done(); 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. // Repaint the stack frame images to have the running symbol.
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
rm.done(); 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();
}
})
);
}
} }

View file

@ -10,7 +10,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.dd.dsf.ui.viewmodel; 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.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.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
@ -46,8 +51,9 @@ abstract public class AbstractVMNode implements IVMNode {
fDisposed = true; fDisposed = true;
} }
public IVMContext getContextFromEvent(Object event) { public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor<IVMContext[]> rm) {
return null; rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$
rm.done();
} }
protected boolean isDisposed() { protected boolean isDisposed() {

View file

@ -322,7 +322,7 @@ abstract public class AbstractVMProvider implements IVMProvider
* overrides this method to optionally return the results for an update from * overrides this method to optionally return the results for an update from
* a cache. * a cache.
*/ */
protected void updateNode(final IVMNode node, IHasChildrenUpdate[] updates) { public void updateNode(final IVMNode node, IHasChildrenUpdate[] updates) {
IHasChildrenUpdate[] updateProxies = new IHasChildrenUpdate[updates.length]; IHasChildrenUpdate[] updateProxies = new IHasChildrenUpdate[updates.length];
for (int i = 0; i < updates.length; i++) { for (int i = 0; i < updates.length; i++) {
final IHasChildrenUpdate update = updates[i]; final IHasChildrenUpdate update = updates[i];
@ -340,7 +340,7 @@ abstract public class AbstractVMProvider implements IVMProvider
if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) {
updateNode( updateNode(
node, node,
new VMChildrenUpdate[] { new VMChildrenUpdate( new VMChildrenUpdate(
update, -1, -1, update, -1, -1,
new ViewerDataRequestMonitor<List<Object>>(getExecutor(), update) { new ViewerDataRequestMonitor<List<Object>>(getExecutor(), update) {
@Override @Override
@ -349,7 +349,7 @@ abstract public class AbstractVMProvider implements IVMProvider
update.done(); update.done();
} }
}) })
}); );
} else { } else {
update.setStatus(getStatus()); 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 * overrides this method to optionally return the results for an update from
* a cache. * a cache.
*/ */
protected void updateNode(final IVMNode node, IChildrenCountUpdate[] updates) { public void updateNode(final IVMNode node, final IChildrenCountUpdate update) {
IChildrenCountUpdate[] updateProxies = new IChildrenCountUpdate[updates.length]; node.update(new IChildrenCountUpdate[] {
for (int i = 0; i < updates.length; i++) { new VMChildrenCountUpdate(
final IChildrenCountUpdate update = updates[i];
updateProxies[i] = new VMChildrenCountUpdate(
update, update,
new ViewerDataRequestMonitor<Integer>(getExecutor(), updates[i]) { new ViewerDataRequestMonitor<Integer>(getExecutor(), update) {
@Override @Override
protected void handleOK() { protected void handleOK() {
update.setChildCount(getData()); update.setChildCount(getData());
@ -388,7 +386,7 @@ abstract public class AbstractVMProvider implements IVMProvider
if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) {
updateNode( updateNode(
node, node,
new VMChildrenUpdate[] { new VMChildrenUpdate( new VMChildrenUpdate(
update, -1, -1, update, -1, -1,
new ViewerDataRequestMonitor<List<Object>>(getExecutor(), update) { new ViewerDataRequestMonitor<List<Object>>(getExecutor(), update) {
@Override @Override
@ -397,14 +395,13 @@ abstract public class AbstractVMProvider implements IVMProvider
update.done(); 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 * overrides this method to optionally return the results for an update from
* a cache. * a cache.
*/ */
protected void updateNode(IVMNode node, IChildrenUpdate[] updates) { public void updateNode(IVMNode node, IChildrenUpdate update) {
node.update(updates); node.update(new IChildrenUpdate[] { update });
} }

View file

@ -170,7 +170,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
update.setChildCount(0); update.setChildCount(0);
update.done(); update.done();
} else if (childNodes.length == 1) { } else if (childNodes.length == 1) {
getVMProvider().updateNode(childNodes[0], new IChildrenCountUpdate[] { update } ); getVMProvider().updateNode(childNodes[0], update);
} else { } else {
getChildrenCountsForNode( getChildrenCountsForNode(
update, update,
@ -208,7 +208,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
// Invalid update, just mark done. // Invalid update, just mark done.
update.done(); update.done();
} else if (childNodes.length == 1) { } else if (childNodes.length == 1) {
getVMProvider().updateNode(childNodes[0], new IChildrenUpdate[] { update }); getVMProvider().updateNode(childNodes[0], update);
} else { } else {
getChildrenCountsForNode( getChildrenCountsForNode(
update, update,
@ -261,23 +261,22 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
final int nodeIndex = i; final int nodeIndex = i;
getVMProvider().updateNode( getVMProvider().updateNode(
childNodes[i], childNodes[i],
new IChildrenCountUpdate[] { new VMChildrenCountUpdate(
new VMChildrenCountUpdate( update,
update, childrenCountMultiReqMon.add(
childrenCountMultiReqMon.add( new DataRequestMonitor<Integer>(getVMProvider().getExecutor(), null) {
new DataRequestMonitor<Integer>(getVMProvider().getExecutor(), null) { @Override
@Override protected void handleOK() {
protected void handleOK() { counts[nodeIndex] = getData();
counts[nodeIndex] = getData(); }
}
@Override
@Override protected void handleCompleted() {
protected void handleCompleted() { super.handleCompleted();
super.handleCompleted(); childrenCountMultiReqMon.requestMonitorDone(this);
childrenCountMultiReqMon.requestMonitorDone(this); }
} }))
})) );
});
} }
} }
@ -315,21 +314,19 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
if (elementsLength > 0) { if (elementsLength > 0) {
getVMProvider().updateNode( getVMProvider().updateNode(
nodes[i], nodes[i],
new IChildrenUpdate[] { new VMChildrenUpdate(
new VMChildrenUpdate( update, elementsStartIdx, elementsLength,
update, elementsStartIdx, elementsLength, elementsMultiRequestMon.add(new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
elementsMultiRequestMon.add(new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) { @Override
@Override protected void handleCompleted() {
protected void handleCompleted() { if (getStatus().isOK()) {
if (getStatus().isOK()) { for (int i = 0; i < elementsLength; i++) {
for (int i = 0; i < elementsLength; i++) { update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i);
update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i);
}
} }
elementsMultiRequestMon.requestMonitorDone(this);
} }
})) elementsMultiRequestMon.requestMonitorDone(this);
} }
}))
); );
} }
} }

View file

@ -24,9 +24,8 @@ import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor; 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.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.IModelChangedListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
@ -182,6 +181,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
*/ */
public void installed(Viewer viewer) { public void installed(Viewer viewer) {
fViewer = 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 no child nodes have deltas we can stop here.
if (childNodesWithDeltaFlags.size() == 0) { if (childNodesWithDeltaFlags.size() == 0) {
rm.done();
rm.setData(viewRootDelta); rm.setData(viewRootDelta);
rm.done();
return; return;
} }
@ -284,19 +284,26 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
protected void buildChildDeltas(final IVMNode node, final Object event, final VMDelta parentDelta, protected void buildChildDeltas(final IVMNode node, final Object event, final VMDelta parentDelta,
final int nodeOffset, final RequestMonitor rm) final int nodeOffset, final RequestMonitor rm)
{ {
final IVMContext vmc = node.getContextFromEvent(event); node.getContextsForEvent(
parentDelta,
if (vmc != null) { event,
buildChildDeltasForEventContext(vmc, node, event, parentDelta, nodeOffset, rm); new DataRequestMonitor<IVMContext[]>(getVMProvider().getExecutor(), rm) {
} else { @Override
// The DMC for this node was not found in the event. Call the protected void handleCompleted() {
// super-class to resort to the default behavior which may add a if (getStatus().isOK()) {
// delta for every element in this node. assert getData() != null;
buildChildDeltasForAllContexts(node, event, parentDelta, nodeOffset, rm); 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 VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor)
{ {
final Map<IVMNode,Integer> childNodeDeltas = getChildNodesWithDeltaFlags(node, parentDelta, event); 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. // elements and then finding the DMC that the event is for.
getVMProvider().updateNode( getVMProvider().updateNode(
node, node,
new IChildrenUpdate[] { new VMChildrenUpdate(
new VMChildrenUpdate( parentDelta, getVMProvider().getPresentationContext(), -1, -1,
parentDelta, getVMProvider().getPresentationContext(), -1, -1, new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) { @Override
@Override protected void handleCompleted() {
protected void handleCompleted() { if (isDisposed()) return;
if (isDisposed()) return;
// Check for an empty list of elements. If it's empty then we
// Check for an empty list of elements. If it's empty then we // don't have to call the children nodes, so return here.
// 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.
// No need to propagate error, there's no means or need to display it. if (!getStatus().isOK() || getData().isEmpty()) {
if (!getStatus().isOK() || getData().isEmpty()) { requestMonitor.done();
requestMonitor.done(); return;
return; }
}
CountingRequestMonitor countingRm =
// Find the index. 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; int i;
for (i = 0; i < getData().size(); i++) { for (i = 0; i < getData().size(); i++) {
if (vmc.equals(getData().get(i))) break; if (vmc.equals(getData().get(i))) break;
} }
if (i == getData().size()) { if (i == getData().size()) {
// Element not found, no need to generate the delta. // Element not found, no need to generate the delta.
requestMonitor.done(); continue;
return;
} }
// Optimization: Try to find a delta with a matching element, if found use it. // 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); 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 { } else {
// Optimization: Try to find a delta with a matching element, if found use it. CountingRequestMonitor countingRm =
// Otherwise create a new delta for the event element. new CountingRequestMonitor(getVMProvider().getExecutor(), requestMonitor);
VMDelta delta = (VMDelta)parentDelta.getChildDelta(vmc); int count = 0;
if (delta == null) { for (IVMContext vmc : vmcs) {
delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE); // 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. // each element as the parent of their delta.
getVMProvider().updateNode( getVMProvider().updateNode(
node, node,
new IChildrenUpdate[] { new VMChildrenUpdate(
new VMChildrenUpdate( parentDelta, getVMProvider().getPresentationContext(), -1, -1,
parentDelta, getVMProvider().getPresentationContext(), -1, -1, new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) { @Override
@Override protected void handleCompleted() {
protected void handleCompleted() { if (fDisposed) return;
if (fDisposed) return;
// Check for an empty list of elements. If it's empty then we
// Check for an empty list of elements. If it's empty then we // don't have to call the children nodes, so return here.
// 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.
// No need to propagate error, there's no means or need to display it. if (!getStatus().isOK() || getData().size() == 0) {
if (!getStatus().isOK() || getData().size() == 0) { requestMonitor.done();
requestMonitor.done(); return;
return; }
}
final MultiRequestMonitor<RequestMonitor> elementsDeltasMultiRequestMon =
final MultiRequestMonitor<RequestMonitor> elementsDeltasMultiRequestMon = new MultiRequestMonitor<RequestMonitor>(getVMProvider().getExecutor(), null) {
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 @Override
protected void handleCompleted() { protected void handleCompleted() {
if (isDisposed()) return; elementsDeltasMultiRequestMon.requestMonitorDone(this);
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() {
elementsDeltasMultiRequestMon.requestMonitorDone(this);
}
}));
}
} }
}) }
}); })
);
} }
} }
@ -568,19 +586,18 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
final int nodeIndex = i; final int nodeIndex = i;
getVMProvider().updateNode( getVMProvider().updateNode(
childNodes[i], childNodes[i],
new IChildrenCountUpdate[] { new VMChildrenCountUpdate(
new VMChildrenCountUpdate( delta, getVMProvider().getPresentationContext(),
delta, getVMProvider().getPresentationContext(), childrenCountMultiRequestMon.add(
childrenCountMultiRequestMon.add( new DataRequestMonitor<Integer>(getVMProvider().getExecutor(), null) {
new DataRequestMonitor<Integer>(getVMProvider().getExecutor(), null) { @Override
@Override protected void handleCompleted() {
protected void handleCompleted() { counts[nodeIndex] = getData();
counts[nodeIndex] = getData(); childrenCountMultiRequestMon.requestMonitorDone(this);
childrenCountMultiRequestMon.requestMonitorDone(this); }
} })
}) )
) );
});
} }
} else { } else {
Map<IVMNode, Integer> data = new HashMap<IVMNode, Integer>(); Map<IVMNode, Integer> data = new HashMap<IVMNode, Integer>();

View file

@ -15,17 +15,32 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; 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") @SuppressWarnings("restriction")
public interface IVMModelProxy extends IModelProxy { public interface IVMModelProxy extends IModelProxy {
/**
* Returns the root element that this model proxy was created for.
*/
public Object getRootElement(); 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); public boolean isDeltaEvent(Object event);
/**
* Creates a model delta for the given event.
*/
public void createDelta(final Object event, final DataRequestMonitor<IModelDelta> rm); 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); public void fireModelChanged(IModelDelta delta);
} }

View file

@ -11,6 +11,7 @@
package org.eclipse.dd.dsf.ui.viewmodel; package org.eclipse.dd.dsf.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; 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.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; 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); 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 * 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. * by avoiding the need to retrieve all possible elements for the given node.
* </p> * </p>
* For example: If a threads node implementation is given a thread stopped event in * 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 * the implementation should create a view model context for that thread and return it
* here. * here.
* *
* @param parentDelta The parent delta in the processing of this event.
* @param event The event to check for the data model object. * @param event The event to check for the data model object.
* @return A view model object if it can be calculated, <code>null</code> * @param Request monitor for the array of elements corresponding to the
* if it cannot. * given event.
*/ */
public IVMContext getContextFromEvent(Object event); public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor<IVMContext[]> rm);
/** /**
* Releases the resources held by this node. * Releases the resources held by this node.

View file

@ -3,8 +3,11 @@ package org.eclipse.dd.dsf.ui.viewmodel;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; 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.IColumnPresentationFactory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; 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.IModelProxyFactory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider; 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 public interface IVMProvider
extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory, IViewerInputProvider 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. * Returns the VM Adapter associated with the provider.
*/ */
@ -66,10 +75,26 @@ public interface IVMProvider
public IVMNode[] getAllVMNodes(); public IVMNode[] getAllVMNodes();
/** /**
* Returns the presentation context of the viewer that this provider * Calls the given view model node to perform the given updates. This
* is configured for. * 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. * Cleans up the resources associated with this provider.

View file

@ -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;
}
}

View file

@ -45,6 +45,9 @@ public class RootVMNode extends AbstractVMNode implements IRootVMNode {
* event should be processed to generate a delta. * event should be processed to generate a delta.
*/ */
public boolean isDeltaEvent(Object rootObject, Object event) { public boolean isDeltaEvent(Object rootObject, Object event) {
if (event instanceof ModelProxyInstalledEvent) {
return rootObject.equals( ((ModelProxyInstalledEvent)event).getRootElement() );
}
return true; return true;
} }

View file

@ -15,6 +15,7 @@ import java.util.concurrent.RejectedExecutionException;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; 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.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.Immutable;
import org.eclipse.dd.dsf.datamodel.DMContexts; 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.AbstractVMNode;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; 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.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
@ -129,15 +131,17 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode
} }
@Override @Override
public IVMContext getContextFromEvent(Object event) { public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor<IVMContext[]> rm) {
if (event instanceof IDMEvent<?>) { if (event instanceof IDMEvent<?>) {
IDMEvent<?> dmEvent = (IDMEvent<?>)event; IDMEvent<?> dmEvent = (IDMEvent<?>)event;
IDMContext dmc = DMContexts.getAncestorOfType(dmEvent.getDMContext(), fDMCClassType); IDMContext dmc = DMContexts.getAncestorOfType(dmEvent.getDMContext(), fDMCClassType);
if (dmc != null) { 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() { protected AbstractDMVMProvider getDMVMProvider() {

View file

@ -285,7 +285,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
} }
@Override @Override
protected void updateNode(IVMNode node, IHasChildrenUpdate[] updates) { public void updateNode(IVMNode node, IHasChildrenUpdate[] updates) {
LinkedList <IHasChildrenUpdate> missUpdates = new LinkedList<IHasChildrenUpdate>(); LinkedList <IHasChildrenUpdate> missUpdates = new LinkedList<IHasChildrenUpdate>();
for(final IHasChildrenUpdate update : updates) { for(final IHasChildrenUpdate update : updates) {
ElementDataKey key = makeEntryKey(node, update); ElementDataKey key = makeEntryKey(node, update);
@ -316,20 +316,14 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
} }
@Override @Override
protected void updateNode(IVMNode node, IChildrenCountUpdate[] updates) { public void updateNode(IVMNode node, final IChildrenCountUpdate update) {
// 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];
ElementDataKey key = makeEntryKey(node, update); ElementDataKey key = makeEntryKey(node, update);
final ElementDataEntry entry = getElementDataEntry(key); final ElementDataEntry entry = getElementDataEntry(key);
if(entry.fChildrenCount != null) { if(entry.fChildrenCount != null) {
update.setChildCount(entry.fChildrenCount.intValue()); update.setChildCount(entry.fChildrenCount.intValue());
update.done(); update.done();
} else { } else {
updates[0] = new VMChildrenCountUpdate(update, new DataRequestMonitor<Integer>(getExecutor(), null) { IChildrenCountUpdate updateProxy = new VMChildrenCountUpdate(update, new DataRequestMonitor<Integer>(getExecutor(), null) {
@Override @Override
protected void handleCompleted() { protected void handleCompleted() {
if(getStatus().isOK()) { if(getStatus().isOK()) {
@ -341,17 +335,12 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
update.done(); update.done();
} }
}); });
super.updateNode(node, updates); super.updateNode(node, updateProxy);
} }
} }
@Override @Override
protected void updateNode(IVMNode node, IChildrenUpdate[] updates) { public void updateNode(IVMNode node, final IChildrenUpdate update) {
// 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];
ElementDataKey key = makeEntryKey(node, 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. // 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 // Or if the client requested all children (offset = -1, length -1) and we have not
// retrieved that before. // retrieved that before.
updates[0] = new VMChildrenUpdate( IChildrenUpdate updateProxy = new VMChildrenUpdate(
update, update.getOffset(), update.getLength(), update, update.getOffset(), update.getLength(),
new DataRequestMonitor<List<Object>>(getExecutor(), null) new DataRequestMonitor<List<Object>>(getExecutor(), null)
{ {
@ -396,7 +385,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
update.done(); update.done();
} }
}); });
super.updateNode(node, updates); super.updateNode(node, updateProxy);
} else if (update.getOffset() < 0 ) { } else if (update.getOffset() < 0 ) {
// The update requested all children. Fill in all children assuming that // The update requested all children. Fill in all children assuming that
// the children array is complete. // 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()); multiRm.setDoneCount(partialUpdates.size());
} else { } else {
// we have all of the children in cache; return from cache // we have all of the children in cache; return from cache