diff options
author | eutarass | 2011-02-09 16:12:48 +0000 |
---|---|---|
committer | eutarass | 2011-02-09 16:12:48 +0000 |
commit | 53698df1607ff0ef5e140ca70f24dd6d2d50b03f (patch) | |
tree | efa3ecbb1332cbdc0e02b574bbe1473f5cb9af7f /plugins | |
parent | 168006b2ef95d874747b0dc7bce41b59b7091f0c (diff) | |
download | org.eclipse.tcf-53698df1607ff0ef5e140ca70f24dd6d2d50b03f.tar.gz org.eclipse.tcf-53698df1607ff0ef5e140ca70f24dd6d2d50b03f.tar.xz org.eclipse.tcf-53698df1607ff0ef5e140ca70f24dd6d2d50b03f.zip |
TCF Debugger: added code to display breakpoint status info in UI
Diffstat (limited to 'plugins')
9 files changed, 290 insertions, 13 deletions
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/Activator.java b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/Activator.java index acb054e54..2bf3d1b5e 100644 --- a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/Activator.java +++ b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/Activator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2011 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.swt.widgets.Shell; +import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.plugin.AbstractUIPlugin; @@ -26,14 +27,28 @@ public class Activator extends AbstractUIPlugin { public static final String PLUGIN_ID = "org.eclipse.tm.tcf.cdt.ui"; private static Activator plugin; + private static TCFBreakpointStatusListener bp_status_listener; public void start(BundleContext context) throws Exception { super.start(context); plugin = this; + Protocol.invokeLater(new Runnable() { + public void run() { + if (bp_status_listener == null) bp_status_listener = new TCFBreakpointStatusListener(); + } + }); EvaluationContextManager.startup(); } public void stop(BundleContext context) throws Exception { + Protocol.invokeAndWait(new Runnable() { + public void run() { + if (bp_status_listener != null) { + bp_status_listener.dispose(); + bp_status_listener = null; + } + } + }); plugin = null; super.stop(context); } diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFBreakpointStatusListener.java b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFBreakpointStatusListener.java new file mode 100644 index 000000000..766a920e0 --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFBreakpointStatusListener.java @@ -0,0 +1,151 @@ +/*******************************************************************************
+ * Copyright (c) 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.cdt.ui;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.debug.core.model.ICBreakpoint;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tm.internal.tcf.debug.model.ITCFBreakpointListener;
+import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpointsModel;
+import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpointsStatus;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModelManager;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+
+/**
+ * This class monitors breakpoints status on TCF debug targets and calls ICBreakpoint.incrementInstallCount() or
+ * ICBreakpoint.decrementInstallCount() when breakpoint status changes.
+ */
+class TCFBreakpointStatusListener {
+
+ private class BreakpointListener implements ITCFBreakpointListener {
+
+ private final TCFBreakpointsStatus status;
+ private final Set<ICBreakpoint> installed;
+
+ BreakpointListener(TCFLaunch launch) {
+ status = launch.getBreakpointsStatus();
+ status.addListener(this);
+ bp_listeners.put(launch, this);
+ installed = new HashSet<ICBreakpoint>();
+ for (String id : status.getStatusIDs()) breakpointStatusChanged(id);
+ }
+
+ public void breakpointStatusChanged(String id) {
+ IBreakpoint bp = bp_model.getBreakpoint(id);
+ if (bp instanceof ICBreakpoint) {
+ boolean ok = false;
+ ICBreakpoint cbp = (ICBreakpoint)bp;
+ Map<String,Object> map = status.getStatus(id);
+ if (map != null) {
+ @SuppressWarnings("unchecked")
+ Collection<Map<String,Object>> list = (Collection<Map<String,Object>>)map.get(IBreakpoints.STATUS_INSTANCES);
+ if (list != null) {
+ for (Map<String,Object> m : list) {
+ if (m.get(IBreakpoints.INSTANCE_ERROR) == null) ok = true;
+ }
+ }
+ }
+ if (ok) {
+ if (installed.add(cbp)) incrementInstallCount(cbp);
+ }
+ else {
+ if (installed.remove(cbp)) decrementInstallCount(cbp);
+ }
+ }
+ }
+
+ public void breakpointRemoved(String id) {
+ IBreakpoint bp = bp_model.getBreakpoint(id);
+ if (bp instanceof ICBreakpoint) {
+ ICBreakpoint cbp = (ICBreakpoint)bp;
+ if (installed.remove(cbp)) decrementInstallCount(cbp);
+ }
+ }
+
+ void dispose() {
+ for (ICBreakpoint cbp : installed) decrementInstallCount(cbp);
+ installed.clear();
+ }
+
+ private void incrementInstallCount(final ICBreakpoint cbp) {
+ asyncExec(new Runnable() {
+ public void run() {
+ try {
+ cbp.incrementInstallCount();
+ }
+ catch (Exception x) {
+ Activator.log(x);
+ }
+ }
+ });
+ }
+
+ private void decrementInstallCount(final ICBreakpoint cbp) {
+ asyncExec(new Runnable() {
+ public void run() {
+ try {
+ cbp.decrementInstallCount();
+ }
+ catch (Exception x) {
+ Activator.log(x);
+ }
+ }
+ });
+ }
+
+ private void asyncExec(Runnable r) {
+ synchronized (Device.class) {
+ Display display = Display.getDefault();
+ if (display != null && !display.isDisposed()) {
+ display.asyncExec(r);
+ }
+ }
+ }
+ }
+
+ private final TCFModelManager.ModelManagerListener launch_listener = new TCFModelManager.ModelManagerListener() {
+
+ public void onConnected(TCFLaunch launch, TCFModel model) {
+ assert bp_listeners.get(launch) == null;
+ new BreakpointListener(launch);
+ }
+
+ public void onDisconnected(TCFLaunch launch, TCFModel model) {
+ bp_listeners.remove(launch).dispose();
+ }
+ };
+
+ private final TCFModelManager model_manager;
+ private final TCFBreakpointsModel bp_model;
+ private final Map<TCFLaunch,BreakpointListener> bp_listeners;;
+
+ TCFBreakpointStatusListener() {
+ bp_model = TCFBreakpointsModel.getBreakpointsModel();
+ model_manager = TCFModelManager.getModelManager();
+ model_manager.addListener(launch_listener);
+ bp_listeners = new HashMap<TCFLaunch,BreakpointListener>();
+ }
+
+ void dispose() {
+ model_manager.removeListener(launch_listener);
+ for (BreakpointListener l : bp_listeners.values()) l.dispose();
+ bp_listeners.clear();
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/hover/ExpressionInformationControlCreator.java b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/hover/ExpressionInformationControlCreator.java index 6b00fdac4..f390c1bc6 100644 --- a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/hover/ExpressionInformationControlCreator.java +++ b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/hover/ExpressionInformationControlCreator.java @@ -48,7 +48,6 @@ import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.tm.internal.tcf.cdt.ui.Activator;
-import org.eclipse.tm.internal.tcf.cdt.ui.hover.ExpressionInformationControlCreator.ExpressionInformationControl;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartSite;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java index fe3a8792d..9f3becfcf 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -80,6 +80,8 @@ public class Activator extends AbstractUIPlugin { * @return the shared TCFModelManager instance */ public static TCFModelManager getModelManager() { + assert Protocol.isDispatchThread(); + if (model_manager == null) model_manager = new TCFModelManager(); return model_manager; } @@ -88,6 +90,8 @@ public class Activator extends AbstractUIPlugin { * @return the shared TCFAnnotationManager instance */ public static TCFAnnotationManager getAnnotationManager() { + assert Protocol.isDispatchThread(); + if (annotation_manager == null) annotation_manager = new TCFAnnotationManager(); return annotation_manager; } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java index a089f9368..b5dcac5a7 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java @@ -17,8 +17,12 @@ import java.util.Map; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.CompositeImageDescriptor; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.PlatformUI; import org.osgi.framework.Bundle; public class ImageCache { @@ -54,10 +58,15 @@ public class ImageCache { IMG_STACK_FRAME_RUNNING = "icons/full/obj16/stckframe_running_obj.gif", IMG_BREAKPOINT_ENABLED = "icons/full/obj16/brkp_obj.gif", - IMG_BREAKPOINT_DISABLED = "icons/full/obj16/brkpd_obj.gif"; + IMG_BREAKPOINT_DISABLED = "icons/full/obj16/brkpd_obj.gif", + IMG_BREAKPOINT_INSTALLED = "icons/ovr16/installed_ovr.gif", + IMG_BREAKPOINT_CONDITIONAL = "icons/ovr16/conditional_ovr.gif", + IMG_BREAKPOINT_WARNING = "icons/ovr16/warning_ovr.gif"; private static final Map<String,ImageDescriptor> desc_cache = new HashMap<String,ImageDescriptor>(); private static final Map<ImageDescriptor,Image> image_cache = new HashMap<ImageDescriptor,Image>(); + private static final Map<String,Map<ImageDescriptor,ImageDescriptor>> overlay_cache = + new HashMap<String,Map<ImageDescriptor,ImageDescriptor>>(); public static synchronized ImageDescriptor getImageDescriptor(String name) { if (name == null) return null; @@ -76,6 +85,16 @@ public class ImageCache { } } if (descriptor == null) { + bundle = Platform.getBundle("org.eclipse.cdt.debug.ui"); + if (bundle != null){ + URL url = FileLocator.find(bundle, new Path(name), null); + if (url != null) descriptor = ImageDescriptor.createFromURL(url); + } + } + if (descriptor == null) { + descriptor = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(name); + } + if (descriptor == null) { descriptor = ImageDescriptor.getMissingImageDescriptor(); } desc_cache.put(name, descriptor); @@ -83,6 +102,29 @@ public class ImageCache { return descriptor; } + public static synchronized ImageDescriptor addOverlay(ImageDescriptor descriptor, String name) { + if (descriptor == null || name == null) return descriptor; + Map<ImageDescriptor,ImageDescriptor> map = overlay_cache.get(name); + if (map == null) overlay_cache.put(name, map = new HashMap<ImageDescriptor,ImageDescriptor>()); + ImageDescriptor res = map.get(descriptor); + if (res != null) return res; + final ImageData base = descriptor.getImageData(); + final ImageData overlay = getImageDescriptor(name).getImageData(); + res = new CompositeImageDescriptor() { + @Override + protected void drawCompositeImage(int width, int height) { + drawImage(base, 0, 0); + drawImage(overlay, 0, 0); + } + @Override + protected Point getSize() { + return new Point(base.width, base.height); + } + }; + map.put(descriptor, res); + return res; + } + public static synchronized Image getImage(ImageDescriptor desc) { Image image = image_cache.get(desc); if (image == null) { diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java index fdfd04347..c8939e44d 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,20 +10,29 @@ *******************************************************************************/ package org.eclipse.tm.internal.tcf.debug.ui.model; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchesListener; import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch; +import org.eclipse.tm.internal.tcf.debug.ui.Activator; import org.eclipse.tm.tcf.protocol.Protocol; public class TCFModelManager { + public interface ModelManagerListener { + public void onConnected(TCFLaunch launch, TCFModel model); + public void onDisconnected(TCFLaunch launch, TCFModel model); + } + private final Map<TCFLaunch,TCFModel> models = new HashMap<TCFLaunch,TCFModel>(); + private final List<ModelManagerListener> listeners = new ArrayList<ModelManagerListener>(); private final TCFLaunch.LaunchListener tcf_launch_listener = new TCFLaunch.LaunchListener() { @@ -38,12 +47,28 @@ public class TCFModelManager { assert Protocol.isDispatchThread(); TCFModel model = models.get(launch); if (model != null) model.onConnected(); + for (ModelManagerListener l : listeners) { + try { + l.onConnected(launch, model); + } + catch (Throwable x) { + Activator.log(x); + } + } } public void onDisconnected(TCFLaunch launch) { assert Protocol.isDispatchThread(); TCFModel model = models.get(launch); if (model != null) model.onDisconnected(); + for (ModelManagerListener l : listeners) { + try { + l.onDisconnected(launch, model); + } + catch (Throwable x) { + Activator.log(x); + } + } } public void onProcessOutput(TCFLaunch launch, String process_id, int stream_id, byte[] data) { @@ -106,6 +131,14 @@ public class TCFModelManager { assert models.isEmpty(); } + public void addListener(ModelManagerListener l) { + listeners.add(l); + } + + public void removeListener(ModelManagerListener l) { + listeners.remove(l); + } + public TCFModel getModel(TCFLaunch launch) { assert Protocol.isDispatchThread(); return models.get(launch); @@ -116,4 +149,8 @@ public class TCFModelManager { if (model == null) return null; return model.getRootNode(); } + + public static TCFModelManager getModelManager() { + return Activator.getModelManager(); + } } diff --git a/plugins/org.eclipse.tm.tcf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.tm.tcf.debug/META-INF/MANIFEST.MF index 9cd5d3d87..58d7b3a29 100644 --- a/plugins/org.eclipse.tm.tcf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.tm.tcf.debug/META-INF/MANIFEST.MF @@ -20,4 +20,4 @@ Eclipse-LazyStart: true Export-Package: org.eclipse.tm.internal.tcf.debug.launch;x-friends:="org.eclipse.tm.tcf.debug.ui,org.eclipse.tm.tcf.cdt.ui", org.eclipse.tm.internal.tcf.debug.actions;x-friends:="org.eclipse.tm.tcf.debug.ui", org.eclipse.tm.internal.tcf.debug.tests;x-friends:="org.eclipse.tm.tcf.debug.ui", - org.eclipse.tm.internal.tcf.debug.model;x-friends:="org.eclipse.tm.tcf.debug.ui" + org.eclipse.tm.internal.tcf.debug.model;x-friends:="org.eclipse.tm.tcf.debug.ui,org.eclipse.tm.tcf.cdt.ui" diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java index a65db6423..e769d507c 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java @@ -20,7 +20,6 @@ import java.util.Set; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -45,6 +44,7 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana private final IBreakpointManager bp_manager = DebugPlugin.getDefault().getBreakpointManager(); private final HashSet<IChannel> channels = new HashSet<IChannel>(); + private final HashMap<String,IBreakpoint> id2bp = new HashMap<String,IBreakpoint>(); private boolean disposed; @@ -64,6 +64,12 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana return true; } + /** + * Get TCF ID of a breakpoint. + * @param bp - IBreakpoint object. + * @return TCF ID of the breakpoint. + * @throws CoreException + */ public String getBreakpointID(IBreakpoint bp) throws CoreException { IMarker marker = bp.getMarker(); String id = (String)marker.getAttributes().get(ITCFConstants.ID_TCF_DEBUG_MODEL + '.' + IBreakpoints.PROP_ID); @@ -73,6 +79,18 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana return id + ':' + marker.getId(); } + /** + * Get IBreakpoint for given TCF breakpoint ID. + * The mapping works only for breakpoints that were sent to a debug target. + * It can be used to map target responses to IBreakpoint objects. + * @param id - TCF breakpoint ID. + * @return IBreakpoint object associated with the ID, or null. + */ + public IBreakpoint getBreakpoint(String id) { + assert Protocol.isDispatchThread(); + return id2bp.get(id); + } + @SuppressWarnings("unchecked") public void downloadBreakpoints(final IChannel channel, final Runnable done) throws IOException, CoreException { assert Protocol.isDispatchThread(); @@ -93,6 +111,7 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana if (channels.isEmpty()) { bp_manager.removeBreakpointListener(TCFBreakpointsModel.this); bp_manager.removeBreakpointManagerListener(TCFBreakpointsModel.this); + id2bp.clear(); } } public void onChannelOpened() { @@ -108,6 +127,7 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana IMarker marker = arr[i].getMarker(); String file = getFilePath(marker.getResource()); bps[i] = toBreakpointAttributes(id, file, marker.getType(), marker.getAttributes()); + id2bp.put(id, arr[i]); } service.set(bps, new IBreakpoints.DoneCommand() { public void doneCommand(IToken token, Exception error) { @@ -238,12 +258,13 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana return p.toFile().getCanonicalPath(); } - public void breakpointAdded(IBreakpoint breakpoint) { + public void breakpointAdded(final IBreakpoint breakpoint) { try { new BreakpointUpdate(breakpoint) { @Override void update() { service.add(tcf_attrs, done); + id2bp.put((String)tcf_attrs.get(IBreakpoints.PROP_ID), breakpoint); } }.exec(); } @@ -256,7 +277,6 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana private Set<String> calcMarkerDeltaKeys(IMarker marker, IMarkerDelta delta) throws CoreException { Set<String> keys = new HashSet<String>(); if (delta == null) return keys; - assert delta.getKind() == IResourceDelta.CHANGED; Map<String,Object> m0 = delta.getAttributes(); Map<String,Object> m1 = marker.getAttributes(); if (m0 != null) keys.addAll(m0.keySet()); @@ -273,28 +293,31 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana if (v0 != null && !v0.equals(v1)) continue; i.remove(); } + keys.remove("org.eclipse.cdt.debug.core.installCount"); return keys; } - public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { + public void breakpointChanged(final IBreakpoint breakpoint, IMarkerDelta delta) { try { final Set<String> s = calcMarkerDeltaKeys(breakpoint.getMarker(), delta); if (s.isEmpty()) return; new BreakpointUpdate(breakpoint) { @Override void update() { + String id = (String)tcf_attrs.get(IBreakpoints.PROP_ID); if (s.size() == 1 && s.contains(IBreakpoint.ENABLED)) { Boolean enabled = (Boolean)tcf_attrs.get(IBreakpoints.PROP_ENABLED); if (enabled == null || !enabled.booleanValue()) { - service.disable(new String[]{ (String)tcf_attrs.get(IBreakpoints.PROP_ID) }, done); + service.disable(new String[]{ id }, done); } else { - service.enable(new String[]{ (String)tcf_attrs.get(IBreakpoints.PROP_ID) }, done); + service.enable(new String[]{ id }, done); } } else { service.change(tcf_attrs, done); } + id2bp.put(id, breakpoint); } }.exec(); } @@ -308,7 +331,9 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana new BreakpointUpdate(breakpoint) { @Override void update() { - service.remove(new String[]{ (String)tcf_attrs.get(IBreakpoints.PROP_ID) }, done); + String id = (String)tcf_attrs.get(IBreakpoints.PROP_ID); + service.remove(new String[]{ id }, done); + id2bp.remove(id); } }.exec(); } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java index cbb71d51f..486101843 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java @@ -75,6 +75,10 @@ public class TCFBreakpointsStatus { } } + public Set<String> getStatusIDs() { + return status.keySet(); + } + public Map<String,Object> getStatus(String id) { assert id != null; assert Protocol.isDispatchThread(); |