mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
[291426] - [breakpoints] Add DSF support for flex-hierarchy breakpoints view.
This commit is contained in:
parent
9514e9c398
commit
9d94af8a4d
15 changed files with 1587 additions and 12 deletions
|
@ -13,13 +13,14 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
|||
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints.BreakpointVMProvider;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.modules.ModulesVMProvider;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMProvider;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch.LaunchVMProvider;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
|
@ -43,7 +44,7 @@ public class GdbViewModelAdapter extends AbstractDebugVMAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) {
|
||||
protected IVMProvider createViewModelProvider(IPresentationContext context) {
|
||||
if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
|
||||
return new LaunchVMProvider(this, context, getSession());
|
||||
} else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
|
||||
|
@ -54,6 +55,8 @@ public class GdbViewModelAdapter extends AbstractDebugVMAdapter
|
|||
return new ExpressionVMProvider(this, context, getSession());
|
||||
} else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) {
|
||||
return new ModulesVMProvider(this, context, getSession());
|
||||
} else if (IDebugUIConstants.ID_BREAKPOINT_VIEW.equals(context.getId()) ) {
|
||||
return new BreakpointVMProvider(this, context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ Export-Package: org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional,
|
|||
org.eclipse.cdt.dsf.debug.ui.sourcelookup,
|
||||
org.eclipse.cdt.dsf.debug.ui.viewmodel;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.examples.dsf,org.eclipse.cdt.examples.dsf.pda.ui",
|
||||
org.eclipse.cdt.dsf.debug.ui.viewmodel.actions;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.examples.dsf,org.eclipse.cdt.examples.dsf.pda.ui",
|
||||
org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.examples.dsf,org.eclipse.cdt.examples.dsf.pda.ui",
|
||||
org.eclipse.cdt.dsf.debug.ui.viewmodel.expression;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.examples.dsf,org.eclipse.cdt.examples.dsf.pda.ui",
|
||||
org.eclipse.cdt.dsf.debug.ui.viewmodel.launch;
|
||||
x-friends:="org.eclipse.cdt.dsf.gdb.ui,
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointContainer;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class BreakpointOrganizerVMContext extends AbstractVMContext implements IBreakpointContainer {
|
||||
|
||||
private final IAdaptable fCategory;
|
||||
private final IBreakpoint[] fBreakpoints;
|
||||
|
||||
BreakpointOrganizerVMContext(BreakpointOrganizerVMNode vmNode, IAdaptable category, IBreakpoint[] breakpoints) {
|
||||
super(vmNode);
|
||||
fCategory = category;
|
||||
fBreakpoints = breakpoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BreakpointOrganizerVMContext &&
|
||||
getVMNode().equals( ((BreakpointOrganizerVMContext)obj).getVMNode() ) &&
|
||||
getOrganizer().equals( ((BreakpointOrganizerVMContext)obj).getOrganizer() ) &&
|
||||
fCategory.equals(((BreakpointOrganizerVMContext)obj).fCategory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getOrganizer().hashCode() + getVMNode().hashCode() + fCategory.hashCode();
|
||||
}
|
||||
|
||||
public IBreakpointOrganizer getOrganizer() {
|
||||
return ((BreakpointOrganizerVMNode)getVMNode()).getOrganizer();
|
||||
}
|
||||
|
||||
public IAdaptable getCategory() {
|
||||
return fCategory;
|
||||
}
|
||||
|
||||
public boolean contains(IBreakpoint breakpoint) {
|
||||
for (IBreakpoint bp : fBreakpoints) {
|
||||
if (bp.equals(breakpoint)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public IBreakpoint[] getBreakpoints() {
|
||||
return fBreakpoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fCategory.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
||||
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.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class BreakpointOrganizerVMNode extends AbstractVMNode {
|
||||
|
||||
private final IBreakpointOrganizer fOrganizer;
|
||||
|
||||
private final IPropertyChangeListener fOrganizerListener = new IPropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
((BreakpointVMProvider)getVMProvider()).handleEventInExecThread(event);
|
||||
}
|
||||
};
|
||||
|
||||
public BreakpointOrganizerVMNode(BreakpointVMProvider provider, IBreakpointOrganizer organizer) {
|
||||
super(provider);
|
||||
fOrganizer = organizer;
|
||||
fOrganizer.addPropertyChangeListener(fOrganizerListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
fOrganizer.removePropertyChangeListener(fOrganizerListener);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public IBreakpointOrganizer getOrganizer() {
|
||||
return fOrganizer;
|
||||
}
|
||||
|
||||
public void update(final IHasChildrenUpdate[] updates) {
|
||||
for (final IHasChildrenUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getBreakpointOrganizerVMCs(
|
||||
this, update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<List<BreakpointOrganizerVMContext>>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
update.setHasChilren(!getData().isEmpty());
|
||||
} else {
|
||||
update.setHasChilren(false);
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void update(final IChildrenCountUpdate[] updates) {
|
||||
for (final IChildrenCountUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getBreakpointOrganizerVMCs(
|
||||
this, update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<List<BreakpointOrganizerVMContext>>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
update.setChildCount(getData().size());
|
||||
} else {
|
||||
update.setChildCount(0);
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void update(IChildrenUpdate[] updates) {
|
||||
for (final IChildrenUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getBreakpointOrganizerVMCs(
|
||||
this, update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<List<BreakpointOrganizerVMContext>>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
|
||||
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : (getData().size()));
|
||||
while (updateIdx < endIdx && updateIdx < getData().size()) {
|
||||
update.setChild(getData().get(updateIdx), updateIdx);
|
||||
updateIdx++;
|
||||
}
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected BreakpointOrganizerVMContext createVMContext(IAdaptable category, IBreakpoint[] breakpoints) {
|
||||
return new BreakpointOrganizerVMContext(this, category, breakpoints);
|
||||
}
|
||||
|
||||
public int getDeltaFlags(Object event) {
|
||||
if (event instanceof BreakpointsChangedEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()) ||
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty()))
|
||||
{
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
} else if (BreakpointVMProvider.isBreakpointOrganizerEvent(event)) {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) {
|
||||
if (event instanceof BreakpointsChangedEvent) {
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||
}
|
||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()) ||
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty()))
|
||||
{
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||
}
|
||||
} else if (BreakpointVMProvider.isBreakpointOrganizerEvent(event)) {
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||
}
|
||||
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
public class BreakpointVMContext extends AbstractVMContext {
|
||||
|
||||
private final IBreakpoint fBreakpoint;
|
||||
|
||||
public BreakpointVMContext(BreakpointVMNode node, IBreakpoint breakpoint) {
|
||||
super(node);
|
||||
fBreakpoint = breakpoint;
|
||||
}
|
||||
|
||||
public IBreakpoint getBreakpoint() {
|
||||
return fBreakpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (adapter.isInstance(fBreakpoint)) {
|
||||
return fBreakpoint;
|
||||
}
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BreakpointVMContext &&
|
||||
getBreakpoint().equals( ((BreakpointVMContext)obj).getBreakpoint() ) &&
|
||||
fBreakpoint.equals(((BreakpointVMContext)obj).fBreakpoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return fBreakpoint.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fBreakpoint.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMAdapter;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
public class BreakpointVMInput extends PlatformObject implements IElementMementoProvider {
|
||||
|
||||
private IVMNode fVMNode;
|
||||
|
||||
public BreakpointVMInput(IVMNode node, IDMContext activeDMContext) {
|
||||
fVMNode = node;
|
||||
}
|
||||
|
||||
public void encodeElements(IElementMementoRequest[] requests) {
|
||||
for (IElementMementoRequest request : requests) {
|
||||
request.getMemento().putString("ELEMENT_NAME", "BreakpointInputMemento"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
request.done();
|
||||
}
|
||||
}
|
||||
|
||||
public void compareElements(IElementCompareRequest[] requests) {
|
||||
for (IElementCompareRequest request : requests) {
|
||||
request.setEqual( "BreakpointInputMemento".equals(request.getMemento().getString("ELEMENT_NAME")) ); //$NON-NLS-1$//$NON-NLS-2$
|
||||
request.done();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes" })
|
||||
public Object getAdapter(Class adapter) {
|
||||
// If the context implements the given adapter directly, it always takes
|
||||
// precedence.
|
||||
if (adapter.isInstance(this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
IVMProvider vmProvider = fVMNode.getVMProvider();
|
||||
IVMAdapter vmAdapter = vmProvider.getVMAdapter();
|
||||
if (adapter.isInstance(vmAdapter)) {
|
||||
return vmAdapter;
|
||||
} else if (adapter.isInstance(vmProvider)) {
|
||||
return vmProvider;
|
||||
} else if (adapter.isInstance(fVMNode)) {
|
||||
return fVMNode;
|
||||
}
|
||||
return Platform.getAdapterManager().getAdapter(this, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BreakpointVMInput;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getClass().hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.DefaultVMModelProxyStrategy;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointContainer;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckboxModelProxy;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
|
||||
/**
|
||||
* Breakpoints VM model proxy that includes an ICheckboxModelProxy implementation.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class BreakpointVMModelProxyStrategy extends DefaultVMModelProxyStrategy implements ICheckboxModelProxy {
|
||||
|
||||
public BreakpointVMModelProxyStrategy(AbstractVMProvider provider, Object rootElement) {
|
||||
super(provider, rootElement);
|
||||
}
|
||||
|
||||
public boolean setChecked(IPresentationContext context, Object viewerInput, TreePath path, boolean checked) {
|
||||
Object lastSegment = path.getLastSegment();
|
||||
if (lastSegment instanceof IBreakpointContainer) {
|
||||
IBreakpoint[] breakpoints = ((IBreakpointContainer) lastSegment).getBreakpoints();
|
||||
for (int i = 0; i < breakpoints.length; ++i) {
|
||||
try {
|
||||
breakpoints[i].setEnabled(checked);
|
||||
} catch (CoreException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
IBreakpoint breakpoint = (IBreakpoint)DebugPlugin.getAdapter(lastSegment, IBreakpoint.class);
|
||||
if (breakpoint != null) {
|
||||
try {
|
||||
breakpoint.setEnabled(checked);
|
||||
} catch (CoreException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckUpdate;
|
||||
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.IElementCompareRequest;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
||||
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.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.ui.IMemento;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class BreakpointVMNode extends AbstractVMNode implements IElementLabelProvider, IElementMementoProvider {
|
||||
|
||||
public BreakpointVMNode(IVMProvider provider) {
|
||||
super(provider);
|
||||
}
|
||||
|
||||
public void update(final IHasChildrenUpdate[] updates) {
|
||||
for (final IHasChildrenUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||
update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
update.setHasChilren(getData().length != 0);
|
||||
} else {
|
||||
update.setHasChilren(false);
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void update(final IChildrenCountUpdate[] updates) {
|
||||
for (final IChildrenCountUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||
update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
update.setChildCount(getData().length);
|
||||
} else {
|
||||
update.setChildCount(0);
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void update(IChildrenUpdate[] updates) {
|
||||
for (final IChildrenUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||
update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Comparator<Object> comparator =
|
||||
(Comparator<Object>)getVMProvider().getPresentationContext().getProperty(
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
|
||||
if (comparator != null) {
|
||||
Arrays.sort(getData(), comparator);
|
||||
}
|
||||
fillUpdateWithBreakpointVMCs(update, getData());
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void fillUpdateWithBreakpointVMCs(IChildrenUpdate update, IBreakpoint[] bps) {
|
||||
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
|
||||
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : bps.length);
|
||||
while (updateIdx < endIdx && updateIdx < bps.length) {
|
||||
update.setChild(createVMContext(bps[updateIdx]), updateIdx);
|
||||
updateIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
protected BreakpointVMContext createVMContext(IBreakpoint bp) {
|
||||
return new BreakpointVMContext(this, bp);
|
||||
}
|
||||
|
||||
public void update(ILabelUpdate[] updates) {
|
||||
Map<IElementLabelProvider, List<ILabelUpdate>> delegatesMap = new HashMap<IElementLabelProvider, List<ILabelUpdate>>(1,1);
|
||||
|
||||
for (final ILabelUpdate update : updates) {
|
||||
final IBreakpoint bp = ((BreakpointVMContext)update.getElement()).getBreakpoint();
|
||||
IElementLabelProvider provider = (IElementLabelProvider)bp.getAdapter(IElementLabelProvider.class);
|
||||
if (provider == null) {
|
||||
update.done();
|
||||
continue;
|
||||
}
|
||||
|
||||
List<ILabelUpdate> delegatesList = delegatesMap.get(provider);
|
||||
if (delegatesList == null) {
|
||||
delegatesList = new ArrayList<ILabelUpdate>(updates.length);
|
||||
delegatesMap.put(provider, delegatesList);
|
||||
}
|
||||
delegatesList.add(new ICheckUpdate() {
|
||||
public void setChecked(boolean checked, boolean grayed) {
|
||||
if (update instanceof ICheckUpdate) {
|
||||
((ICheckUpdate)update).setChecked(checked, grayed);
|
||||
}
|
||||
}
|
||||
public String[] getColumnIds() { return update.getColumnIds(); }
|
||||
public void setLabel(String text, int columnIndex) {
|
||||
update.setLabel(text, columnIndex);
|
||||
}
|
||||
public void setFontData(FontData fontData, int columnIndex) { update.setFontData(fontData, columnIndex); }
|
||||
public void setImageDescriptor(ImageDescriptor image, int columnIndex) { update.setImageDescriptor(image, columnIndex); }
|
||||
public void setForeground(RGB foreground, int columnIndex) { update.setForeground(foreground, columnIndex); }
|
||||
public void setBackground(RGB background, int columnIndex) { update.setBackground(background, columnIndex); }
|
||||
public IPresentationContext getPresentationContext() { return update.getPresentationContext(); }
|
||||
public Object getElement() { return bp; }
|
||||
public TreePath getElementPath() { return update.getElementPath().getParentPath().createChildPath(bp); }
|
||||
public Object getViewerInput() { return update.getViewerInput(); }
|
||||
public void setStatus(IStatus status) { update.setStatus(status); }
|
||||
public IStatus getStatus() { return update.getStatus(); }
|
||||
public void done() { update.done(); }
|
||||
public void cancel() { update.cancel(); }
|
||||
public boolean isCanceled() { return update.isCanceled(); }
|
||||
});
|
||||
}
|
||||
|
||||
for (IElementLabelProvider provider : delegatesMap.keySet()) {
|
||||
List<ILabelUpdate> updatesList = delegatesMap.get(provider);
|
||||
provider.update(updatesList.toArray(new ILabelUpdate[updatesList.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
public void encodeElements(IElementMementoRequest[] updates) {
|
||||
Map<IElementMementoProvider, List<IElementMementoRequest>> delegatesMap = new HashMap<IElementMementoProvider, List<IElementMementoRequest>>(1,1);
|
||||
|
||||
for (final IElementMementoRequest update : updates) {
|
||||
final IBreakpoint bp = ((BreakpointVMContext)update.getElement()).getBreakpoint();
|
||||
IElementMementoProvider provider = (IElementMementoProvider)bp.getAdapter(IElementMementoProvider.class);
|
||||
if (provider == null) {
|
||||
update.done();
|
||||
continue;
|
||||
}
|
||||
|
||||
List<IElementMementoRequest> delegatesList = delegatesMap.get(provider);
|
||||
if (delegatesList == null) {
|
||||
delegatesList = new ArrayList<IElementMementoRequest>(updates.length);
|
||||
delegatesMap.put(provider, delegatesList);
|
||||
}
|
||||
delegatesList.add(new IElementMementoRequest() {
|
||||
public IMemento getMemento() { return update.getMemento(); }
|
||||
public IPresentationContext getPresentationContext() { return update.getPresentationContext(); }
|
||||
public Object getElement() { return bp; }
|
||||
public TreePath getElementPath() { return update.getElementPath().getParentPath().createChildPath(bp); }
|
||||
public Object getViewerInput() { return update.getViewerInput(); }
|
||||
public void setStatus(IStatus status) { update.setStatus(status); }
|
||||
public IStatus getStatus() { return update.getStatus(); }
|
||||
public void done() { update.done(); }
|
||||
public void cancel() { update.cancel(); }
|
||||
public boolean isCanceled() { return update.isCanceled(); }
|
||||
});
|
||||
}
|
||||
|
||||
for (IElementMementoProvider provider : delegatesMap.keySet()) {
|
||||
List<IElementMementoRequest> updatesList = delegatesMap.get(provider);
|
||||
provider.encodeElements(updatesList.toArray(new IElementMementoRequest[updatesList.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
public void compareElements(IElementCompareRequest[] updates) {
|
||||
Map<IElementMementoProvider, List<IElementCompareRequest>> delegatesMap = new HashMap<IElementMementoProvider, List<IElementCompareRequest>>(1,1);
|
||||
|
||||
for (final IElementCompareRequest update : updates) {
|
||||
final IBreakpoint bp = ((BreakpointVMContext)update.getElement()).getBreakpoint();
|
||||
IElementMementoProvider provider = (IElementMementoProvider)bp.getAdapter(IElementMementoProvider.class);
|
||||
if (provider == null) {
|
||||
update.done();
|
||||
continue;
|
||||
}
|
||||
|
||||
List<IElementCompareRequest> delegatesList = delegatesMap.get(provider);
|
||||
if (delegatesList == null) {
|
||||
delegatesList = new ArrayList<IElementCompareRequest>(updates.length);
|
||||
delegatesMap.put(provider, delegatesList);
|
||||
}
|
||||
delegatesList.add(new IElementCompareRequest() {
|
||||
public IMemento getMemento() { return update.getMemento(); }
|
||||
public void setEqual(boolean equal) { update.setEqual(equal);}
|
||||
public IPresentationContext getPresentationContext() { return update.getPresentationContext(); }
|
||||
public Object getElement() { return bp; }
|
||||
public TreePath getElementPath() { return update.getElementPath().getParentPath().createChildPath(bp); }
|
||||
public Object getViewerInput() { return update.getViewerInput(); }
|
||||
public void setStatus(IStatus status) { update.setStatus(status); }
|
||||
public IStatus getStatus() { return update.getStatus(); }
|
||||
public void done() { update.done(); }
|
||||
public void cancel() { update.cancel(); }
|
||||
public boolean isCanceled() { return update.isCanceled(); }
|
||||
});
|
||||
}
|
||||
|
||||
for (IElementMementoProvider provider : delegatesMap.keySet()) {
|
||||
List<IElementCompareRequest> updatesList = delegatesMap.get(provider);
|
||||
provider.compareElements(updatesList.toArray(new IElementCompareRequest[updatesList.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
public int getDeltaFlags(Object event) {
|
||||
if (event instanceof BreakpointsChangedEvent) {
|
||||
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
||||
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
||||
return IModelDelta.CONTENT | IModelDelta.SELECT | IModelDelta.EXPAND;
|
||||
}
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
||||
{
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
||||
return IModelDelta.EXPAND | IModelDelta.CONTENT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) {
|
||||
if (event instanceof BreakpointsChangedEvent) {
|
||||
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
||||
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
||||
buildBreakpointAddedDelta(bpChangedEvent, parent, nodeOffset, rm);
|
||||
// Do not call rm.done() in this method!
|
||||
return;
|
||||
} else {
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||
}
|
||||
}
|
||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
||||
{
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.EXPAND | IModelDelta.CONTENT);
|
||||
}
|
||||
}
|
||||
|
||||
rm.done();
|
||||
}
|
||||
|
||||
private void buildBreakpointAddedDelta(final BreakpointsChangedEvent event, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
|
||||
getVMProvider().updateNode(this, new VMChildrenUpdate(
|
||||
parent, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
for (int i = 0; i < event.getBreakpoints().length; i++) {
|
||||
int bpIndex = getData().indexOf(event.getBreakpoints()[i]);
|
||||
if (bpIndex >= 0) {
|
||||
// Select only the first breakpoint that was added
|
||||
if (i == 0) {
|
||||
parent.addNode(getData().get(bpIndex), bpIndex, IModelDelta.SELECT);
|
||||
}
|
||||
// For all other added breakpoints, expand the parent.
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT | IModelDelta.EXPAND);
|
||||
}
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,358 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataCache;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.IExpressionVMNode;
|
||||
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode;
|
||||
import org.eclipse.core.resources.IMarkerDelta;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.IBreakpointsListener;
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.OtherBreakpointCategory;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
|
||||
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.IBreakpointOrganizerDelegate;
|
||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
|
||||
/**
|
||||
* The expression provider is used to populate the contents of the expressions
|
||||
* view. The node hierarchy in this view is a little different than in a typical
|
||||
* provider: the expression manager node should be registered as the single child
|
||||
* of the root node and no nodes should be registered as children of expression node.
|
||||
* Instead the top level expression nodes should be registered with a call to
|
||||
* {@link #setExpressionNodes(IExpressionVMNode[])}. And each expression node can
|
||||
* have its own sub-hierarchy of elements as needed. However all nodes configured
|
||||
* with this provider (with the exception of the root and the expression manager)
|
||||
* should implement {@link IExpressionVMNode}.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class BreakpointVMProvider extends AbstractVMProvider
|
||||
{
|
||||
private IPropertyChangeListener fPresentationContextListener = new IPropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
handleEventInExecThread(event);
|
||||
}
|
||||
};
|
||||
|
||||
private IBreakpointsListener fBreakpointsListener = new IBreakpointsListener() {
|
||||
public void breakpointsRemoved(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
|
||||
handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.REMOVED, breakpoints));
|
||||
}
|
||||
|
||||
public void breakpointsChanged(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
|
||||
handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.CHANGED, breakpoints));
|
||||
}
|
||||
|
||||
public void breakpointsAdded(IBreakpoint[] breakpoints) {
|
||||
handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.ADDED, breakpoints));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private class ContainerBreakpointsCache extends DataCache<List<BreakpointOrganizerVMContext>> {
|
||||
|
||||
private BreakpointOrganizerVMNode fOrganizerVMNode;
|
||||
private TreePath fParentPath;
|
||||
|
||||
public ContainerBreakpointsCache(BreakpointOrganizerVMNode organizerVMNode, TreePath parentPath) {
|
||||
super(getExecutor());
|
||||
fOrganizerVMNode = organizerVMNode;
|
||||
fParentPath = parentPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void retrieve(final DataRequestMonitor<List<BreakpointOrganizerVMContext>> rm) {
|
||||
getNestingCategoryBreakpoints(
|
||||
fParentPath,
|
||||
new DataRequestMonitor<IBreakpoint[]>(getExecutor(), rm) {
|
||||
@SuppressWarnings({ "cast", "unchecked" })
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
Map<IAdaptable, List<IBreakpoint>> bpsLists = new HashMap<IAdaptable, List<IBreakpoint>>();
|
||||
for (IBreakpoint bp : getData()) {
|
||||
IAdaptable[] bpCategories = fOrganizerVMNode.getOrganizer().getCategories(bp);
|
||||
if (bpCategories == null || bpCategories.length == 0) {
|
||||
bpCategories = OtherBreakpointCategory.getCategories(fOrganizerVMNode.getOrganizer());
|
||||
}
|
||||
|
||||
for (IAdaptable category : bpCategories) {
|
||||
List<IBreakpoint> categoryBPs = bpsLists.get(category);
|
||||
if (categoryBPs == null) {
|
||||
categoryBPs = new ArrayList<IBreakpoint>();
|
||||
bpsLists.put(category, categoryBPs);
|
||||
}
|
||||
categoryBPs.add(bp);
|
||||
}
|
||||
}
|
||||
|
||||
// Only show the empty containers for the top-level node.
|
||||
if (fParentPath.getSegmentCount() == 0) {
|
||||
final IAdaptable[] independentCategories = fOrganizerVMNode.getOrganizer().getCategories();
|
||||
if (independentCategories != null) {
|
||||
for (IAdaptable category : independentCategories) {
|
||||
if (!bpsLists.containsKey(category)) {
|
||||
bpsLists.put(category, (List<IBreakpoint>)Collections.EMPTY_LIST);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<BreakpointOrganizerVMContext> vmcs = new ArrayList<BreakpointOrganizerVMContext>(bpsLists.size());
|
||||
for (Map.Entry<IAdaptable, List<IBreakpoint>> entry : bpsLists.entrySet()) {
|
||||
List<IBreakpoint> bpsList = entry.getValue();
|
||||
IBreakpoint[] bpsArray = bpsList.toArray(new IBreakpoint[bpsList.size()]);
|
||||
|
||||
vmcs.add(createBreakpointOrganizerVMContext(fOrganizerVMNode, entry.getKey(), bpsArray));
|
||||
}
|
||||
Comparator<Object> comparator = (Comparator<Object>)getPresentationContext().getProperty(
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
|
||||
if (comparator != null) {
|
||||
Collections.sort(vmcs, comparator);
|
||||
}
|
||||
|
||||
rm.setData(vmcs);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private final Map<TreePath, ContainerBreakpointsCache> fContainerBreakpointsCacheMap =
|
||||
new HashMap<TreePath, ContainerBreakpointsCache>();
|
||||
|
||||
private DataCache<IBreakpoint[]> fFilteredBreakpointsCache = new DataCache<IBreakpoint[]>(getExecutor()) {
|
||||
@Override
|
||||
protected void retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor<IBreakpoint[]> rm) {
|
||||
calcFileteredBreakpoints(rm);
|
||||
}
|
||||
};
|
||||
|
||||
public BreakpointVMProvider(AbstractVMAdapter adapter, IPresentationContext context) {
|
||||
super(adapter, context);
|
||||
|
||||
configureLayout();
|
||||
context.addPropertyChangeListener(fPresentationContextListener);
|
||||
DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(fBreakpointsListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IVMModelProxy createModelProxyStrategy(Object rootElement) {
|
||||
return new BreakpointVMModelProxyStrategy(this, rootElement);
|
||||
}
|
||||
|
||||
protected IVMNode createBreakpointVMNode() {
|
||||
return new BreakpointVMNode(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the nodes of this provider. This method may be over-ridden by
|
||||
* sub classes to create an alternate configuration in this provider.
|
||||
*/
|
||||
protected void configureLayout() {
|
||||
/*
|
||||
* Create the top level node which provides the anchor starting point.
|
||||
*/
|
||||
IRootVMNode rootNode = new RootDMVMNode(this);
|
||||
|
||||
IBreakpointOrganizer[] organizers = (IBreakpointOrganizer[])
|
||||
getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS);
|
||||
|
||||
IVMNode parentNode = rootNode;
|
||||
if (organizers != null) {
|
||||
for (IBreakpointOrganizer organizer : organizers) {
|
||||
IVMNode organizerNode = new BreakpointOrganizerVMNode(this, organizer);
|
||||
addChildNodes(parentNode, new IVMNode[] {organizerNode});
|
||||
parentNode = organizerNode;
|
||||
}
|
||||
}
|
||||
|
||||
IVMNode bpsNode = createBreakpointVMNode();
|
||||
addChildNodes(parentNode, new IVMNode[] {bpsNode});
|
||||
|
||||
/*
|
||||
* Let the work know which is the top level node.
|
||||
*/
|
||||
setRootNode(rootNode);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
getPresentationContext().removePropertyChangeListener(fPresentationContextListener);
|
||||
DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(fBreakpointsListener);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnPresentationId(IPresentationContext context, Object element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(IViewerInputUpdate update) {
|
||||
IStructuredSelection filterSelection = (IStructuredSelection)
|
||||
update.getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION);
|
||||
IDMContext activeDMContext = null;
|
||||
if (filterSelection != null) {
|
||||
if (update.getElement() instanceof IDMVMContext) {
|
||||
activeDMContext = ((IDMVMContext)update.getElement()).getDMContext();
|
||||
}
|
||||
}
|
||||
update.setInputElement(new BreakpointVMInput(getRootVMNode(), activeDMContext));
|
||||
update.done();
|
||||
}
|
||||
|
||||
public void getNestingCategoryBreakpoints(TreePath path, final DataRequestMonitor<IBreakpoint[]> rm) {
|
||||
BreakpointOrganizerVMContext nestingOrganizerVmc = null;
|
||||
while (path.getSegmentCount() > 0) {
|
||||
if (path.getLastSegment() instanceof BreakpointOrganizerVMContext) {
|
||||
nestingOrganizerVmc = (BreakpointOrganizerVMContext)path.getLastSegment();
|
||||
break;
|
||||
}
|
||||
path = path.getParentPath();
|
||||
}
|
||||
if (nestingOrganizerVmc == null) {
|
||||
getFileteredBreakpoints(rm);
|
||||
} else {
|
||||
final BreakpointOrganizerVMContext _nestingOrganizerVmc = nestingOrganizerVmc;
|
||||
getBreakpointOrganizerVMCs(
|
||||
(BreakpointOrganizerVMNode)_nestingOrganizerVmc.getVMNode(), path.getParentPath(),
|
||||
new DataRequestMonitor<List<BreakpointOrganizerVMContext>>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
int newVmcIdx = getData().indexOf(_nestingOrganizerVmc);
|
||||
|
||||
if (newVmcIdx >= 0) {
|
||||
rm.setData(getData().get(newVmcIdx).getBreakpoints());
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Breakpoint category not found", null)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void getBreakpointOrganizerVMCs(BreakpointOrganizerVMNode organizerVMNode, TreePath path,
|
||||
DataRequestMonitor<List<BreakpointOrganizerVMContext>> rm)
|
||||
{
|
||||
ContainerBreakpointsCache cache = fContainerBreakpointsCacheMap.get(path);
|
||||
if (cache == null) {
|
||||
cache = new ContainerBreakpointsCache(organizerVMNode, path);
|
||||
fContainerBreakpointsCacheMap.put(path, cache);
|
||||
}
|
||||
|
||||
cache.request(rm);
|
||||
}
|
||||
|
||||
|
||||
protected BreakpointOrganizerVMContext createBreakpointOrganizerVMContext(BreakpointOrganizerVMNode node, IAdaptable category, IBreakpoint[] breakpoints) {
|
||||
return new BreakpointOrganizerVMContext(node, category, breakpoints);
|
||||
}
|
||||
|
||||
|
||||
public void getFileteredBreakpoints(final DataRequestMonitor<IBreakpoint[]> rm) {
|
||||
fFilteredBreakpointsCache.request(rm);
|
||||
}
|
||||
|
||||
protected void calcFileteredBreakpoints(DataRequestMonitor<IBreakpoint[]> rm) {
|
||||
rm.setData(DebugPlugin.getDefault().getBreakpointManager().getBreakpoints());
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void handleEventInExecThread(final Object event) {
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Object event, RequestMonitor rm) {
|
||||
if (isPresentationContextEvent(event)) {
|
||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty()))
|
||||
{
|
||||
clearNodes();
|
||||
configureLayout();
|
||||
}
|
||||
}
|
||||
super.handleEvent(event, rm);
|
||||
}
|
||||
|
||||
public static boolean isPresentationContextEvent(Object event) {
|
||||
return event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getSource() instanceof IPresentationContext;
|
||||
}
|
||||
|
||||
public static boolean isBreakpointOrganizerEvent(Object event) {
|
||||
return event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getSource() instanceof IBreakpointOrganizerDelegate;
|
||||
}
|
||||
|
||||
private static final int MODEL_DELTA_CHANGE_FLAGS = IModelDelta.STATE | IModelDelta.CONTENT | IModelDelta.ADDED | IModelDelta.REMOVED | IModelDelta.REPLACED | IModelDelta.INSERTED;
|
||||
|
||||
@Override
|
||||
protected void handleEvent(IVMModelProxy proxyStrategy, Object event, RequestMonitor rm) {
|
||||
// Before generating a delta, flush the caches.
|
||||
int deltaFlags = proxyStrategy.getEventDeltaFlags(event);
|
||||
if ((deltaFlags & MODEL_DELTA_CHANGE_FLAGS) != 0) {
|
||||
flushCaches();
|
||||
}
|
||||
|
||||
super.handleEvent(proxyStrategy, event, rm);
|
||||
}
|
||||
|
||||
private void flushCaches() {
|
||||
fFilteredBreakpointsCache.reset();
|
||||
for (DataCache<?> cache : fContainerBreakpointsCacheMap.values()) {
|
||||
cache.reset();
|
||||
}
|
||||
fContainerBreakpointsCacheMap.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
public class BreakpointsChangedEvent {
|
||||
public enum Type { ADDED, REMOVED, CHANGED };
|
||||
|
||||
private final Type fType;
|
||||
private final IBreakpoint[] fBreakpoints;
|
||||
|
||||
public BreakpointsChangedEvent(Type type, IBreakpoint[] breakpoints) {
|
||||
fType = type;
|
||||
fBreakpoints = breakpoints;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return fType;
|
||||
}
|
||||
|
||||
public IBreakpoint[] getBreakpoints() {
|
||||
return fBreakpoints;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems 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.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
||||
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.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class RawBreakpointVMNode extends AbstractVMNode {
|
||||
|
||||
public RawBreakpointVMNode(IVMProvider provider) {
|
||||
super(provider);
|
||||
}
|
||||
|
||||
public void update(final IHasChildrenUpdate[] updates) {
|
||||
for (final IHasChildrenUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||
update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
update.setHasChilren(getData().length != 0);
|
||||
} else {
|
||||
update.setHasChilren(false);
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void update(final IChildrenCountUpdate[] updates) {
|
||||
for (final IChildrenCountUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||
update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
update.setChildCount(getData().length);
|
||||
} else {
|
||||
update.setChildCount(0);
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void update(IChildrenUpdate[] updates) {
|
||||
for (final IChildrenUpdate update : updates) {
|
||||
if (!checkUpdate(update)) continue;
|
||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||
update.getElementPath(),
|
||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Comparator<Object> comparator =
|
||||
(Comparator<Object>)getVMProvider().getPresentationContext().getProperty(
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
|
||||
if (comparator != null) {
|
||||
Arrays.sort(getData(), comparator);
|
||||
}
|
||||
fillUpdateWithBreakpoints(update, getData());
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void fillUpdateWithBreakpoints(IChildrenUpdate update, IBreakpoint[] bps) {
|
||||
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
|
||||
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : bps.length);
|
||||
while (updateIdx < endIdx && updateIdx < bps.length) {
|
||||
update.setChild(bps[updateIdx], updateIdx);
|
||||
updateIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
public int getDeltaFlags(Object event) {
|
||||
if (event instanceof BreakpointsChangedEvent) {
|
||||
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
||||
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
||||
return IModelDelta.CONTENT | IModelDelta.SELECT | IModelDelta.EXPAND;
|
||||
}
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
||||
{
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
||||
return IModelDelta.EXPAND | IModelDelta.CONTENT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) {
|
||||
if (event instanceof BreakpointsChangedEvent) {
|
||||
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
||||
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
||||
buildBreakpointAddedDelta(bpChangedEvent, parent, nodeOffset, rm);
|
||||
// Do not call rm.done() in this method!
|
||||
return;
|
||||
} else {
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||
}
|
||||
}
|
||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
||||
{
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.EXPAND | IModelDelta.CONTENT);
|
||||
}
|
||||
}
|
||||
|
||||
rm.done();
|
||||
}
|
||||
|
||||
private void buildBreakpointAddedDelta(final BreakpointsChangedEvent event, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
|
||||
getVMProvider().updateNode(this, new VMChildrenUpdate(
|
||||
parent, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
for (int i = 0; i < event.getBreakpoints().length; i++) {
|
||||
int bpIndex = getData().indexOf(event.getBreakpoints()[i]);
|
||||
if (bpIndex >= 0) {
|
||||
// Select only the first breakpoint that was added
|
||||
if (i == 0) {
|
||||
parent.addNode(getData().get(bpIndex), bpIndex, IModelDelta.SELECT);
|
||||
}
|
||||
// For all other added breakpoints, expand the parent.
|
||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT | IModelDelta.EXPAND);
|
||||
}
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -387,13 +387,12 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
|
|||
/**
|
||||
* Convenience method which checks whether given layout node is a node that
|
||||
* is configured in this ViewModelProvider.
|
||||
* <br>
|
||||
* Note: isOurNode() will also return true if the given node was previously
|
||||
* configured in the VM provider but was later disposed.
|
||||
*/
|
||||
private boolean isOurNode(IVMNode node) {
|
||||
for (IVMNode nodeToSearch : getVMProvider().getAllVMNodes()) {
|
||||
if (nodeToSearch.equals(node))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return node.getVMProvider() == getVMProvider();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.core.runtime.SafeRunner;
|
|||
import org.eclipse.debug.internal.ui.DebugUIPlugin;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor;
|
||||
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.ModelDelta;
|
||||
|
@ -72,10 +73,17 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
}
|
||||
|
||||
public boolean isDeltaEvent(Object event) {
|
||||
return getEventDeltaFlags(event) != IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
||||
public int getEventDeltaFlags(Object event) {
|
||||
IRootVMNode rootNode = getVMProvider().getRootVMNode();
|
||||
return rootNode != null &&
|
||||
rootNode.isDeltaEvent(getRootElement(), event) &&
|
||||
getDeltaFlags(rootNode, null, event) != IModelDelta.NO_CHANGE;
|
||||
if (rootNode != null &&
|
||||
rootNode.isDeltaEvent(getRootElement(), event))
|
||||
{
|
||||
return getDeltaFlags(rootNode, null, event);
|
||||
}
|
||||
return IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,7 +354,9 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
new RequestMonitor(getVMProvider().getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(viewRootDelta);
|
||||
// Get rid of redundant CONTENT and STATE flags in delta and prune
|
||||
// nodes without flags
|
||||
rm.setData(pruneDelta((VMDelta)viewRootDelta));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
|
@ -354,6 +364,25 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
});
|
||||
}
|
||||
|
||||
protected VMDelta pruneDelta(VMDelta delta) {
|
||||
delta.accept(new IModelDeltaVisitor() {
|
||||
public boolean visit(IModelDelta deltaNode, int depth) {
|
||||
if ((deltaNode.getFlags() & (IModelDelta.CONTENT | IModelDelta.STATE)) != 0) {
|
||||
VMDelta parent = (VMDelta)deltaNode.getParentDelta();
|
||||
while (parent != null) {
|
||||
if ((parent.getFlags() & IModelDelta.CONTENT) != 0) {
|
||||
((VMDelta)deltaNode).setFlags(deltaNode.getFlags() & ~(IModelDelta.CONTENT | IModelDelta.STATE));
|
||||
break;
|
||||
}
|
||||
parent = parent.getParentDelta();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base implementation that handles calling child nodes to build
|
||||
* the model delta. This method delegates to two other methods:
|
||||
|
|
|
@ -35,7 +35,11 @@ public interface IVMModelProxy extends IModelProxy {
|
|||
|
||||
/**
|
||||
* Returns whether the given event applies to the root element and the
|
||||
* nodes in this model proxy.
|
||||
* nodes in this model proxy.
|
||||
* <p>
|
||||
* This method is the equivalent of calling
|
||||
* <code> getEventDeltaFlags(event) != IModelDelta.NO_CHANGE </code>.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isDeltaEvent(Object event);
|
||||
|
||||
|
@ -71,4 +75,15 @@ public interface IVMModelProxy extends IModelProxy {
|
|||
* @since 2.0
|
||||
*/
|
||||
public TreePath getRootPath();
|
||||
|
||||
/**
|
||||
* Returns the delta flags associated with this event. This method is
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public int getEventDeltaFlags(Object event);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
package org.eclipse.cdt.dsf.concurrent;
|
||||
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2008 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
|
||||
*******************************************************************************/
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.cdt.dsf.internal.DsfPlugin;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* A general purpose cache, which caches the result of a single request.
|
||||
* Sub classes need to implement {@link #retrieve(DataRequestMonitor)} to fetch
|
||||
* data from the data source. Clients are responsible for calling
|
||||
* {@link #disable()} and {@link #reset()} to manage the state of the cache in
|
||||
* response to events from the data source.
|
||||
* <p>
|
||||
* This cache requires an executor to use. The executor is used to synchronize
|
||||
* access to the cache state and data.
|
||||
* </p>
|
||||
* @since 2.1
|
||||
*/
|
||||
@ConfinedToDsfExecutor("fExecutor")
|
||||
public abstract class DataCache<V> {
|
||||
|
||||
final private Executor fExecutor;
|
||||
|
||||
private boolean fValid;
|
||||
|
||||
protected DataRequestMonitor<V> fRm;
|
||||
private V fData;
|
||||
private IStatus fStatus;
|
||||
|
||||
private List<DataRequestMonitor<V>> fWaitingList = new LinkedList<DataRequestMonitor<V>>();
|
||||
|
||||
public DataCache(Executor executor) {
|
||||
fExecutor = executor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sub-classes should override this method to retrieve the cache data
|
||||
* from its source.
|
||||
*
|
||||
* @param rm Request monitor for completion of data retrieval.
|
||||
*/
|
||||
protected abstract void retrieve(DataRequestMonitor<V> rm);
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the cache is currently valid. I.e.
|
||||
* whether the cache can return a value immediately without first
|
||||
* retrieving it from the data source.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return fValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the cache is currently waiting for data
|
||||
* from the data source.
|
||||
*/
|
||||
public boolean isPending() {
|
||||
return fRm != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current data value held by this cache. Clients should first
|
||||
* call isValid() to determine if the data is up to date.
|
||||
*/
|
||||
public V getData() {
|
||||
return fData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the source request held by this cache. Clients
|
||||
* should first call isValid() to determine if the data is up to date.
|
||||
*/
|
||||
public IStatus getStatus() {
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request data from the cache. The cache is valid, it will complete the
|
||||
* request immediately, otherwise data will first be retrieved from the
|
||||
* source.
|
||||
* @param req
|
||||
*/
|
||||
public void request(final DataRequestMonitor<V> rm) {
|
||||
if (!fValid) {
|
||||
boolean first = fWaitingList.isEmpty();
|
||||
fWaitingList.add(rm);
|
||||
if(first) {
|
||||
fRm = new DataRequestMonitor<V>(fExecutor, null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (!isCanceled()) {
|
||||
fValid = true;
|
||||
fRm = null;
|
||||
set(getData(), getStatus());
|
||||
}
|
||||
}
|
||||
};
|
||||
retrieve(fRm);
|
||||
}
|
||||
} else {
|
||||
rm.setData(fData);
|
||||
rm.setStatus(fStatus);
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void set(V data, IStatus status) {
|
||||
fData = data;
|
||||
fStatus = status;
|
||||
List<DataRequestMonitor<V>> waitingList = fWaitingList;
|
||||
fWaitingList = new LinkedList<DataRequestMonitor<V>>();
|
||||
|
||||
for (DataRequestMonitor<V> rm : waitingList) {
|
||||
rm.setData(data);
|
||||
rm.setStatus(status);
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the cache with a data value <code>null</code> and an error
|
||||
* status with code {@link IDsfStatusConstants#INVALID_STATE}.
|
||||
*
|
||||
* @see #reset(Object, IStatus)
|
||||
*/
|
||||
public void reset() {
|
||||
reset(null, new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Cache reset", null)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the cache with given data and status. Resetting the cache
|
||||
* forces the cache to be invalid and cancels any current pending requests
|
||||
* from data source.
|
||||
* <p>
|
||||
* This method should be called when the data source has issued an event
|
||||
* indicating that the source data has changed but data may still be
|
||||
* retrieved. Clients may need to re-request data following cache reset.
|
||||
* </p>
|
||||
* @param data The data that should be returned to any clients currently
|
||||
* waiting for cache data.
|
||||
* @status The status that should be returned to any clients currently
|
||||
* waiting for cache data.
|
||||
*/
|
||||
public void reset(V data, IStatus status) {
|
||||
fValid = false;
|
||||
if (fRm != null) {
|
||||
fRm.cancel();
|
||||
fRm = null;
|
||||
}
|
||||
set(data, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the cache with a data value <code>null</code> and an error
|
||||
* status with code {@link IDsfStatusConstants#INVALID_STATE}.
|
||||
*
|
||||
* @see #disable(Object, IStatus)
|
||||
*/
|
||||
public void disable() {
|
||||
disable(null, new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Cache disable", null)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the cache then disables it. When a cache is disabled it means
|
||||
* that it is valid and requests to the data source will not be sent.
|
||||
* <p>
|
||||
* This method should be called when the data source has issued an event
|
||||
* indicating that the source data has changed and future requests for
|
||||
* data will return the given data and status. Once the source data
|
||||
* becomes available again, clients should call {@link #reset()}.
|
||||
* </p>
|
||||
* @param data The data that should be returned to any clients waiting for
|
||||
* cache data and for clients requesting data until the cache is reset again.
|
||||
* @status The status that should be returned to any clients waiting for
|
||||
* cache data and for clients requesting data until the cache is reset again.
|
||||
*
|
||||
* @see #reset(Object, IStatus)
|
||||
*/
|
||||
public void disable(V data, IStatus status) {
|
||||
reset(data, status);
|
||||
fValid = true;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue