mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Bug 336876 - [multicore] Grouping of Execution Elements for DSF debugger feature
This commit is contained in:
parent
ceb221e714
commit
e9ccc03be3
20 changed files with 1048 additions and 15 deletions
|
@ -0,0 +1,22 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.model;
|
||||
|
||||
import org.eclipse.debug.core.commands.IDebugCommandHandler;
|
||||
|
||||
/**
|
||||
* Handler interface to perform grouping of debug contexts.
|
||||
*
|
||||
* @since 7.1
|
||||
*/
|
||||
public interface IGroupDebugContextsHandler extends IDebugCommandHandler {
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.model;
|
||||
|
||||
import org.eclipse.debug.core.commands.IDebugCommandHandler;
|
||||
|
||||
/**
|
||||
* Handler interface to perform ungrouping of debug contexts.
|
||||
*
|
||||
* @since 7.1
|
||||
*/
|
||||
public interface IUngroupDebugContextsHandler extends IDebugCommandHandler {
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
# QNX Software Systems - Initial API and implementation
|
||||
# IBM Corporation
|
||||
# Patrick Chuong (Texas Instruments) - Pin and Clone Supports (Bug 331781)
|
||||
# Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
###############################################################################
|
||||
|
||||
pluginName=C/C++ Development Tools Debugger UI
|
||||
|
@ -195,6 +196,15 @@ Uncall.name = Uncall
|
|||
Uncall.description = Perform Uncall
|
||||
Uncall.label = Uncall
|
||||
|
||||
# Debug View layout
|
||||
DebugViewLayoutActionSet.label = Debug View Layout
|
||||
DebugViewLayoutCategory.name = Debug View Layout Commands
|
||||
DebugViewLayoutCategory.description = Set of commands for controlling the Debug View Layout
|
||||
GroupDebugContexts.name = Group
|
||||
GroupDebugContexts.description = Groups the selected debug contexts
|
||||
UngroupDebugContexts.name = Ungroup
|
||||
UngroupDebugContexts.description = Ungroups the selected debug contexts
|
||||
|
||||
# Menu for selecting breakpoint toggle type
|
||||
BreakpointTypes.label=B&reakpoint Types
|
||||
|
||||
|
|
|
@ -1818,6 +1818,11 @@
|
|||
label="%TracepointActionSet.label"
|
||||
visible="false">
|
||||
</actionSet>
|
||||
<actionSet
|
||||
id="org.eclipse.cdt.debug.ui.debugViewLayoutActionSet"
|
||||
label="%DebugViewLayoutActionSet.label"
|
||||
visible="false">
|
||||
</actionSet>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
|
@ -1897,6 +1902,23 @@
|
|||
helpContextId="view_memory_context"
|
||||
name="%command.viewMemory.name">
|
||||
</command>
|
||||
<category
|
||||
description="%DebugViewLayoutCategory.description"
|
||||
id="org.eclipse.cdt.debug.ui.category.debugViewLayout"
|
||||
name="%DebugViewLayoutCategory.name">
|
||||
</category>
|
||||
<command
|
||||
categoryId="org.eclipse.cdt.debug.ui.category.debugViewLayout"
|
||||
description="%GroupDebugContexts.description"
|
||||
id="org.eclipse.cdt.debug.ui.command.groupDebugContexts"
|
||||
name="%GroupDebugContexts.name">
|
||||
</command>
|
||||
<command
|
||||
categoryId="org.eclipse.cdt.debug.ui.category.debugViewLayout"
|
||||
description="%UngroupDebugContexts.description"
|
||||
id="org.eclipse.cdt.debug.ui.command.ungroupDebugContexts"
|
||||
name="%UngroupDebugContexts.name">
|
||||
</command>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.handlers">
|
||||
|
@ -1951,6 +1973,14 @@
|
|||
</with>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
<handler
|
||||
class="org.eclipse.cdt.debug.internal.ui.commands.GroupDebugContextsCommandHandler"
|
||||
commandId="org.eclipse.cdt.debug.ui.command.groupDebugContexts">
|
||||
</handler>
|
||||
<handler
|
||||
class="org.eclipse.cdt.debug.internal.ui.commands.UngroupDebugContextsCommandHandler"
|
||||
commandId="org.eclipse.cdt.debug.ui.command.ungroupDebugContexts">
|
||||
</handler>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.core.expressions.definitions">
|
||||
|
@ -2004,6 +2034,18 @@
|
|||
</iterate>
|
||||
</with>
|
||||
</definition>
|
||||
<definition
|
||||
id="org.eclipse.cdt.debug.ui.testDebugViewLayoutActionSetActive">
|
||||
<with
|
||||
variable="activeContexts">
|
||||
<iterate
|
||||
operator="or">
|
||||
<equals
|
||||
value="org.eclipse.cdt.debug.ui.debugViewLayoutActionSet">
|
||||
</equals>
|
||||
</iterate>
|
||||
</with>
|
||||
</definition>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.bindings">
|
||||
|
@ -2297,6 +2339,53 @@
|
|||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
<menuContribution
|
||||
locationURI="popup:org.eclipse.debug.ui.DebugView?after=emptyStepGroup">
|
||||
<command
|
||||
commandId="org.eclipse.cdt.debug.ui.command.groupDebugContexts"
|
||||
label="%GroupDebugContexts.name">
|
||||
<visibleWhen
|
||||
checkEnabled="false">
|
||||
<and>
|
||||
<reference
|
||||
definitionId="org.eclipse.cdt.debug.ui.testDebugViewLayoutActionSetActive">
|
||||
</reference>
|
||||
<with
|
||||
variable="debugContext">
|
||||
<iterate
|
||||
ifEmpty="false"
|
||||
operator="and">
|
||||
<test
|
||||
property="org.eclipse.cdt.debug.ui.isGroupDebugContextsVisible">
|
||||
</test>
|
||||
</iterate>
|
||||
</with>
|
||||
</and>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
<command
|
||||
commandId="org.eclipse.cdt.debug.ui.command.ungroupDebugContexts"
|
||||
label="%UngroupDebugContexts.name">
|
||||
<visibleWhen
|
||||
checkEnabled="false">
|
||||
<and>
|
||||
<reference
|
||||
definitionId="org.eclipse.cdt.debug.ui.testDebugViewLayoutActionSetActive">
|
||||
</reference>
|
||||
<with
|
||||
variable="debugContext">
|
||||
<iterate
|
||||
ifEmpty="false"
|
||||
operator="and">
|
||||
<test
|
||||
property="org.eclipse.cdt.debug.ui.isUngroupDebugContextsVisible">
|
||||
</test>
|
||||
</iterate>
|
||||
</with>
|
||||
</and>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
|
||||
<!-- Cast to Type / Display as Array -->
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.ui.commands;
|
||||
|
||||
import org.eclipse.cdt.debug.core.model.IGroupDebugContextsHandler;
|
||||
import org.eclipse.debug.ui.actions.DebugCommandHandler;
|
||||
|
||||
/**
|
||||
* Command handler to trigger grouping of debug contexts operation.
|
||||
*
|
||||
* @since 7.1
|
||||
*/
|
||||
public class GroupDebugContextsCommandHandler extends DebugCommandHandler {
|
||||
|
||||
@Override
|
||||
protected Class<?> getCommandType() {
|
||||
return IGroupDebugContextsHandler.class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.ui.commands;
|
||||
|
||||
import org.eclipse.cdt.debug.core.model.IUngroupDebugContextsHandler;
|
||||
import org.eclipse.debug.ui.actions.DebugCommandHandler;
|
||||
|
||||
/**
|
||||
* Command handler to trigger ungrouping of debug contexts operation.
|
||||
*
|
||||
* @since 7.1
|
||||
*/
|
||||
public class UngroupDebugContextsCommandHandler extends DebugCommandHandler {
|
||||
|
||||
@Override
|
||||
protected Class<?> getCommandType() {
|
||||
return IUngroupDebugContextsHandler.class;
|
||||
}
|
||||
}
|
|
@ -22,6 +22,8 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.5.0",
|
|||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: org.eclipse.cdt.dsf.debug.internal.ui;x-internal:=true,
|
||||
org.eclipse.cdt.dsf.debug.internal.ui.actions;x-internal:=true,
|
||||
org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout;x-internal:=true,
|
||||
org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions,
|
||||
org.eclipse.cdt.dsf.debug.internal.ui.disassembly;x-internal:=true,
|
||||
org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions;x-internal:=true,
|
||||
org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model;x-internal:=true,
|
||||
|
|
|
@ -450,8 +450,14 @@
|
|||
properties="areNumberFormatsSupported,isNumberFormatAvailable,isNumberFormatActive"
|
||||
type="org.eclipse.debug.ui.IDebugView">
|
||||
</propertyTester>
|
||||
<propertyTester
|
||||
class="org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.DebugViewLayoutTester"
|
||||
id="org.eclipse.cdt.dsf.ui.debug.view.layout.DebugViewLayoutTester"
|
||||
namespace="org.eclipse.cdt.debug.ui"
|
||||
properties="isGroupDebugContextsVisible,isUngroupDebugContextsVisible"
|
||||
type="org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext">
|
||||
</propertyTester>
|
||||
</extension>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.detailPaneFactories">
|
||||
<detailFactories
|
||||
|
@ -790,4 +796,5 @@
|
|||
</editor>
|
||||
</extension>
|
||||
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout;
|
||||
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.core.expressions.PropertyTester;
|
||||
|
||||
/**
|
||||
* Property tester for debug view related commands - group, ungroup, hide, etc.
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
|
||||
public class DebugViewLayoutTester extends PropertyTester{
|
||||
|
||||
public DebugViewLayoutTester() {
|
||||
}
|
||||
|
||||
protected static final String IS_GROUP_VISIBLE = "isGroupDebugContextsVisible"; //$NON-NLS-1$
|
||||
protected static final String IS_UNGROUP_VISIBLE = "isUngroupDebugContextsVisible"; //$NON-NLS-1$
|
||||
|
||||
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
|
||||
|
||||
if( IS_GROUP_VISIBLE.equals(property) || IS_UNGROUP_VISIBLE.equals(property)) {
|
||||
if (receiver instanceof IDMVMContext) {
|
||||
return test((IDMVMContext)receiver);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean test(IDMVMContext dmContext) {
|
||||
String sessionId = dmContext.getDMContext().getSessionId();
|
||||
return DsfSession.isSessionActive(sessionId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.internal.provisional.service.IExecutionContextTranslator;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandHandler;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandRequest;
|
||||
import org.eclipse.debug.core.commands.IEnabledStateRequest;
|
||||
|
||||
/**
|
||||
* @since 2.2
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public abstract class DsfDebugViewLayoutCommand implements IDebugCommandHandler{
|
||||
|
||||
protected final DsfExecutor fExecutor;
|
||||
protected final DsfServicesTracker fTracker;
|
||||
protected static IExecutionDMContext[] EMPTY_ARRAY = new IExecutionDMContext[0];
|
||||
|
||||
public DsfDebugViewLayoutCommand(DsfSession session) {
|
||||
fExecutor = session.getExecutor();
|
||||
fTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
fTracker.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param request
|
||||
* @return set of IExecutionDMContext if:
|
||||
* - all elements are from a DSF session.
|
||||
* - all elements are from the same DSF session.
|
||||
*/
|
||||
protected IExecutionDMContext[] getDMContexts( IDebugCommandRequest request) {
|
||||
|
||||
HashSet<IExecutionDMContext> ret = new HashSet<IExecutionDMContext>();
|
||||
String sessionId = null;
|
||||
|
||||
for( Object obj : request.getElements()) {
|
||||
if(!( obj instanceof IDMVMContext ))
|
||||
return EMPTY_ARRAY;
|
||||
|
||||
IDMContext dmContext = ((IDMVMContext)obj).getDMContext();
|
||||
IExecutionDMContext exeContext = DMContexts.getAncestorOfType(dmContext, IExecutionDMContext.class);
|
||||
|
||||
if( exeContext == null)
|
||||
return EMPTY_ARRAY;
|
||||
|
||||
// make sure all elements are from the same DSF session.
|
||||
if( sessionId == null) {
|
||||
sessionId = dmContext.getSessionId();
|
||||
}
|
||||
else {
|
||||
if( !sessionId.equals(dmContext.getSessionId()))
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
ret.add(exeContext);
|
||||
}
|
||||
return ret.toArray(new IExecutionDMContext[0]);
|
||||
}
|
||||
|
||||
public void canExecute(final IEnabledStateRequest request) {
|
||||
final IExecutionDMContext[] executionContexts = getDMContexts( request);
|
||||
if( executionContexts.length > 0 && !fExecutor.isTerminated()) {
|
||||
fExecutor.submit(new DsfRunnable() {
|
||||
public void run() {
|
||||
IExecutionContextTranslator translator = fTracker.getService(IExecutionContextTranslator.class);
|
||||
if( translator != null) {
|
||||
canExecuteOnDsfThread(translator, executionContexts,
|
||||
new DataRequestMonitor<Boolean>(fExecutor, null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
boolean canExecute = isSuccess() && getData();
|
||||
request.setEnabled(canExecute);
|
||||
request.done();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean execute(final IDebugCommandRequest request) {
|
||||
final IExecutionDMContext[] executionContexts = getDMContexts( request);
|
||||
if( executionContexts.length > 0 && !fExecutor.isTerminated()) {
|
||||
fExecutor.submit(new DsfRunnable() {
|
||||
public void run() {
|
||||
IExecutionContextTranslator translator = fTracker.getService(IExecutionContextTranslator.class);
|
||||
if( translator != null) {
|
||||
executeOnDsfThread(translator, executionContexts,
|
||||
new RequestMonitor(fExecutor, null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
request.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
request.done();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
request.done();
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract void executeOnDsfThread( IExecutionContextTranslator translator, IExecutionDMContext[] contexts, RequestMonitor requestMonitor);
|
||||
abstract void canExecuteOnDsfThread( IExecutionContextTranslator translator, IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.internal.provisional.service.IExecutionContextTranslator;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandHandler;
|
||||
|
||||
/**
|
||||
* @since 2.2
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class DsfGroupDebugContextsCommand extends DsfDebugViewLayoutCommand implements IDebugCommandHandler{
|
||||
|
||||
@Override
|
||||
void executeOnDsfThread( IExecutionContextTranslator translator, IExecutionDMContext[] contexts, RequestMonitor requestMonitor) {
|
||||
translator.group(contexts, requestMonitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
void canExecuteOnDsfThread( IExecutionContextTranslator translator, IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) {
|
||||
translator.canGroup(contexts, rm);
|
||||
}
|
||||
|
||||
public DsfGroupDebugContextsCommand(DsfSession session) {
|
||||
super( session);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.internal.provisional.service.IExecutionContextTranslator;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandHandler;
|
||||
|
||||
/**
|
||||
* @since 2.2
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class DsfUngroupDebugContextsCommand extends DsfDebugViewLayoutCommand implements IDebugCommandHandler{
|
||||
|
||||
public DsfUngroupDebugContextsCommand(DsfSession session) {
|
||||
super( session);
|
||||
}
|
||||
|
||||
@Override
|
||||
void executeOnDsfThread(IExecutionContextTranslator translator, IExecutionDMContext[] contexts, RequestMonitor requestMonitor) {
|
||||
translator.ungroup(contexts, requestMonitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
void canExecuteOnDsfThread(IExecutionContextTranslator translator, IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) {
|
||||
translator.canUngroup(contexts, rm);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2009 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
* Patrick Chuong (Texas Instruments) - Add support for icon overlay in the debug view (Bug 334566)
|
||||
* Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch;
|
||||
|
||||
|
@ -41,7 +42,6 @@ import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
|
|||
import org.eclipse.cdt.dsf.ui.viewmodel.ModelProxyInstalledEvent;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
|
||||
|
@ -65,7 +65,7 @@ import org.eclipse.debug.ui.IDebugUIConstants;
|
|||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public abstract class AbstractContainerVMNode extends AbstractDMVMNode
|
||||
public abstract class AbstractContainerVMNode extends AbstractExecutionContextVMNode
|
||||
implements IElementLabelProvider, IElementPropertiesProvider
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,344 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 240208)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
|
||||
/**
|
||||
* This class is a base class of AbstractThreadVMNode and AbstractContainerVMNode.
|
||||
* It contains common functionality between these classes.
|
||||
*
|
||||
* The main reason this class is introduce is to allow the debug view to
|
||||
* show multiple levels of execution containers and properly handle the delta generation.
|
||||
*
|
||||
* Longer term we would like to merge the classes AbstractContainerVMNode and
|
||||
* AbstractThreadVMNode. That will make the implementation of both classes
|
||||
* more generic and robust in the case of recursive containers.
|
||||
*
|
||||
* Having this class as a base for both AbstractContainerVMNode and
|
||||
* AbstractThreadVMNode enables us to merge them in the future.
|
||||
*
|
||||
* Originally DefaultVMModelProxyStrategy didn't accept recursive container for
|
||||
* generating deltas, even though they are accepted and supported by
|
||||
* AbstractDMVMProvider for viewing.
|
||||
* The approach I took to support recursive container in delta generation is to have
|
||||
* the VMNodes to generate level by level its deltas instead of one the whole delta at once.
|
||||
* That required changes in identifying which is the correct context for each of the events.
|
||||
*
|
||||
* See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=240208
|
||||
*
|
||||
* @since 2.2
|
||||
* @experimental
|
||||
*/
|
||||
public abstract class AbstractExecutionContextVMNode extends AbstractDMVMNode
|
||||
{
|
||||
/**
|
||||
* List that keeps track of which events are considered leave events for
|
||||
* delta creation.
|
||||
*/
|
||||
protected ArrayList<Class<?>> leafEventTypes = new ArrayList<Class<?>>();
|
||||
|
||||
/**
|
||||
* List that keeps track of which events are considered container events for
|
||||
* delta creation.
|
||||
*/
|
||||
protected ArrayList<Class<?>> containerEventTypes = new ArrayList<Class<?>>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Pass the parameter to the base class's constructor.
|
||||
*
|
||||
* @param session
|
||||
* @param dmcClassType
|
||||
*
|
||||
* @see #setChildNodes(IVMNode[])
|
||||
*/
|
||||
public AbstractExecutionContextVMNode(AbstractDMVMProvider provider,
|
||||
DsfSession session, Class<? extends IDMContext> dmcClassType) {
|
||||
super(provider, session, dmcClassType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the events that common DSF classes relay on.
|
||||
*/
|
||||
protected void addCommonEventTypes() {
|
||||
|
||||
// non container events.
|
||||
addEventType(ISuspendedDMEvent.class,false);
|
||||
addEventType(IResumedDMEvent.class, false);
|
||||
addEventType(FullStackRefreshEvent.class, false);
|
||||
addEventType(SteppingTimedOutEvent.class, false);
|
||||
addEventType(ExpandStackEvent.class, false);
|
||||
|
||||
// container events.
|
||||
addEventType(IContainerSuspendedDMEvent.class,true);
|
||||
addEventType(IContainerResumedDMEvent.class, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* When DSF debugger define custom events for which the containers and threads
|
||||
* nodes needs to be update they can need to register these events using this
|
||||
* function, so the proper recursive deltas are being created.
|
||||
*
|
||||
* @param eventClass
|
||||
*/
|
||||
protected void addEventType( Class<? extends IDMEvent<?>> eventClass, boolean containerEvent)
|
||||
{
|
||||
if( containerEvent)
|
||||
containerEventTypes.add( eventClass);
|
||||
else
|
||||
leafEventTypes.add( eventClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* If DSF debuggers overrides the behavior of the AbstractThreadVMNode
|
||||
* or AbstractContainerVMNode, some event are no longer needed the derived
|
||||
* VMNdoe can call this method to remove some events.
|
||||
*
|
||||
* @param eventClass
|
||||
* @param containerEvent
|
||||
*/
|
||||
protected void removeEventType( Class<?> eventClass, boolean containerEvent) {
|
||||
if( containerEvent)
|
||||
containerEventTypes.remove( eventClass);
|
||||
else
|
||||
leafEventTypes.remove( eventClass);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When we support recursive containers we want to make sure the immediate parent is returned only.
|
||||
*
|
||||
* @param parentDelta
|
||||
* @param e
|
||||
* @param rm - request monitor
|
||||
* @return true if the context is set by the method.
|
||||
*/
|
||||
protected boolean getContextsForRecursiveVMNode(VMDelta parentDelta, Object e, final DataRequestMonitor<IVMContext[]> rm) {
|
||||
|
||||
IExecutionDMContext leafContext = null;
|
||||
if( isExecutionContainerEvent(e)) {
|
||||
leafContext = getLeafContextForContainerEvent( e);
|
||||
}
|
||||
else if( isExecutionLeafEvent(e)) {
|
||||
leafContext = getLeafContextForLeafEvent( e);
|
||||
}
|
||||
if( leafContext != null) {
|
||||
setImmediateParentAsContexts(leafContext,parentDelta,rm);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure we build the delta for the recursive containers one level at a time.
|
||||
*
|
||||
* @param e - the events.
|
||||
* @param parentDelta
|
||||
* @param nodeOffset
|
||||
* @param requestMonitor
|
||||
* @return true if the delta is built by this method.
|
||||
*/
|
||||
protected boolean buildDeltaForRecursiveVMNode(Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) {
|
||||
|
||||
IExecutionDMContext leafContext = null;
|
||||
if( isExecutionContainerEvent(e)) {
|
||||
leafContext = getLeafContextForContainerEvent( e);
|
||||
}
|
||||
else if( isExecutionLeafEvent(e)) {
|
||||
leafContext = getLeafContextForLeafEvent( e);
|
||||
}
|
||||
if( leafContext != null) {
|
||||
addOneLevelToDelta( leafContext, parentDelta, requestMonitor);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the deltas are generated one level at a time we needs to distinguish
|
||||
* between container and regular event to return the proper context for the event.
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
protected IExecutionDMContext getLeafContextForContainerEvent( Object event) {
|
||||
|
||||
IExecutionDMContext leafEC = null;
|
||||
IExecutionDMContext[] triggeringContext = null;
|
||||
|
||||
if( isExecutionContainerEvent(event)) {
|
||||
if( event instanceof IContainerSuspendedDMEvent) {
|
||||
IContainerSuspendedDMEvent typedEvent = (IContainerSuspendedDMEvent)event;
|
||||
triggeringContext = typedEvent.getTriggeringContexts();
|
||||
}
|
||||
if( event instanceof IContainerResumedDMEvent) {
|
||||
IContainerResumedDMEvent typedEvent = (IContainerResumedDMEvent)event;
|
||||
triggeringContext = typedEvent.getTriggeringContexts();
|
||||
}
|
||||
}
|
||||
|
||||
if( triggeringContext != null && triggeringContext.length > 0){
|
||||
leafEC = triggeringContext[0];
|
||||
}
|
||||
|
||||
return leafEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the deltas are generated one level at a time we needs to distinguish
|
||||
* between container and regular event to return the proper context for the event.
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
protected IExecutionDMContext getLeafContextForLeafEvent( Object event) {
|
||||
|
||||
IExecutionDMContext leafEC = null;
|
||||
|
||||
if( event instanceof IDMEvent<?>)
|
||||
if( isExecutionLeafEvent( event)) {
|
||||
IDMEvent<?> typedEvent = (IDMEvent<?>)event;
|
||||
IDMContext dmContext = typedEvent.getDMContext();
|
||||
if( dmContext instanceof IExecutionDMContext)
|
||||
leafEC = (IExecutionDMContext)dmContext;
|
||||
}
|
||||
|
||||
return leafEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Considers the parent delta when we construct the next level.
|
||||
*
|
||||
* @param leafContext
|
||||
* @param parentDelta
|
||||
* @param requestMonitor
|
||||
*/
|
||||
protected void addOneLevelToDelta( IExecutionDMContext leafContext, VMDelta parentDelta, RequestMonitor requestMonitor) {
|
||||
assert leafContext != null;
|
||||
if( parentDelta.getElement() instanceof ILaunch) {
|
||||
IContainerDMContext topContainer =
|
||||
DMContexts.getTopMostAncestorOfType( leafContext, IContainerDMContext.class);
|
||||
|
||||
// It is possible for a thread node to be an immediate child of a launch node
|
||||
// with no container node in between.
|
||||
if( topContainer != null)
|
||||
parentDelta.addNode(createVMContext(topContainer), 0, IModelDelta.NO_CHANGE);
|
||||
}
|
||||
else if( parentDelta.getElement() instanceof IDMVMContext) {
|
||||
IDMVMContext vmContext = (IDMVMContext)parentDelta.getElement();
|
||||
IDMContext dmContext = vmContext.getDMContext();
|
||||
IExecutionDMContext current = DMContexts.getParentOfType(leafContext, IContainerDMContext.class);
|
||||
while( current != null) {
|
||||
IContainerDMContext parent = DMContexts.getParentOfType(current, IContainerDMContext.class);
|
||||
if( dmContext.equals(parent)) {
|
||||
parentDelta.addNode(createVMContext(current), 0, IModelDelta.NO_CHANGE);
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
}
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the event (container or not) set the proper context that is the immediate
|
||||
* parent one level at a time.
|
||||
*
|
||||
* @param leafContext
|
||||
* @param parentDelta
|
||||
* @param rm
|
||||
*/
|
||||
protected void setImmediateParentAsContexts( IExecutionDMContext leafContext,
|
||||
VMDelta parentDelta, DataRequestMonitor<IVMContext[]> rm){
|
||||
|
||||
assert leafContext != null;
|
||||
IVMContext[] all = null;
|
||||
if( parentDelta.getElement() instanceof ILaunch) {
|
||||
IContainerDMContext topContainer =
|
||||
DMContexts.getTopMostAncestorOfType( leafContext, IContainerDMContext.class);
|
||||
if( topContainer != null) {
|
||||
all = new IVMContext[] { createVMContext(topContainer) };
|
||||
}
|
||||
else {
|
||||
// the thread is directly a child node of the launch node (no container in the middle).
|
||||
all = new IVMContext[] { createVMContext(leafContext) };
|
||||
}
|
||||
}
|
||||
else if( parentDelta.getElement() instanceof IDMVMContext) {
|
||||
IDMVMContext vmContext = (IDMVMContext)parentDelta.getElement();
|
||||
IDMContext dmContext = vmContext.getDMContext();
|
||||
IExecutionDMContext current = leafContext;
|
||||
while( current != null) {
|
||||
IContainerDMContext parent = DMContexts.getParentOfType(current, IContainerDMContext.class);
|
||||
if( dmContext.equals(parent)) {
|
||||
all = new IVMContext[] { createVMContext(current)};
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
}
|
||||
if( all == null)
|
||||
all = new IVMContext[0];
|
||||
rm.setData( all );
|
||||
rm.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the event should be considered a container event or not.
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
protected boolean isExecutionContainerEvent( Object event) {
|
||||
if( event != null)
|
||||
for( Class<?> clazz : containerEventTypes)
|
||||
if( clazz.isAssignableFrom(event.getClass()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the event should be use to generate delta for each of the levels.
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
protected boolean isExecutionLeafEvent( Object event) {
|
||||
if( event != null)
|
||||
for( Class<?> clazz : leafEventTypes)
|
||||
if( clazz.isAssignableFrom(event.getClass()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems and others.
|
||||
* Copyright (c) 2006, 2011 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
|
||||
|
@ -9,6 +9,7 @@
|
|||
* Wind River Systems - initial API and implementation
|
||||
* Ericsson - Modified for multi threaded functionality
|
||||
* Patrick Chuong (Texas Instruments) - Add support for icon overlay in the debug view (Bug 334566)
|
||||
* Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch;
|
||||
|
||||
|
@ -42,7 +43,6 @@ import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
|
|||
import org.eclipse.cdt.dsf.ui.viewmodel.ModelProxyInstalledEvent;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
|
||||
|
@ -68,7 +68,7 @@ import org.eclipse.debug.ui.IDebugUIConstants;
|
|||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public abstract class AbstractThreadVMNode extends AbstractDMVMNode
|
||||
public abstract class AbstractThreadVMNode extends AbstractExecutionContextVMNode
|
||||
implements IElementLabelProvider, IElementPropertiesProvider
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2010 IBM Corporation and others.
|
||||
* Copyright (c) 2005, 2011 IBM Corporation 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Wind River Systems - adapted to use with DSF
|
||||
* Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.ui.viewmodel;
|
||||
|
||||
|
@ -21,6 +22,7 @@ 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.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.core.runtime.ISafeRunnable;
|
||||
import org.eclipse.core.runtime.ListenerList;
|
||||
import org.eclipse.core.runtime.SafeRunner;
|
||||
|
@ -63,6 +65,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
private boolean fDisposed = false;
|
||||
private ListenerList fListeners = new ListenerList();
|
||||
private IDoubleClickListener fDoubleClickListener;
|
||||
private boolean fAllowRecursiveVMNodes = false;
|
||||
|
||||
/**
|
||||
* Creates this model proxy strategy for the given provider.
|
||||
|
@ -337,7 +340,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
// of the viewer. Get the root node of the chain--i.e.,
|
||||
// the delta for the root element of the entire viewer.
|
||||
final IModelDelta viewRootDelta = getRootDelta(getData());
|
||||
|
||||
|
||||
// Find the child nodes that (may) have deltas for the given event.
|
||||
final Map<IVMNode,Integer> childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(rootNode, getData(), event);
|
||||
|
||||
|
@ -695,8 +698,36 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
delta.setChildCount(getData().get(null));
|
||||
|
||||
for (final IVMNode childNode : childNodes.keySet()) {
|
||||
// Avoid descending into recursive node hierarchy's when calculating the delta.
|
||||
if (node.equals(childNode)) continue;
|
||||
|
||||
if (node.equals(childNode)) {
|
||||
|
||||
// Avoid descending into recursive node hierarchy's when calculating the delta.
|
||||
// if recursive nodes are not allowed.
|
||||
if( !allowRecursiveVMNodes())
|
||||
continue;
|
||||
|
||||
// get into recursion to build the delta only if the recursive context is added.
|
||||
//
|
||||
// We user current assumption that recursive container can be added as first children
|
||||
// if the list of VMNodes. If we decide to make the patch more generic ( allow recursive
|
||||
// node to be at different index) we need to remove this simplification.
|
||||
//
|
||||
if( isDeltaElementOfType(delta, childNode)) {
|
||||
childNode.buildDelta(
|
||||
event, delta, 0,
|
||||
new RequestMonitor(getVMProvider().getExecutor(), multiRm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
buildChildDeltas(
|
||||
childNode, event, delta, 0,
|
||||
new RequestMonitor(getVMProvider().getExecutor(), multiRm) );
|
||||
}
|
||||
});
|
||||
multiRmCount++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
final int nodeOffset = getData().get(childNode);
|
||||
childNode.buildDelta(
|
||||
|
@ -793,7 +824,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
protected Map<IVMNode, Integer> getChildNodesWithDeltaFlags(IVMNode node, ModelDelta parentDelta, Object e) {
|
||||
Map<IVMNode, Integer> nodes = new HashMap<IVMNode, Integer>();
|
||||
for (final IVMNode childNode : getVMProvider().getChildVMNodes(node)) {
|
||||
if (!childNode.equals(node)) {
|
||||
if (!childNode.equals(node) || allowRecursiveVMNodes()) {
|
||||
int delta = getDeltaFlags(childNode, parentDelta, e);
|
||||
if (delta != IModelDelta.NO_CHANGE) {
|
||||
nodes.put(childNode, delta);
|
||||
|
@ -803,5 +834,57 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether DefaultVMModelProxyStrategy allows to handles recursive VMNdoes hierarchy.
|
||||
*
|
||||
* @see setAllowRecursiveVMNodes()
|
||||
* @return true if this DefaultVMModelProxyStrategy allows recursive containers.
|
||||
*/
|
||||
public boolean allowRecursiveVMNodes() {
|
||||
return fAllowRecursiveVMNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow DefaultVMModelProxyStrategy to handles recursive VMNdoes hierarchy.
|
||||
*
|
||||
* For example if the client wants the debug view to display container nodes that
|
||||
* have containers this flag has to be set.
|
||||
*
|
||||
* Launch1
|
||||
* Container-1
|
||||
* Container-1.1
|
||||
* Thread-1
|
||||
* Container-1.1.1
|
||||
* Thread-2
|
||||
* Thread-2
|
||||
*
|
||||
* This will allow the client to setup a VMNode to be in the list of its children.
|
||||
* addChildNodes(containerNode, new IVMNode[] { containerNode, threadsNode });
|
||||
*
|
||||
* The client also need to make sure the recursive VMNodes and their immediate children:
|
||||
* 1. Handles buildDelta() by building one level at a time by examining the delta passed as parameter.
|
||||
* 2. Returns the correct level container inside getContextsForEvent() based on the delta passed.
|
||||
*
|
||||
* See org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch.ContainerVMNode for sample implementation.
|
||||
*
|
||||
* @param allow - whether to allow or not recursive containment of VMNodes.
|
||||
*/
|
||||
public void setAllowRecursiveVMNodes( boolean allow) {
|
||||
fAllowRecursiveVMNodes = allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares if the VMNode of element of the provided delta is the same as the provided IVMNode.
|
||||
*
|
||||
* @param delta - delta for which to compare the IDMVMContext
|
||||
* @param node - the IVMNode we want to compare to.
|
||||
* @return if the VMNode of element of the provided delta is the same as the provided IVMNode.
|
||||
*/
|
||||
protected boolean isDeltaElementOfType( VMDelta delta, IVMNode node) {
|
||||
if( delta.getElement() instanceof IDMVMContext) {
|
||||
IDMVMContext dmvmContext = (IDMVMContext)delta.getElement();
|
||||
return dmvmContext.getVMNode().equals(node);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ Bundle-ActivationPolicy: lazy
|
|||
Export-Package: org.eclipse.cdt.dsf.concurrent,
|
||||
org.eclipse.cdt.dsf.datamodel,
|
||||
org.eclipse.cdt.dsf.debug.internal.provisional.model;x-friends:="org.eclipse.cdt.dsf.ui",
|
||||
org.eclipse.cdt.dsf.debug.internal.provisional.service;x-internal:=true,
|
||||
org.eclipse.cdt.dsf.debug.model,
|
||||
org.eclipse.cdt.dsf.debug.service,
|
||||
org.eclipse.cdt.dsf.debug.service.command,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2009 Wind River Systems and others.
|
||||
* Copyright (c) 2006, 2011 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
* Ericsson - Modified for additional features in DSF Reference implementation
|
||||
* Dobrin Alexiev (Texas Instruments) - added helpers for recursive data model contexts (bug 240208)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.datamodel;
|
||||
|
||||
|
@ -73,6 +74,63 @@ public class DMContexts {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the top most ancestor of the specified type.
|
||||
* It assumes only one immediate parent of the give type exists.
|
||||
* The search is done until there is no more immediate parents of the given type.
|
||||
* The method returns the last one found.
|
||||
*
|
||||
* @param <V>
|
||||
* @param ctx DMC to search.
|
||||
* @param ancestorType Class type of the desired DMC ancestor.
|
||||
* @return Returns the ancestor if found, null otherwise.
|
||||
* @since 2.2
|
||||
*/
|
||||
@ThreadSafe
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <V extends IDMContext> V getTopMostAncestorOfType(IDMContext ctx, Class<V> ancestorType) {
|
||||
if(ctx == null)
|
||||
return null;
|
||||
|
||||
V topMostAncestor = null;
|
||||
boolean hasAncestorOfType = false;
|
||||
IDMContext current = ctx;
|
||||
do {
|
||||
hasAncestorOfType = false;
|
||||
IDMContext[] parents = current.getParents();
|
||||
for( IDMContext parent : parents) {
|
||||
if (ancestorType.isAssignableFrom(parent.getClass())) {
|
||||
hasAncestorOfType = true;
|
||||
topMostAncestor = (V) parent;
|
||||
current = parent;
|
||||
}
|
||||
}
|
||||
|
||||
} while( hasAncestorOfType);
|
||||
return topMostAncestor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the immediate parent of the specified type if exists.
|
||||
*
|
||||
* @param ctx DMC to search.
|
||||
* @param ancestorType Class type of the desired DMC ancestor.
|
||||
* @return Returns the ancestor if found, null otherwise.
|
||||
* @since 2.2
|
||||
*/
|
||||
@ThreadSafe
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <V extends IDMContext> V getParentOfType(IDMContext ctx, Class<V> ancestorType) {
|
||||
if(ctx == null)
|
||||
return null;
|
||||
|
||||
for( IDMContext parent : ctx.getParents())
|
||||
if (ancestorType.isAssignableFrom(parent.getClass()))
|
||||
return (V)parent;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all data model contexts of given type among ancestors of the
|
||||
* specified context. Ancestors are returned in order of closest to farthest,
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, 2011 Texas Instruments, 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:
|
||||
* Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 240208)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.internal.provisional.service;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.service.IDsfService;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL. This class or interface has been added as part
|
||||
* of a work in progress. There is no guarantee that this API will work or that
|
||||
* it will remain the same.
|
||||
*
|
||||
* Interface for translating one model of execution context hierarchy to another.
|
||||
* As the grouping feature is added incrementally this interface will be defined properly.
|
||||
*
|
||||
* The reason this interface is proposed at the DSF level is to accommodate requirements from
|
||||
* multiple DSF debuggers.
|
||||
*
|
||||
* @since 2.2
|
||||
* @experimental
|
||||
*/
|
||||
public interface IExecutionContextTranslator extends IDsfService {
|
||||
|
||||
/**
|
||||
* returns true if all DM contexts can be grouped into one container.
|
||||
*
|
||||
* @param context
|
||||
* @param rm
|
||||
*/
|
||||
void canGroup(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm);
|
||||
|
||||
/**
|
||||
* returns true if all DM contexts can be ungrouped.
|
||||
*
|
||||
* @param context
|
||||
* @param rm
|
||||
*/
|
||||
void canUngroup(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm);
|
||||
|
||||
/**
|
||||
* Groups the specified execution contexts.
|
||||
*
|
||||
* @param context
|
||||
* @param requestMonitor
|
||||
*/
|
||||
void group(IExecutionDMContext[] contexts, RequestMonitor requestMonitor);
|
||||
|
||||
/**
|
||||
* Ungroups the specified execution contexts.
|
||||
*
|
||||
* @param context
|
||||
* @param requestMonitor
|
||||
*/
|
||||
void ungroup(IExecutionDMContext[] contexts, RequestMonitor requestMonitor);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2009 Ericsson and others.
|
||||
* Copyright (c) 2008, 2011 Ericsson 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
|
||||
|
@ -7,9 +7,11 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
*******************************************************************************/
|
||||
* Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208)
|
||||
********************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.service;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.internal.provisional.service.IExecutionContextTranslator;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
|
||||
|
@ -48,6 +50,8 @@ public abstract class AbstractDsfDebugServicesFactory implements IDsfDebugServic
|
|||
return (V)createStackService(session);
|
||||
} else if (ISymbols.class.isAssignableFrom(clazz)) {
|
||||
return (V)createSymbolsService(session);
|
||||
} else if (IExecutionContextTranslator.class.isAssignableFrom(clazz)) {
|
||||
return (V)createExecutionContextTranslator(session);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -66,5 +70,10 @@ public abstract class AbstractDsfDebugServicesFactory implements IDsfDebugServic
|
|||
protected ISignals createSignalsService(DsfSession session) { return null; }
|
||||
protected IStack createStackService(DsfSession session) { return null; }
|
||||
protected ISymbols createSymbolsService(DsfSession session) { return null; }
|
||||
|
||||
/**
|
||||
* @since 2.2
|
||||
*/
|
||||
protected IExecutionContextTranslator createExecutionContextTranslator( DsfSession session) { return null; }
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue