|
Added
Link Here
|
| 1 |
/******************************************************************************* |
| 2 |
* Copyright (c) 2011 Ericsson and others. |
| 3 |
* All rights reserved. This program and the accompanying materials |
| 4 |
* are made available under the terms of the Eclipse Public License v1.0 |
| 5 |
* which accompanies this distribution, and is available at |
| 6 |
* http://www.eclipse.org/legal/epl-v10.html |
| 7 |
* |
| 8 |
* Contributors: |
| 9 |
* Ericsson - initial API and implementation |
| 10 |
*******************************************************************************/ |
| 11 |
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch; |
| 12 |
|
| 13 |
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; |
| 14 |
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode; |
| 15 |
import org.eclipse.cdt.dsf.gdb.launching.GDBProcess; |
| 16 |
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider; |
| 17 |
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta; |
| 18 |
import org.eclipse.debug.core.DebugEvent; |
| 19 |
import org.eclipse.debug.core.ILaunch; |
| 20 |
import org.eclipse.debug.core.model.IProcess; |
| 21 |
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; |
| 22 |
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; |
| 23 |
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; |
| 24 |
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; |
| 25 |
import org.eclipse.jface.viewers.TreePath; |
| 26 |
|
| 27 |
/** |
| 28 |
* Layout node for the standard platform debug model IProcess object. This |
| 29 |
* node requires that an ILaunch object be found as an ancestor of this node. |
| 30 |
* It does not implement the label provider functionality, so the default |
| 31 |
* adapters should be used to retrieve the label. |
| 32 |
* |
| 33 |
* This version is specific to DSF-GDB to only show the GDB process. |
| 34 |
*/ |
| 35 |
public class GdbStandardProcessVMNode extends StandardProcessVMNode { |
| 36 |
|
| 37 |
// We only want to show the GDB process and not the inferiors. |
| 38 |
// The inferior was not considered valuable and would waste space |
| 39 |
// especially in multi-process debugging |
| 40 |
private final static Class<?> fProcessType = GDBProcess.class; |
| 41 |
|
| 42 |
public GdbStandardProcessVMNode(AbstractVMProvider provider) { |
| 43 |
super(provider); |
| 44 |
} |
| 45 |
|
| 46 |
@Override |
| 47 |
public String toString() { |
| 48 |
return "GdbStandardProcessVMNode"; //$NON-NLS-1$ |
| 49 |
} |
| 50 |
|
| 51 |
@Override |
| 52 |
public void update(IChildrenUpdate[] updates) { |
| 53 |
for (IChildrenUpdate update : updates) { |
| 54 |
ILaunch launch = findLaunch(update.getElementPath()); |
| 55 |
if (launch == null) { |
| 56 |
// There is no launch in the parent of this node. This means that the |
| 57 |
// layout is misconfigured. |
| 58 |
assert false; |
| 59 |
update.done(); |
| 60 |
continue; |
| 61 |
} |
| 62 |
|
| 63 |
/* |
| 64 |
* Assume that the process objects are stored within the launch, and |
| 65 |
* retrieve them on dispatch thread. |
| 66 |
*/ |
| 67 |
int count = 0; |
| 68 |
for (IProcess process : launch.getProcesses()) { |
| 69 |
if (fProcessType.isAssignableFrom(process.getClass())) { |
| 70 |
update.setChild(process, count++); |
| 71 |
} |
| 72 |
} |
| 73 |
update.done(); |
| 74 |
} |
| 75 |
} |
| 76 |
|
| 77 |
@Override |
| 78 |
public void update(final IChildrenCountUpdate[] updates) { |
| 79 |
for (IChildrenCountUpdate update : updates) { |
| 80 |
if (!checkUpdate(update)) continue; |
| 81 |
ILaunch launch = findLaunch(update.getElementPath()); |
| 82 |
if (launch == null) { |
| 83 |
assert false; |
| 84 |
update.setChildCount(0); |
| 85 |
update.done(); |
| 86 |
return; |
| 87 |
} |
| 88 |
|
| 89 |
int count = 0; |
| 90 |
for (IProcess process : launch.getProcesses()) { |
| 91 |
if (fProcessType.isAssignableFrom(process.getClass())) { |
| 92 |
count++; |
| 93 |
} |
| 94 |
} |
| 95 |
update.setChildCount(count); |
| 96 |
update.done(); |
| 97 |
} |
| 98 |
} |
| 99 |
|
| 100 |
// @see org.eclipse.cdt.dsf.ui.viewmodel.IViewModelLayoutNode#hasElements(org.eclipse.cdt.dsf.ui.viewmodel.IVMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) |
| 101 |
@Override |
| 102 |
public void update(IHasChildrenUpdate[] updates) { |
| 103 |
for (IHasChildrenUpdate update : updates) { |
| 104 |
ILaunch launch = findLaunch(update.getElementPath()); |
| 105 |
if (launch == null) { |
| 106 |
assert false; |
| 107 |
update.setHasChilren(false); |
| 108 |
update.done(); |
| 109 |
return; |
| 110 |
} |
| 111 |
|
| 112 |
boolean hasChildren = false; |
| 113 |
for (IProcess process : launch.getProcesses()) { |
| 114 |
if (fProcessType.isAssignableFrom(process.getClass())) { |
| 115 |
hasChildren = true; |
| 116 |
break; |
| 117 |
} |
| 118 |
} |
| 119 |
|
| 120 |
update.setHasChilren(hasChildren); |
| 121 |
update.done(); |
| 122 |
} |
| 123 |
} |
| 124 |
|
| 125 |
/** |
| 126 |
* Recursively searches the VMC for Launch VMC, and returns its ILaunch. |
| 127 |
* Returns null if an ILaunch is not found. |
| 128 |
*/ |
| 129 |
private ILaunch findLaunch(TreePath path) { |
| 130 |
for (int i = path.getSegmentCount() - 1; i >= 0; i--) { |
| 131 |
if (path.getSegment(i) instanceof ILaunch) { |
| 132 |
return (ILaunch)path.getSegment(i); |
| 133 |
} |
| 134 |
} |
| 135 |
return null; |
| 136 |
} |
| 137 |
|
| 138 |
@Override |
| 139 |
public int getDeltaFlags(Object e) { |
| 140 |
int myFlags = 0; |
| 141 |
if (e instanceof DebugEvent) { |
| 142 |
DebugEvent de = (DebugEvent)e; |
| 143 |
if (fProcessType.isAssignableFrom(de.getSource().getClass()) && |
| 144 |
(de.getKind() == DebugEvent.CHANGE || |
| 145 |
de.getKind() == DebugEvent.CREATE || |
| 146 |
de.getKind() == DebugEvent.TERMINATE) ) |
| 147 |
{ |
| 148 |
myFlags = IModelDelta.STATE; |
| 149 |
} |
| 150 |
} |
| 151 |
return myFlags; |
| 152 |
} |
| 153 |
|
| 154 |
@Override |
| 155 |
public void buildDelta(Object e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { |
| 156 |
if (e instanceof DebugEvent && fProcessType.isAssignableFrom(((DebugEvent)e).getSource().getClass())) { |
| 157 |
DebugEvent de = (DebugEvent)e; |
| 158 |
if (de.getKind() == DebugEvent.CHANGE) { |
| 159 |
handleChange(de, parent); |
| 160 |
} else if (de.getKind() == DebugEvent.CREATE) { |
| 161 |
handleCreate(de, parent); |
| 162 |
} else if (de.getKind() == DebugEvent.TERMINATE) { |
| 163 |
handleTerminate(de, parent); |
| 164 |
} |
| 165 |
/* |
| 166 |
* No other node should need to process events related to process. |
| 167 |
* Therefore, just invoke the request monitor without calling super.buildDelta(). |
| 168 |
*/ |
| 169 |
} |
| 170 |
requestMonitor.done(); |
| 171 |
} |
| 172 |
} |