diff options
15 files changed, 494 insertions, 235 deletions
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java index ffaf21900..03a940fcb 100644 --- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java +++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java @@ -233,26 +233,32 @@ public class LocatorService implements ILocator { private final Thread input_thread = new Thread() { public void run() { - for (;;) { - DatagramSocket socket = LocatorService.this.socket; - try { - final DatagramPacket p = new DatagramPacket(inp_buf, inp_buf.length); - socket.receive(p); - Protocol.invokeAndWait(new Runnable() { - public void run() { - handleDatagramPacket(p); - } - }); - } - catch (IllegalStateException x) { - // TCF event dispatch is shutdown - return; - } - catch (Exception x) { - if (socket != LocatorService.this.socket) continue; - log("Cannot read from datagram socket at port " + socket.getLocalPort(), x); + try { + for (;;) { + DatagramSocket socket = LocatorService.this.socket; + try { + final DatagramPacket p = new DatagramPacket(inp_buf, inp_buf.length); + socket.receive(p); + Protocol.invokeAndWait(new Runnable() { + public void run() { + handleDatagramPacket(p); + } + }); + } + catch (IllegalStateException x) { + // TCF event dispatch is shutdown + return; + } + catch (Exception x) { + if (socket != LocatorService.this.socket) continue; + log("Cannot read from datagram socket at port " + socket.getLocalPort(), x); + sleep(2000); + } } } + catch (Throwable x) { + log("Unhandled exception in socket reading thread", x); + } } }; diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java index 09430e656..d2129b6a5 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java @@ -13,7 +13,6 @@ package org.eclipse.tm.internal.tcf.debug.ui.model; import java.util.HashMap; import java.util.Map; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IMemory; import org.eclipse.tm.tcf.services.IRunControl; @@ -127,11 +126,11 @@ public class TCFChildrenExecContext extends TCFChildren { TCFNodeExecContext n = (TCFNodeExecContext)node.model.getNode(id); if (n == null) { n = new TCFNodeExecContext(node, id); - n.addModelDelta(IModelDelta.ADDED); + n.postContextAddedDelta(); add(n); } else { - n.addModelDelta(IModelDelta.STATE); + n.postAllChangedDelta(); } run_children.add(n); n.setRunContext(context); @@ -143,11 +142,11 @@ public class TCFChildrenExecContext extends TCFChildren { TCFNodeExecContext n = (TCFNodeExecContext)node.model.getNode(id); if (n == null) { n = new TCFNodeExecContext(node, id); - n.addModelDelta(IModelDelta.ADDED); + n.postContextAddedDelta(); add(n); } else { - n.addModelDelta(IModelDelta.STATE); + n.postAllChangedDelta(); } mem_children.add(n); n.setMemoryContext(context); diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java index c36f8d46b..801bdf70b 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java @@ -16,9 +16,7 @@ import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.IExpressionsListener; import org.eclipse.debug.core.model.IExpression; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.tm.tcf.protocol.Protocol; -import org.eclipse.tm.tcf.services.IExpressions; public class TCFChildrenExpressions extends TCFChildren { @@ -43,7 +41,7 @@ public class TCFChildrenExpressions extends TCFChildren { public void run() { reset(); if (g != generation) return; - node.addModelDelta(IModelDelta.CONTENT); + node.postExpressionAddedOrRemovedDelta(); } }); } @@ -76,11 +74,6 @@ public class TCFChildrenExpressions extends TCFChildren { @Override protected boolean startDataRetrieval() { - IExpressions exps = node.model.getLaunch().getService(IExpressions.class); - if (exps == null) { - set(null, null, new HashMap<String,TCFNode>()); - return true; - } HashMap<String,TCFNode> data = new HashMap<String,TCFNode>(); int cnt = 0; for (final IExpression e : exp_manager.getExpressions()) { diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java index 39d370900..c55cbea5a 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java @@ -37,6 +37,12 @@ public class TCFChildrenLocalVariables extends TCFChildren { set(null, null, new HashMap<String,TCFNode>()); return true; } + TCFChildrenStackTrace stack_trace_cache = ((TCFNodeExecContext)node.parent).getStackTrace(); + if (!stack_trace_cache.validate(this)) return false; // node.getFrameNo() is not valid + if (node.getFrameNo() < 0) { + set(null, null, new HashMap<String,TCFNode>()); + return true; + } assert command == null; command = exps.getChildren(node.id, new IExpressions.DoneGetChildren() { public void doneGetChildren(IToken token, Exception error, String[] contexts) { diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenRegisters.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenRegisters.java index d07ba58ce..7168b9c70 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenRegisters.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenRegisters.java @@ -19,9 +19,9 @@ import org.eclipse.tm.tcf.services.IRegisters; public class TCFChildrenRegisters extends TCFChildren { - private final TCFNodeStackFrame node; + private final TCFNode node; - TCFChildrenRegisters(TCFNodeStackFrame node) { + TCFChildrenRegisters(TCFNode node) { super(node.channel, 128); this.node = node; } @@ -38,27 +38,31 @@ public class TCFChildrenRegisters extends TCFChildren { @Override protected boolean startDataRetrieval() { - TCFChildrenStackTrace stack_trace_cache = ((TCFNodeExecContext)node.parent).getStackTrace(); - if (!stack_trace_cache.validate(this)) return false; // node.getFrameNo() is not valid IRegisters regs = node.model.getLaunch().getService(IRegisters.class); - final int frame_no = node.getFrameNo(); - if (regs == null || frame_no < 0) { + if (regs == null) { set(null, null, new HashMap<String,TCFNode>()); return true; } + if (node instanceof TCFNodeStackFrame) { + TCFChildrenStackTrace stack_trace_cache = ((TCFNodeExecContext)node.parent).getStackTrace(); + if (!stack_trace_cache.validate(this)) return false; // node.getFrameNo() is not valid + final int frame_no = ((TCFNodeStackFrame)node).getFrameNo(); + if (frame_no < 0) { + set(null, null, new HashMap<String,TCFNode>()); + return true; + } + } assert command == null; - final TCFNode parent = frame_no == 0 ? node.parent : node; - command = regs.getChildren(parent.id, new IRegisters.DoneGetChildren() { + command = regs.getChildren(node.id, new IRegisters.DoneGetChildren() { public void doneGetChildren(IToken token, Exception error, String[] contexts) { Map<String,TCFNode> data = null; if (command == token && error == null) { int index = 0; data = new HashMap<String,TCFNode>(); for (String id : contexts) { - TCFNode n = node.model.getNode(id); - if (n == null) n = new TCFNodeRegister(parent, id); - assert n.parent == parent; - ((TCFNodeRegister)n).setIndex(index++); + TCFNodeRegister n = (TCFNodeRegister)node.model.getNode(id); + if (n == null) n = new TCFNodeRegister(node, id); + n.setIndex(index++); data.put(id, n); } } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java index c64444ce3..854bf3036 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java @@ -36,6 +36,15 @@ public class TCFChildrenSubExpressions extends TCFChildren { reset(); for (TCFNode n : getNodes()) { if (n instanceof TCFNodeExpression) ((TCFNodeExpression)n).onSuspended(); + if (n instanceof TCFNodeArrayPartition) ((TCFNodeArrayPartition)n).onSuspended(); + } + } + + void onValueChanged() { + reset(); + for (TCFNode n : getNodes()) { + if (n instanceof TCFNodeExpression) ((TCFNodeExpression)n).onValueChanged(); + if (n instanceof TCFNodeArrayPartition) ((TCFNodeArrayPartition)n).onValueChanged(); } } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java index af9c856bb..48eb2b2d6 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java @@ -47,6 +47,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactor import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactory; 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.IViewerInputUpdate; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.IDebugView; @@ -116,7 +118,7 @@ import org.eclipse.ui.texteditor.ITextEditor; * keeping the cache in a coherent state, * and feeding UI with up-to-date data. */ -public class TCFModel implements IElementContentProvider, IElementLabelProvider, +public class TCFModel implements IElementContentProvider, IElementLabelProvider, IViewerInputProvider, IModelProxyFactory, IColumnPresentationFactory, ISourceDisplay, ISuspendTrigger { private final TCFLaunch launch; @@ -601,27 +603,24 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, }); } - /** - * Create and post ModelDelta for changes in this node. - * @param flags - description of what has changed: IModelDelta.ADDED, IModelDelta.REMOVED, etc. - */ - final void addDelta(TCFNode node, int flags) { - for (TCFModelProxy p : model_proxies) { - int f = flags & node.getRelevantModelDeltaFlags(p.getPresentationContext()); - if (f != 0) p.addDelta(node, f); - } - } - - void launchChanged() { if (launch_node != null) { - launch_node.addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + for (TCFModelProxy p : model_proxies) { + String id = p.getPresentationContext().getId(); + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(id)) { + p.addDelta(launch_node, IModelDelta.STATE | IModelDelta.CONTENT); + } + } } else { refreshLaunchView(); } } + Set<TCFModelProxy> getModelProxies() { + return model_proxies; + } + void dispose() { if (console != null) { display.asyncExec(new Runnable() { @@ -762,6 +761,17 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, } } + public void update(IViewerInputUpdate update) { + Object o = update.getElement(); + if (o instanceof TCFLaunch) { + update.setInputElement(o); + update.done(); + } + else { + ((TCFNode)o).update(update); + } + } + public IModelProxy createModelProxy(Object element, IPresentationContext context) { return new TCFModelProxy(this); } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java index 82951b7c0..d8ea92914 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java @@ -22,6 +22,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.Viewer; import org.eclipse.tm.tcf.protocol.Protocol; @@ -29,6 +30,7 @@ import org.eclipse.tm.tcf.protocol.Protocol; /** * A model proxy represents a model for a specific presentation context and * fires deltas to notify listeners of changes in the model. + * Model proxy listeners are debuggers views. */ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Runnable { @@ -43,6 +45,7 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru private TCFNode selection; private boolean posted; + private boolean installed; private boolean disposed; private long last_update_time; @@ -78,7 +81,7 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru } public Object getViewerInput() { - return TCFModelProxy.this.getViewer().getInput(); + return TCFModelProxy.this.getInput(); } public void cancel() { @@ -145,8 +148,10 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru super.installed(viewer); Protocol.invokeAndWait(new Runnable() { public void run() { + assert !installed; assert !disposed; model.onProxyInstalled(TCFModelProxy.this); + installed = true; } }); } @@ -154,6 +159,7 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru public void dispose() { Protocol.invokeAndWait(new Runnable() { public void run() { + assert installed; assert !disposed; model.onProxyDisposed(TCFModelProxy.this); disposed = true; @@ -162,6 +168,12 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru super.dispose(); } + /** + * Add model change information (delta) to a buffer of pending deltas. + * Implementation will coalesce and post deltas to the view. + * @param node - a model node that changed. + * @param flags - flags that describe the change, see IModelDelta + */ void addDelta(TCFNode node, int flags) { if (flags == 0) return; Integer delta = node2flags.get(node); @@ -174,6 +186,10 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru post(); } + /** + * Request view selection to be set to given node. + * @param node - a model node that will become new selection. + */ void setSelection(TCFNode node) { selection = node; while (node.parent != null) { @@ -183,6 +199,14 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru post(); } + /** + * Get current value of the view input. + * @return view input object. + */ + Object getInput() { + return getViewer().getInput(); + } + private void post() { assert Protocol.isDispatchThread(); if (!posted) { @@ -229,7 +253,8 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru private ModelDelta makeDelta(ModelDelta root, TCFNode node, int flags, boolean selection_delta) { ModelDelta delta = node2delta.get(node); if (delta == null) { - if (node.parent == null) { + TCFNode parent = node.parent; + if (parent == null) { if (root.getElement() instanceof TCFNode) return null; int children = -1; if (selection_delta || (flags & IModelDelta.EXPAND) != 0) { @@ -242,11 +267,11 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru } else { int parent_flags = 0; - Integer parent_flags_obj = node2flags.get(node.parent); + Integer parent_flags_obj = node2flags.get(parent); if (parent_flags_obj != null) parent_flags = parent_flags_obj; if ((parent_flags & IModelDelta.REMOVED) != 0) return null; - ModelDelta parent = makeDelta(root, node.parent, parent_flags, selection_delta); - if (parent == null) return null; + ModelDelta up = makeDelta(root, parent, parent_flags, selection_delta); + if (up == null) return null; int index = -1; int children = -1; if ((flags & IModelDelta.INSERTED) != 0) { @@ -256,7 +281,7 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru if (index < 0) index = getNodeIndex(node); children = getNodeChildren(node).length; } - delta = parent.addNode(node, index, flags, children); + delta = up.addNode(node, index, flags, children); } node2delta.put(node, delta); } @@ -276,12 +301,29 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru assert Protocol.isDispatchThread(); if (disposed) return; if (node2flags.isEmpty() && selection == null) return; + Object input = getInput(); + int flags = 0; + if (input instanceof TCFNode) { + // Optimize away STATE delta on a view input node + TCFNode node = (TCFNode)input; + Integer i = node2flags.get(node); + if (i != null) { + flags = i; + if ((flags & IModelDelta.STATE) != 0) { + flags &= ~IModelDelta.STATE; + if (flags == 0) { + node2flags.remove(node); + if (node2flags.isEmpty() && selection == null) return; + } + else { + node2flags.put(node, flags); + } + } + } + } pending_node = null; node2children.clear(); node2delta.clear(); - Object input = getViewer().getInput(); - int flags = 0; - if (node2flags.containsKey(input)) flags = node2flags.get(input); ModelDelta root = new ModelDelta(input, flags); for (TCFNode node : node2flags.keySet()) makeDelta(root, node, node2flags.get(node), false); if (pending_node == null) { diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java index 1ea777143..d4e913b04 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java @@ -17,8 +17,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpd 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.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.Protocol; @@ -148,20 +147,20 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo /** * Retrieve children count for a presentation context. - * @param result - children count update request. + * @param update - children count update request. */ - final void update(final IChildrenCountUpdate result) { - new TCFRunnable(result) { + final void update(final IChildrenCountUpdate update) { + new TCFRunnable(update) { public void run() { if (!done) { - if (!result.isCanceled()) { + if (!update.isCanceled()) { if (!disposed && channel.getState() == IChannel.STATE_OPEN) { - if (!getData(result, this)) return; + if (!getData(update, this)) return; } else { - result.setChildCount(0); + update.setChildCount(0); } - result.setStatus(Status.OK_STATUS); + update.setStatus(Status.OK_STATUS); } done(); } @@ -171,17 +170,17 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo /** * Retrieve children for a presentation context. - * @param result - children update request. + * @param update - children update request. */ - final void update(final IChildrenUpdate result) { - new TCFRunnable(result) { + final void update(final IChildrenUpdate update) { + new TCFRunnable(update) { public void run() { if (!done) { - if (!result.isCanceled()) { + if (!update.isCanceled()) { if (!disposed && channel.getState() == IChannel.STATE_OPEN) { - if (!getData(result, this)) return; + if (!getData(update, this)) return; } - result.setStatus(Status.OK_STATUS); + update.setStatus(Status.OK_STATUS); } done(); } @@ -191,21 +190,21 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo /** * Check if node has children in a presentation context. - * @param result - "has children" update request. + * @param update - "has children" update request. */ - final void update(final IHasChildrenUpdate result) { - new TCFRunnable(result) { + final void update(final IHasChildrenUpdate update) { + new TCFRunnable(update) { public void run() { if (!done) { - if (!result.isCanceled()) { + if (!update.isCanceled()) { IChannel channel = model.getLaunch().getChannel(); if (!disposed && channel.getState() == IChannel.STATE_OPEN) { - if (!getData(result, this)) return; + if (!getData(update, this)) return; } else { - result.setHasChilren(false); + update.setHasChilren(false); } - result.setStatus(Status.OK_STATUS); + update.setStatus(Status.OK_STATUS); } done(); } @@ -215,20 +214,43 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo /** * Retrieve node label for a presentation context. - * @param result - label update request. + * @param update - label update request. */ - final void update(final ILabelUpdate result) { - new TCFRunnable(result) { + final void update(final ILabelUpdate update) { + new TCFRunnable(update) { public void run() { if (!done) { - if (!result.isCanceled()) { + if (!update.isCanceled()) { if (!disposed && channel.getState() == IChannel.STATE_OPEN) { - if (!getData(result, this)) return; + if (!getData(update, this)) return; } else { - result.setLabel("...", 0); + update.setLabel("...", 0); } - result.setStatus(Status.OK_STATUS); + update.setStatus(Status.OK_STATUS); + } + done(); + } + } + }; + } + + /** + * Retrieve viewer input object for a presentation context. + * @param update - input update request. + */ + final void update(final IViewerInputUpdate update) { + new TCFRunnable(update) { + public void run() { + if (!done) { + if (!update.isCanceled()) { + if (!disposed && channel.getState() == IChannel.STATE_OPEN) { + if (!getData(update, this)) return; + } + else { + update.setInputElement(update.getElement()); + } + update.setStatus(Status.OK_STATUS); } done(); } @@ -239,70 +261,65 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo /** * Retrieve children count for a presentation context. * The method is always called on TCF dispatch thread. - * @param result - children count update request. + * @param update - children count update request. * @param done - client call back interface, during data waiting it is * called every time new portion of data becomes available. * @return false if waiting data retrieval, true if all done. */ - protected boolean getData(IChildrenCountUpdate result, Runnable done) { - result.setChildCount(0); + protected boolean getData(IChildrenCountUpdate update, Runnable done) { + update.setChildCount(0); return true; } /** * Retrieve children for a presentation context. * The method is always called on TCF dispatch thread. - * @param result - children update request. + * @param update - children update request. * @param done - client call back interface, during data waiting it is * called every time new portion of data becomes available. * @return false if waiting data retrieval, true if all done. */ - protected boolean getData(IChildrenUpdate result, Runnable done) { + protected boolean getData(IChildrenUpdate update, Runnable done) { return true; } /** * Check if the node has children in a presentation context. * The method is always called on TCF dispatch thread. - * @param result - "has children" update request. + * @param update - "has children" update request. * @param done - client call back interface, during data waiting it is * called every time new portion of data becomes available. * @return false if waiting data retrieval, true if all done. */ - protected boolean getData(IHasChildrenUpdate result, Runnable done) { - result.setHasChilren(false); + protected boolean getData(IHasChildrenUpdate update, Runnable done) { + update.setHasChilren(false); return true; } /** * Retrieve node label for a presentation context. * The method is always called on TCF dispatch thread. - * @param result - label update request. + * @param update - label update request. * @param done - client call back interface, during data waiting it is * called every time new portion of data becomes available. * @return false if waiting data retrieval, true if all done. */ - protected boolean getData(ILabelUpdate result, Runnable done) { - result.setLabel(id, 0); + protected boolean getData(ILabelUpdate update, Runnable done) { + update.setLabel(id, 0); return true; } /** - * Create and post ModelDelta for changes in this node. - * @param flags - description of what has changed: IModelDelta.ADDED, IModelDelta.REMOVED, etc. - */ - final void addModelDelta(int flags) { - model.addDelta(this, flags); - } - - /** - * Return bit set of model delta flags relevant for this node in given presentation context. - * Sub-classes are supposed to override this method. - * @param p - presentation context - * @return bit set of model delta flags + * Retrieve viewer input object for a presentation context. + * The method is always called on TCF dispatch thread. + * @param update - view input update request. + * @param done - client call back interface, during data waiting it is + * called every time new portion of data becomes available. + * @return false if waiting data retrieval, true if all done. */ - int getRelevantModelDeltaFlags(IPresentationContext p) { - return IModelDelta.CONTENT | IModelDelta.STATE | IModelDelta.ADDED | IModelDelta.REMOVED; + protected boolean getData(IViewerInputUpdate update, Runnable done) { + update.setInputElement(update.getElement()); + return true; } /*--------------------------------------------------------------------------------------*/ diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java index 15e0a4827..4d36422db 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java @@ -14,8 +14,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpd 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.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.tm.internal.tcf.debug.ui.ImageCache; public class TCFNodeArrayPartition extends TCFNode { @@ -101,13 +99,12 @@ public class TCFNodeArrayPartition extends TCFNode { return true; } - @Override - int getRelevantModelDeltaFlags(IPresentationContext p) { - if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(p.getId()) || - IDebugUIConstants.ID_VARIABLE_VIEW.equals(p.getId())) { - return super.getRelevantModelDeltaFlags(p); - } - return 0; + void onSuspended() { + children.onSuspended(); + } + + void onValueChanged() { + children.onValueChanged(); } @Override diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java index 678723985..295d9d544 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java @@ -22,6 +22,7 @@ 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.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.swt.graphics.RGB; import org.eclipse.tm.internal.tcf.debug.model.TCFContextState; @@ -43,6 +44,7 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { private final TCFChildrenExecContext children_exec; private final TCFChildrenStackTrace children_stack; + private final TCFChildrenRegisters children_regs; private final TCFDataCache<IMemory.MemoryContext> mem_context; private final TCFDataCache<IRunControl.RunControlContext> run_context; @@ -149,6 +151,7 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { seq_no = seq_cnt++; children_exec = new TCFChildrenExecContext(this); children_stack = new TCFChildrenStackTrace(this); + children_regs = new TCFChildrenRegisters(this); line_info_cache = new LinkedHashMap<BigInteger,TCFSourceRef>() { protected boolean removeEldestEntry(Map.Entry<BigInteger,TCFSourceRef> eldest) { return size() > 256; @@ -332,6 +335,7 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { signal_mask.dispose(); children_exec.dispose(); children_stack.dispose(); + children_regs.dispose(); ArrayList<TCFNodeSymbol> l = new ArrayList<TCFNodeSymbol>(symbols.values()); for (TCFNodeSymbol s : l) s.dispose(); assert symbols.size() == 0; @@ -342,6 +346,7 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { void dispose(String id) { children_exec.dispose(id); children_stack.dispose(id); + children_regs.dispose(id); } void setRunContext(IRunControl.RunControlContext ctx) { @@ -412,22 +417,31 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { @Override protected boolean getData(IChildrenCountUpdate result, Runnable done) { - if (!run_context.validate(done)) return false; - IRunControl.RunControlContext ctx = run_context.getData(); - if (ctx != null && ctx.hasState()) { - if (!children_stack.validate(done)) return false; - if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { - TCFNodeStackFrame frame = children_stack.getTopFrame(); - if (frame != null) return frame.getData(result, done); - result.setChildCount(0); + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { + if (!run_context.validate(done)) return false; + IRunControl.RunControlContext ctx = run_context.getData(); + if (ctx != null && ctx.hasState()) { + if (!children_stack.validate(done)) return false; + result.setChildCount(children_stack.size()); } else { - result.setChildCount(children_stack.size()); + if (!children_exec.validate(done)) return false; + result.setChildCount(children_exec.size()); + } + } + else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) { + if (!run_context.validate(done)) return false; + IRunControl.RunControlContext ctx = run_context.getData(); + if (ctx != null && ctx.hasState()) { + if (!children_regs.validate(done)) return false; + result.setChildCount(children_regs.size()); + } + else { + result.setChildCount(0); } } else { - if (!children_exec.validate(done)) return false; - result.setChildCount(children_exec.size()); + result.setChildCount(0); } return true; } @@ -435,53 +449,67 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { @Override protected boolean getData(IChildrenUpdate result, Runnable done) { TCFNode[] arr = null; - if (!run_context.validate(done)) return false; - IRunControl.RunControlContext ctx = run_context.getData(); - if (ctx != null && ctx.hasState()) { - if (!children_stack.validate(done)) return false; - if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { - TCFNodeStackFrame frame = children_stack.getTopFrame(); - if (frame != null) return frame.getData(result, done); - arr = new TCFNode[0]; + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { + if (!run_context.validate(done)) return false; + IRunControl.RunControlContext ctx = run_context.getData(); + if (ctx != null && ctx.hasState()) { + if (!children_stack.validate(done)) return false; + arr = children_stack.toArray(); } else { - arr = children_stack.toArray(); + if (!children_exec.validate(done)) return false; + arr = children_exec.toArray(); } } - else { - if (!children_exec.validate(done)) return false; - arr = children_exec.toArray(); - } - int offset = 0; - int r_offset = result.getOffset(); - int r_length = result.getLength(); - for (TCFNode n : arr) { - if (offset >= r_offset && offset < r_offset + r_length) { - result.setChild(n, offset); + else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) { + if (!run_context.validate(done)) return false; + IRunControl.RunControlContext ctx = run_context.getData(); + if (ctx != null && ctx.hasState()) { + if (!children_regs.validate(done)) return false; + arr = children_regs.toArray(); + } + } + if (arr != null) { + int offset = 0; + int r_offset = result.getOffset(); + int r_length = result.getLength(); + for (TCFNode n : arr) { + if (offset >= r_offset && offset < r_offset + r_length) { + result.setChild(n, offset); + } + offset++; } - offset++; } return true; } @Override protected boolean getData(IHasChildrenUpdate result, Runnable done) { - if (!run_context.validate(done)) return false; - IRunControl.RunControlContext ctx = run_context.getData(); - if (ctx != null && ctx.hasState()) { - if (!children_stack.validate(done)) return false; - if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { - TCFNodeStackFrame frame = children_stack.getTopFrame(); - if (frame == null) result.setHasChilren(false); - else if (!frame.getData(result, done)) return false; + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { + if (!run_context.validate(done)) return false; + IRunControl.RunControlContext ctx = run_context.getData(); + if (ctx != null && ctx.hasState()) { + if (!children_stack.validate(done)) return false; + result.setHasChilren(children_stack.size() > 0); } else { - result.setHasChilren(children_stack.size() > 0); + if (!children_exec.validate(done)) return false; + result.setHasChilren(children_exec.size() > 0); + } + } + else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) { + if (!run_context.validate(done)) return false; + IRunControl.RunControlContext ctx = run_context.getData(); + if (ctx != null && ctx.hasState()) { + if (!children_regs.validate(done)) return false; + result.setHasChilren(children_regs.size() > 0); + } + else { + result.setHasChilren(false); } } else { - if (!children_exec.validate(done)) return false; - result.setHasChilren(children_exec.size() > 0); + result.setHasChilren(false); } return true; } @@ -536,6 +564,48 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { return true; } + @Override + protected boolean getData(IViewerInputUpdate result, Runnable done) { + result.setInputElement(result.getElement()); + if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId()) && + !IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) { + if (!children_stack.validate(done)) return false; + TCFNodeStackFrame frame = children_stack.getTopFrame(); + if (frame != null) result.setInputElement(frame); + } + return true; + } + + void postAllChangedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + p.addDelta(this, IModelDelta.STATE | IModelDelta.CONTENT); + } + } + + void postContextAddedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + p.addDelta(this, IModelDelta.ADDED); + } + } + + private void postContextRemovedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + p.addDelta(this, IModelDelta.REMOVED); + } + } + + private void postContentChangedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + p.addDelta(this, IModelDelta.CONTENT); + } + } + + private void postStateChangedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + p.addDelta(this, IModelDelta.STATE); + } + } + void onContextAdded(IRunControl.RunControlContext context) { children_exec.onContextAdded(context); } @@ -547,8 +617,9 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { state.reset(); children_stack.reset(); children_stack.onSourceMappingChange(); + children_regs.reset(); for (TCFNodeSymbol s : symbols.values()) s.onMemoryMapChanged(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + postAllChangedDelta(); } void onContextAdded(IMemory.MemoryContext context) { @@ -559,14 +630,14 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { assert !disposed; mem_context.reset(context); for (TCFNodeSymbol s : symbols.values()) s.onMemoryMapChanged(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + postAllChangedDelta(); } void onContextRemoved() { assert !disposed; resumed_cnt++; dispose(); - addModelDelta(IModelDelta.REMOVED); + postContextRemovedDelta(); } void onContainerSuspended() { @@ -579,7 +650,8 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { state.reset(); address.reset(); children_stack.onSuspended(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + children_regs.onSuspended(); + postAllChangedDelta(); } void onContainerResumed() { @@ -591,7 +663,7 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { } state.reset(); for (TCFNodeSymbol s : symbols.values()) s.onExeStateChange(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + postAllChangedDelta(); } void onContextSuspended(String pc, String reason, Map<String,Object> params) { @@ -611,34 +683,31 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { signal_mask.reset(); resumed_cnt++; children_stack.onSuspended(); + children_regs.onSuspended(); for (TCFNodeSymbol s : symbols.values()) s.onExeStateChange(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + postAllChangedDelta(); } void onContextResumed() { assert !disposed; state.reset(new TCFContextState()); - addModelDelta(IModelDelta.STATE); + postStateChangedDelta(); final int cnt = ++resumed_cnt; Protocol.invokeLater(250, new Runnable() { public void run() { if (cnt != resumed_cnt) return; if (disposed) return; children_stack.onResumed(); - addModelDelta(IModelDelta.CONTENT); - if (parent instanceof TCFNodeExecContext) { - ((TCFNodeExecContext)parent).onChildResumedOrSuspended(); + postContentChangedDelta(); + TCFNode n = parent; + while (n instanceof TCFNodeExecContext) { + ((TCFNodeExecContext)n).postStateChangedDelta(); + n = n.parent; } } }); } - void onChildResumedOrSuspended() { - IRunControl.RunControlContext ctx = run_context.getData(); - if (ctx != null && ctx.isContainer()) addModelDelta(IModelDelta.STATE); - if (parent instanceof TCFNodeExecContext) ((TCFNodeExecContext)parent).onChildResumedOrSuspended(); - } - void onContextException(String msg) { } @@ -654,14 +723,14 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { void onRegistersChanged() { children_stack.onRegistersChanged(); - addModelDelta(IModelDelta.CONTENT); + postContentChangedDelta(); } void onRegisterValueChanged() { state.reset(); address.reset(); children_stack.onRegisterValueChanged(); - addModelDelta(IModelDelta.CONTENT); + postContentChangedDelta(); } // Return true if at least one child is suspended. diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java index f9da18815..e947c1838 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java @@ -198,8 +198,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT return true; } if (cast != null) e = "(" + cast + ")(" + e + ")"; - TCFNode n = parent; - while (n instanceof TCFNodeExpression || n instanceof TCFNodeArrayPartition) n = n.parent; + TCFNode n = getRootExpression().parent; if (n instanceof TCFNodeStackFrame && ((TCFNodeStackFrame)n).isEmulated()) n = n.parent; command = exps.create(n.id, null, e, new IExpressions.DoneCreate() { public void doneCreate(IToken token, Exception error, IExpressions.Expression context) { @@ -436,14 +435,41 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT children.dispose(id); } + private TCFNodeExpression getRootExpression() { + TCFNode n = this; + while (n.parent instanceof TCFNodeExpression || n.parent instanceof TCFNodeArrayPartition) n = n.parent; + return (TCFNodeExpression)n; + } + + private void postAllChangedDelta() { + TCFNodeExpression n = getRootExpression(); + for (TCFModelProxy p : model.getModelProxies()) { + String id = p.getPresentationContext().getId(); + if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(id) && n.script != null || + IDebugUIConstants.ID_VARIABLE_VIEW.equals(id) && n.script == null) { + p.addDelta(this, IModelDelta.STATE | IModelDelta.CONTENT); + } + } + } + void onSuspended() { prev_value = next_value; + if (expression.isValid() && expression.getError() != null) expression.reset(); value.reset(); type.reset(); type_name.reset(); string.reset(); children.onSuspended(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + postAllChangedDelta(); + } + + void onValueChanged() { + value.reset(); + type.reset(); + type_name.reset(); + string.reset(); + children.onValueChanged(); + postAllChangedDelta(); } public void onCastToTypeChanged() { @@ -453,7 +479,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT type_name.cancel(); string.cancel(); children.onCastToTypeChanged(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + postAllChangedDelta(); } String getScript() { @@ -754,7 +780,6 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT if (error == null) error = value.getError(); String[] cols = result.getColumnIds(); if (error != null) { - error.printStackTrace(); if (cols == null || cols.length <= 1) { result.setForeground(new RGB(255, 0, 0), 0); result.setLabel(name + ": N/A", 0); @@ -1023,15 +1048,6 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT } @Override - int getRelevantModelDeltaFlags(IPresentationContext p) { - if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(p.getId()) || - IDebugUIConstants.ID_VARIABLE_VIEW.equals(p.getId())) { - return super.getRelevantModelDeltaFlags(p); - } - return 0; - } - - @Override public int compareTo(TCFNode n) { TCFNodeExpression e = (TCFNodeExpression)n; if (sort_pos < e.sort_pos) return -1; @@ -1158,16 +1174,12 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT IExpressions exps = node.model.getLaunch().getService(IExpressions.class); exps.assign(exp.getID(), bf, new IExpressions.DoneAssign() { public void doneAssign(IToken token, Exception error) { - TCFNodeExpression n = node; - while (n.parent instanceof TCFNodeExpression) n = (TCFNodeExpression)n.parent; - n.onSuspended(); + node.getRootExpression().onValueChanged(); if (error != null) { node.model.showMessageBox("Cannot modify element value", error); done(Boolean.FALSE); } else { - node.value.reset(); - node.addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); done(Boolean.TRUE); } } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java index c490af3f8..5670b9486 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java @@ -18,6 +18,7 @@ import java.util.Map; 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; +import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.tm.internal.tcf.debug.model.TCFContextState; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.tcf.services.IMemory; @@ -80,31 +81,43 @@ public class TCFNodeLaunch extends TCFNode implements ISymbolOwner { @Override protected boolean getData(IChildrenCountUpdate result, Runnable done) { - if (!children.validate(done)) return false; - result.setChildCount(children.size()); + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { + if (!children.validate(done)) return false; + result.setChildCount(children.size()); + } + else { + result.setChildCount(0); + } return true; } @Override protected boolean getData(IChildrenUpdate result, Runnable done) { - if (!children.validate(done)) return false; - TCFNode[] arr = children.toArray(); - int offset = 0; - int r_offset = result.getOffset(); - int r_length = result.getLength(); - for (TCFNode n : arr) { - if (offset >= r_offset && offset < r_offset + r_length) { - result.setChild(n, offset); + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { + if (!children.validate(done)) return false; + TCFNode[] arr = children.toArray(); + int offset = 0; + int r_offset = result.getOffset(); + int r_length = result.getLength(); + for (TCFNode n : arr) { + if (offset >= r_offset && offset < r_offset + r_length) { + result.setChild(n, offset); + } + offset++; } - offset++; } return true; } @Override protected boolean getData(IHasChildrenUpdate result, Runnable done) { - if (!children.validate(done)) return false; - result.setHasChilren(children.size() > 0); + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) { + if (!children.validate(done)) return false; + result.setHasChilren(children.size() > 0); + } + else { + result.setHasChilren(false); + } return true; } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java index 2586d4f58..862b635ee 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java @@ -23,6 +23,7 @@ import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Composite; +import org.eclipse.tm.internal.tcf.debug.model.TCFContextState; import org.eclipse.tm.internal.tcf.debug.ui.ImageCache; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IRegisters; @@ -62,6 +63,12 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor { value = new TCFDataCache<byte[]>(channel) { @Override protected boolean startDataRetrieval() { + Boolean b = usePrevValue(this); + if (b == null) return false; + if (b) { + set(null, null, prev_value); + return true; + } if (!context.validate(this)) return false; IRegisters.RegistersContext ctx = context.getData(); if (ctx == null) { @@ -70,6 +77,13 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor { } command = ctx.get(new IRegisters.DoneGet() { public void doneGet(IToken token, Exception error, byte[] value) { + if (error != null) { + Boolean b = usePrevValue(null); + if (b != null && b) { + set(token, null, prev_value); + return; + } + } set(token, error, value); } }); @@ -89,6 +103,32 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor { this.index = index; } + private Boolean usePrevValue(Runnable done) { + // Check if view should show old value. + // Old value is shown if context is running or + // stack trace does not contain expression parent frame. + // Return null if waiting for cache update. + if (prev_value == null) return false; + if (parent instanceof TCFNodeStackFrame) { + TCFNodeExecContext exe = (TCFNodeExecContext)parent.parent; + TCFDataCache<TCFContextState> state_cache = exe.getState(); + if (!state_cache.validate(done)) return null; + TCFContextState state = state_cache.getData(); + if (state == null || !state.is_suspended) return true; + TCFChildrenStackTrace stack_trace_cache = exe.getStackTrace(); + if (!stack_trace_cache.validate(done)) return null; + if (stack_trace_cache.getData().get(parent.id) == null) return true; + } + else { + TCFNodeExecContext exe = (TCFNodeExecContext)parent; + TCFDataCache<TCFContextState> state_cache = exe.getState(); + if (!state_cache.validate(done)) return null; + TCFContextState state = state_cache.getData(); + if (state == null || !state.is_suspended) return true; + } + return false; + } + private void appendErrorText(StringBuffer bf, Throwable error) { if (error == null) return; bf.append("Exception: "); @@ -296,12 +336,11 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor { return ""; } - @Override - int getRelevantModelDeltaFlags(IPresentationContext p) { - if (IDebugUIConstants.ID_REGISTER_VIEW.equals(p.getId())) { - return super.getRelevantModelDeltaFlags(p); + private void postStateChangedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + if (!IDebugUIConstants.ID_REGISTER_VIEW.equals(p.getPresentationContext().getId())) continue; + p.addDelta(this, IModelDelta.STATE); } - return 0; } void onValueChanged() { @@ -311,22 +350,23 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor { while (n != null) { if (n instanceof TCFNodeExecContext) { ((TCFNodeExecContext)n).onRegisterValueChanged(); + break; } n = n.parent; } - addModelDelta(IModelDelta.STATE); + postStateChangedDelta(); } void onSuspended() { prev_value = next_value; value.reset(); - addModelDelta(IModelDelta.STATE); + postStateChangedDelta(); } void onRegistersChanged() { context.reset(); value.reset(); - addModelDelta(IModelDelta.STATE); + postStateChangedDelta(); } public CellEditor getCellEditor(IPresentationContext context, String column_id, Object element, Composite parent) { @@ -415,7 +455,7 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor { } else { node.value.reset(); - node.addModelDelta(IModelDelta.STATE); + node.postStateChangedDelta(); done(Boolean.TRUE); } } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java index 4af131048..e6e84d5b0 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java @@ -19,6 +19,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdat import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.swt.graphics.RGB; import org.eclipse.tm.internal.tcf.debug.model.TCFContextState; @@ -339,6 +340,18 @@ public class TCFNodeStackFrame extends TCFNode { return true; } + @Override + protected boolean getData(IViewerInputUpdate result, Runnable done) { + result.setInputElement(result.getElement()); + if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) { + TCFNodeExecContext exe = (TCFNodeExecContext)parent; + TCFChildrenStackTrace stack_trace_cache = exe.getStackTrace(); + if (!stack_trace_cache.validate(done)) return false; + if (stack_trace_cache.getTopFrame() == this) result.setInputElement(exe); + } + return true; + } + private String getModuleName(BigInteger pc, Runnable done) { TCFDataCache<IRunControl.RunControlContext> parent_dc = ((TCFNodeExecContext)parent).getRunContext(); if (!parent_dc.validate(done)) return null; @@ -372,9 +385,37 @@ public class TCFNodeStackFrame extends TCFNode { return "0x0000000000000000".substring(0, 2 + l) + s; } + private void postAllChangedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + int flags = 0; + String id = p.getPresentationContext().getId(); + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(id)) flags |= IModelDelta.STATE; + if (getChildren(p.getPresentationContext()) != null && p.getInput() == this) flags |= IModelDelta.CONTENT; + if (flags != 0) p.addDelta(this, flags); + } + } + + private void postStateChangedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + String id = p.getPresentationContext().getId(); + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(id)) { + p.addDelta(this, IModelDelta.STATE); + } + } + } + + void postExpressionAddedOrRemovedDelta() { + for (TCFModelProxy p : model.getModelProxies()) { + String id = p.getPresentationContext().getId(); + if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(id) && p.getInput() == this) { + p.addDelta(this, IModelDelta.CONTENT); + } + } + } + void onSourceMappingChange() { line_info.reset(); - addModelDelta(IModelDelta.STATE); + postStateChangedDelta(); } void onSuspended() { @@ -384,23 +425,24 @@ public class TCFNodeStackFrame extends TCFNode { children_regs.onSuspended(); children_vars.onSuspended(); children_exps.onSuspended(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + postAllChangedDelta(); } void onMemoryMapChanged() { - addModelDelta(IModelDelta.STATE); + line_info.reset(); + postStateChangedDelta(); } void onRegistersChanged() { children_regs.onRegistersChanged(); - addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); + postAllChangedDelta(); } void onRegisterValueChanged() { stack_trace_context.cancel(); line_info.cancel(); address.cancel(); - addModelDelta(IModelDelta.STATE); + postStateChangedDelta(); } @Override |