mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Added an example of a view model with a recursive layout node (bug 178692).
This commit is contained in:
parent
bd63dcf820
commit
11aaafc829
8 changed files with 96 additions and 78 deletions
|
@ -114,7 +114,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode
|
|||
}
|
||||
|
||||
// Call the child nodes to generate their delta.
|
||||
final Map<IVMLayoutNode,Integer> childNodeDeltas = getChildNodesWithDeltas(event);
|
||||
final Map<IVMLayoutNode,Integer> childNodeDeltas = getChildNodesWithDeltaFlags(event);
|
||||
if (childNodeDeltas.size() != 0) {
|
||||
callChildNodesToBuildDelta(
|
||||
childNodeDeltas, rootDelta, event,
|
||||
|
|
|
@ -60,7 +60,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
|
|||
return fProvider.getExecutor();
|
||||
}
|
||||
|
||||
protected IVMProvider getVMProvider() {
|
||||
protected AbstractVMProvider getVMProvider() {
|
||||
return fProvider;
|
||||
}
|
||||
|
||||
|
@ -92,16 +92,19 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* <code>AbstractVMLayoutNode</code> 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<IVMLayoutNode,Integer> childNodeDeltas = getChildNodesWithDeltas(event);
|
||||
final Map<IVMLayoutNode,Integer> 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<IVMLayoutNode,Integer> 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 <code>null</code>
|
||||
* key, which contains the full element count for all the nodes.
|
||||
*/
|
||||
private void getChildNodesElementOffsets(IModelDelta delta, boolean fakeIt, final GetDataDone<Map<IVMLayoutNode, Integer>> done) {
|
||||
assert getChildLayoutNodes().length != 0;
|
||||
|
||||
|
@ -258,7 +288,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
|
|||
* <code>true</code> to the <code>hasDeltaFlags()</code> test for the given
|
||||
* event.
|
||||
*/
|
||||
protected Map<IVMLayoutNode, Integer> getChildNodesWithDeltas(Object e) {
|
||||
protected Map<IVMLayoutNode, Integer> getChildNodesWithDeltaFlags(Object e) {
|
||||
Map<IVMLayoutNode, Integer> nodes = new HashMap<IVMLayoutNode, Integer>();
|
||||
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$
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<IModelDelta>() {
|
||||
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,16 +525,10 @@ 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;
|
||||
|
@ -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$
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<IModelDelta> done) {
|
||||
final Map<IVMLayoutNode,Integer> childNodeDeltas = getChildNodesWithDeltas(event);
|
||||
final Map<IVMLayoutNode,Integer> 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.
|
||||
|
|
|
@ -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. <br>
|
||||
* 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.<br>
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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 <code>buildDelta()</code>. A parent node which is processing a
|
||||
* <code>buildDelta</code> 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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The <code>getDeltaFlags()</code> is a synchronous
|
||||
* call which tells the parent node whether on not to call the child node's
|
||||
* <code>buildDelta</code> with the given event. If a child node return
|
||||
* <code>true</code>, it only indicates that the node may add delta flags, but it
|
||||
* does not require it to do so.
|
||||
* </p>
|
||||
*
|
||||
* @param event Event to process.
|
||||
* @param parent Parent model delta node that this object should add delta
|
||||
* data to.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -388,7 +388,7 @@ abstract public class AbstractDMVMLayoutNode<V extends IDMData> 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<IVMLayoutNode,Integer> childNodeDeltas = getChildNodesWithDeltas(event);
|
||||
final Map<IVMLayoutNode,Integer> childNodeDeltas = getChildNodesWithDeltaFlags(event);
|
||||
if (childNodeDeltas.size() == 0) {
|
||||
// There are no child nodes with deltas, just return to parent.
|
||||
getExecutor().execute(done);
|
||||
|
|
Loading…
Add table
Reference in a new issue