diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index 830f2c037e4..49de1e0b869 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -114,7 +114,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode } // Call the child nodes to generate their delta. - final Map childNodeDeltas = getChildNodesWithDeltas(event); + final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); if (childNodeDeltas.size() != 0) { callChildNodesToBuildDelta( childNodeDeltas, rootDelta, event, diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index eeb94b8bafe..2e975953274 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -60,7 +60,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { return fProvider.getExecutor(); } - protected IVMProvider getVMProvider() { + protected AbstractVMProvider getVMProvider() { return fProvider; } @@ -91,17 +91,20 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { return retVal; } - /** - * Handles calling child schema nodes to build the model delta. If child - * schema nodes have deltas, this schema node has to provide the - * IModelDelta objects that the child shema node can build on. + /** + * Base implementation that handles calling child layout nodes to build + * the model delta. The child nodes are called with all the elements + * in this node, which could be very inefficient. In order to build delta + * only for specific elements in this node, the class extending + * AbstractVMLayoutNode should override this method. + * @see IVMLayoutNode#buildDelta(Object, VMDelta, int, Done) */ public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final Done done) { // Find the child nodes that have deltas for the given event. - final Map childNodeDeltas = getChildNodesWithDeltas(event); + final Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(event); // If no child layout nodes have deltas we can stop here. - if (childNodeDeltas.size() == 0) { + if (childNodesWithDeltaFlags.size() == 0) { getExecutor().execute(done); return; } @@ -112,14 +115,14 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { // use the full path from the delta to handle these flags. // Similarly, the index argument is not necessary either. boolean mustGetElements = false; - for (int childDelta : childNodeDeltas.values()) { + for (int childDelta : childNodesWithDeltaFlags.values()) { if ((childDelta & ~IModelDelta.CONTENT & ~IModelDelta.STATE) != 0) { mustGetElements = true; } } if (!mustGetElements) { - callChildNodesToBuildDelta(childNodeDeltas, parentDelta, event, done); + callChildNodesToBuildDelta(childNodesWithDeltaFlags, parentDelta, event, done); } else { // The given child layout nodes have deltas potentially for all elements // from this node. Retrieve all elements and call the child nodes with @@ -147,9 +150,9 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { // 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++) { - VMDelta delta = parentDelta.addNode((IVMContext)getData().get(i), nodeOffset + i, IModelDelta.NO_CHANGE); + VMDelta delta = parentDelta.addNode(getData().get(i), nodeOffset + i, IModelDelta.NO_CHANGE); callChildNodesToBuildDelta( - childNodeDeltas, delta, event, + childNodesWithDeltaFlags, delta, event, elementsDeltasDoneCollector.add(new Done() { public void run() { elementsDeltasDoneCollector.doneDone(this); @@ -162,6 +165,17 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } } + /** + * Calls the specified child layout nodes to build the delta for the given event. + * @param nodes Map of layout nodes to be invoked, and the corresponding delta + * flags that they will generate. This map is generated with a call to + * {@link #getChildNodesWithDeltaFlags(Object)}. + * @param delta The delta object to build on. This delta should have been + * gerated by this node, unless the full delta path is not being calculated + * due to an optimization. + * @param event The event object that the delta is being built for. + * @param done The result token to invoke when the delta is completed. + */ protected void callChildNodesToBuildDelta(final Map nodes, final VMDelta delta, final Object event, final Done done) { assert nodes.size() != 0; @@ -203,6 +217,22 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { }); } + /** + * Calculates the indexes at which the elements of each of the child + * layout nodes begin. These indexes are necessary to correctly + * calculate the deltas for elements in the child nodes. + * @param delta The delta object to build on. This delta should have been + * gerated by this node, unless the full delta path is not being calculated + * due to an optimization. + * @param fakeIt If true, it causes this method to fill the return data + * structure with dummy values. The dummy values indicate that the indexes + * are not known and are acceptable in the delta if the delta flags being + * generated do not require full index information. + * @param done Return token containing the results. The result data is a + * mapping between the child nodes and the indexes at which the child nodes' + * elements begin. There is a special value in the map with a null + * key, which contains the full element count for all the nodes. + */ private void getChildNodesElementOffsets(IModelDelta delta, boolean fakeIt, final GetDataDone> done) { assert getChildLayoutNodes().length != 0; @@ -258,7 +288,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * true to the hasDeltaFlags() test for the given * event. */ - protected Map getChildNodesWithDeltas(Object e) { + protected Map getChildNodesWithDeltaFlags(Object e) { Map nodes = new HashMap(); for (final IVMLayoutNode childNode : getChildLayoutNodes()) { int delta = childNode.getDeltaFlags(e); @@ -328,10 +358,6 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { protected class ViewerUpdate implements IViewerUpdate { - public void cancel() { - // FIXME M5 - } - final private Done fDone; private boolean fDoneInvoked = false; final private TreePath fTreePath; @@ -372,13 +398,8 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { public TreePath getElementPath() { return fTreePath; } public IStatus getStatus() { return fStatus; } public void setStatus(IStatus status) { fStatus = status; } - public void beginTask(String name, int totalWork) {} - public void internalWorked(double work) {} public boolean isCanceled() { return fCancelled; } - public void setCanceled(boolean value) { fCancelled = value; } - public void setTaskName(String name) {} - public void subTask(String name) {} - public void worked(int work) {} + public void cancel() { fCancelled = true; } public void done() { assert !fDoneInvoked; @@ -430,6 +451,11 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { public void setChild(Object child, int offset) { fChildren.add(offset, child); } + + @Override + public String toString() { + return "ElementsUpdate for all elements under parent = " + getElement(); //$NON-NLS-1$ + } } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 9befc631b76..130ce67293a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -28,8 +28,6 @@ import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.DoneCollector; import org.eclipse.dd.dsf.concurrent.GetDataDone; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; @@ -90,14 +88,14 @@ abstract public class AbstractVMProvider implements IVMProvider fPresentationContext = presentationContext; } - public IVMAdapter getVMAdapter() { - return fVMAdapter; - } - public IPresentationContext getPresentationContext() { return fPresentationContext; } - + + public AbstractVMAdapter getVMAdapter() { + return fVMAdapter; + } + /** * Sets the root node for this provider. */ @@ -459,30 +457,6 @@ abstract public class AbstractVMProvider implements IVMProvider return false; } - /** - * Handle "data model changed" event by generating a delta object for each - * view and passing it to the corresponding view model provider. The view - * model provider is then responsible for filling-in and sending the delta - * to the viewer. - * @param e - */ - @DsfServiceEventHandler - public void eventDispatched(final IDMEvent event) { - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - - if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { - rootLayoutNode.createDelta(event, new GetDataDone() { - public void run() { - if (getStatus().isOK()) { - fModelProxy.fireModelChangedNonDispatch(getData()); - } - } - @Override public String toString() { - return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - }); - } - } @ThreadSafe protected class ModelProxy extends AbstractModelProxy { @@ -500,10 +474,12 @@ abstract public class AbstractVMProvider implements IVMProvider public boolean isConflicting(ISchedulingRule rule) { return rule == this; } }; + @Override public void installed(Viewer viewer) { fProxyActive++; } + @Override public void dispose() { fProxyActive--; super.dispose(); @@ -518,6 +494,7 @@ abstract public class AbstractVMProvider implements IVMProvider if (fProxyActive <= 0) return; Job job = new Job("Processing view model delta.") { //$NON-NLS-1$ + @Override protected IStatus run(IProgressMonitor monitor) { fireModelChanged(delta); return Status.OK_STATUS; @@ -532,10 +509,6 @@ abstract public class AbstractVMProvider implements IVMProvider class ViewerUpdate implements IViewerUpdate { - public void cancel() { - // FIXME M5 - } - private IStatus fStatus; private boolean fDoneInvoked = false; final private Done fDone; @@ -552,17 +525,11 @@ abstract public class AbstractVMProvider implements IVMProvider public IStatus getStatus() { return fStatus; } public void setStatus(IStatus status) { fStatus = status; } - public void beginTask(String name, int totalWork) {} - public void internalWorked(double work) {} public boolean isCanceled() { return fClientUpdate.isCanceled(); } - public void setCanceled(boolean value) { - // FIXME M5 - // fClientUpdate.setCanceled(value); + public void cancel() { + fClientUpdate.cancel(); } - public void setTaskName(String name) {} - public void subTask(String name) {} - public void worked(int work) {} - + public void done() { assert !fDoneInvoked; fDoneInvoked = true; @@ -583,6 +550,7 @@ abstract public class AbstractVMProvider implements IVMProvider fDone = done; } + @Override public TreePath getElementPath() { return ((IHasChildrenUpdate)fClientUpdate).getElementPath(); } @@ -591,6 +559,7 @@ abstract public class AbstractVMProvider implements IVMProvider fDone.setData(hasChildren); } + @Override public void done() { assert fDone.getData() != null || !fDone.getStatus().isOK(); super.done(); @@ -607,6 +576,7 @@ abstract public class AbstractVMProvider implements IVMProvider fDone = done; } + @Override public TreePath getElementPath() { return fElementPath; } @@ -615,6 +585,7 @@ abstract public class AbstractVMProvider implements IVMProvider fDone.setData(count); } + @Override public void done() { assert fDone.getData() != null || !fDone.getStatus().isOK(); super.done(); @@ -642,6 +613,7 @@ abstract public class AbstractVMProvider implements IVMProvider return fLength; } + @Override public TreePath getElementPath() { return ((IChildrenUpdate)fClientUpdate).getElementPath(); } @@ -652,5 +624,10 @@ abstract public class AbstractVMProvider implements IVMProvider } } + @Override + public String toString() { + return "ElementsUpdate for elements under parent = " + getElement() + ", in range " + getOffset() + " -> " + (getOffset() + getLength()); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ + } + } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java index 53d5650d917..8bd73da70ed 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java @@ -77,7 +77,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * is the input object into the view. */ public void createDelta(Object event, final GetDataDone done) { - final Map childNodeDeltas = getChildNodesWithDeltas(event); + final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); assert childNodeDeltas.size() != 0 : "Caller should make sure that there are deltas for given event."; //$NON-NLS-1$ // Always create the rootDelta, no matter what delta flags the child nodes have. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java index 883d0e23d0d..b6af2856cd8 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java @@ -60,7 +60,8 @@ public interface IVMLayoutNode /** * Retrieves the element objects of this node for the given path in the * viewer, and for the given range of indexes.
- * Note: the range of children, denoted by ILabelUpdate.getOffset() + * NOTE: update.getOffset() and update.getLength() may return -1. + * The range of children, denoted by ILabelUpdate.getOffset() * and ILabelUpdate.getLength(), may not be specified, in which case these * methods may return -1. This means that all the elements should be * retrieved for this node.
@@ -89,12 +90,31 @@ public interface IVMLayoutNode * for the given event. * @param event Event to process. * @return IModelDelta flags + * @see #buildDelta(Object, VMDelta, int, Done) * @see IModelDelta */ public int getDeltaFlags(Object event); /** - * Builds model delta information based on the given event. + * Builds model delta information based on the given event. + *

+ * Model deltas, which are used to control the state of elements in the viewer, are + * generated by the layout nodes by recursively calling this method on all the nodes + * in the layout tree. Each node implements two methods: {@link #getDeltaFlags(Object)}, + * and buildDelta(). A parent node which is processing a + * buildDelta operation needs to determine which of its elements are + * affected by a given event, set appropriate flags on these elements, and then + * it needs to call its child nodes with those elements to give the child nodes a + * chance to add onto the delta. + *

+ *

+ * The getDeltaFlags() is a synchronous + * call which tells the parent node whether on not to call the child node's + * buildDelta with the given event. If a child node return + * true, it only indicates that the node may add delta flags, but it + * does not require it to do so. + *

+ * * @param event Event to process. * @param parent Parent model delta node that this object should add delta * data to. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java index 44b2a3e6504..c8bd7c4d542 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -16,11 +16,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont public interface IVMProvider extends IElementContentProvider, IModelProxyFactoryAdapter, IColumnPresentationFactoryAdapter { - /** - * Returns the View Model Adapter that this provider belongs to. - */ - public IVMAdapter getVMAdapter(); - /** * Returns the root layout node that is configured in this provider. * It may return null, if a root node is not yet configured. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java index 6c524768b3f..906c71e9502 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java @@ -177,7 +177,7 @@ public class VMDelta extends ModelDelta { * @param numChildren the number of children the element has * @return newly created child delta */ - public ModelDelta addNode(Object element, int index, int flags, int numChildren) { + public VMDelta addNode(Object element, int index, int flags, int numChildren) { VMDelta node = new VMDelta(element, index, flags, numChildren); node.setParent(this); addDelta(node); @@ -197,7 +197,7 @@ public class VMDelta extends ModelDelta { * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getParent() */ @Override - public IModelDelta getParentDelta() { + public VMDelta getParentDelta() { return fParent; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 43088d2fa88..5b35febce0e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -388,7 +388,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract // Create the VM context based on the DM context from the DM event. final IVMContext vmc = new DMVMContext(DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType)); - final Map childNodeDeltas = getChildNodesWithDeltas(event); + final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); if (childNodeDeltas.size() == 0) { // There are no child nodes with deltas, just return to parent. getExecutor().execute(done);