mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-25 21:51:47 +00:00
Merge remote-tracking branch 'origin/GP-4134_Dan_modelTreeReload--SQUASHED'
This commit is contained in:
commit
aec8641320
@ -30,6 +30,7 @@ import ghidra.trace.model.*;
|
|||||||
import ghidra.trace.model.Trace.TraceObjectChangeType;
|
import ghidra.trace.model.Trace.TraceObjectChangeType;
|
||||||
import ghidra.trace.model.target.*;
|
import ghidra.trace.model.target.*;
|
||||||
import ghidra.util.HTMLUtilities;
|
import ghidra.util.HTMLUtilities;
|
||||||
|
import ghidra.util.LockHold;
|
||||||
import ghidra.util.datastruct.WeakValueHashMap;
|
import ghidra.util.datastruct.WeakValueHashMap;
|
||||||
import utilities.util.IDKeyed;
|
import utilities.util.IDKeyed;
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void domainObjectRestored(DomainObjectChangeRecord rec) {
|
public void domainObjectRestored(DomainObjectChangeRecord rec) {
|
||||||
reload();
|
reloadSameTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isEventValue(TraceObjectValue value) {
|
protected boolean isEventValue(TraceObjectValue value) {
|
||||||
@ -167,7 +168,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
}
|
}
|
||||||
AbstractNode node =
|
AbstractNode node =
|
||||||
byValue.computeIfAbsent(new IDKeyed<>(value), k -> createNode(value));
|
byValue.computeIfAbsent(new IDKeyed<>(value), k -> createNode(value));
|
||||||
node.unloadChildren();
|
//node.unloadChildren();
|
||||||
//AbstractNode node = createNode(value);
|
//AbstractNode node = createNode(value);
|
||||||
if (value.isCanonical()) {
|
if (value.isCanonical()) {
|
||||||
byObject.put(new IDKeyed<>(value.getChild()), node);
|
byObject.put(new IDKeyed<>(value.getChild()), node);
|
||||||
@ -204,6 +205,18 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
addNode(i, node);
|
addNode(i, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
/**
|
||||||
|
* Our nodes are re-usable. They're cached so that as an item comes and goes, its
|
||||||
|
* corresponding node can also come and go without being re-instantiated each time.
|
||||||
|
* Furthermore, it's like to have all the same children as before, too. For now, we'll
|
||||||
|
* just ignore dispose. If there's too many unexpected behaviors resulting from this,
|
||||||
|
* then perhaps we should just have dispose also remove itself from the node cache.
|
||||||
|
*/
|
||||||
|
// DO NOTHING
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(GTreeNode node) {
|
public int compareTo(GTreeNode node) {
|
||||||
return TargetObjectKeyComparator.CHILD.compare(this.getName(), node.getName());
|
return TargetObjectKeyComparator.CHILD.compare(this.getName(), node.getName());
|
||||||
@ -211,7 +224,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return getValue().getEntryKey() + "\n" + getValue().getMinSnap();
|
return getValue().getEntryKey() + "@" + getValue().getMinSnap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -260,6 +273,50 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
protected boolean isModified() {
|
protected boolean isModified() {
|
||||||
return isValueModified(getValue());
|
return isValueModified(getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected synchronized void reloadChildrenNow() {
|
||||||
|
if (!isLoaded()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Use a merge to effect the minimal changes to set the children
|
||||||
|
var current = List.copyOf(children());
|
||||||
|
var generated = generateChildren();
|
||||||
|
// NB. The two lists ought to be sorted already.
|
||||||
|
int ic = 0;
|
||||||
|
int ig = 0;
|
||||||
|
int diff = 0;
|
||||||
|
while (ic < current.size() && ig < generated.size()) {
|
||||||
|
GTreeNode nc = current.get(ic);
|
||||||
|
GTreeNode ng = generated.get(ig);
|
||||||
|
int comp = nc.compareTo(ng);
|
||||||
|
if (comp == 0) {
|
||||||
|
ic++;
|
||||||
|
ig++;
|
||||||
|
}
|
||||||
|
else if (comp < 0) {
|
||||||
|
removeNode(nc);
|
||||||
|
diff--;
|
||||||
|
ic++;
|
||||||
|
}
|
||||||
|
else { // comp > 0
|
||||||
|
addNode(ic + diff, ng);
|
||||||
|
diff++;
|
||||||
|
ig++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (ic < current.size()) {
|
||||||
|
GTreeNode nc = current.get(ic);
|
||||||
|
removeNode(nc);
|
||||||
|
// diff--; // Not really needed
|
||||||
|
ic++;
|
||||||
|
}
|
||||||
|
while (ig < generated.size()) {
|
||||||
|
GTreeNode ng = generated.get(ig);
|
||||||
|
addNode(ic + diff, ng);
|
||||||
|
diff++;
|
||||||
|
ig++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RootNode extends AbstractNode {
|
class RootNode extends AbstractNode {
|
||||||
@ -670,6 +727,15 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
root.unloadChildren();
|
root.unloadChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void reloadSameTrace() {
|
||||||
|
try (LockHold hold = trace == null ? null : trace.lockRead()) {
|
||||||
|
for (AbstractNode node : List.copyOf(nodeCache.byObject.values())) {
|
||||||
|
node.reloadChildrenNow();
|
||||||
|
}
|
||||||
|
root.reloadChildrenNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setTrace(Trace trace) {
|
public void setTrace(Trace trace) {
|
||||||
if (this.trace == trace) {
|
if (this.trace == trace) {
|
||||||
return;
|
return;
|
||||||
@ -761,7 +827,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void spanChanged() {
|
protected void spanChanged() {
|
||||||
reload();
|
reloadSameTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSpan(Lifespan span) {
|
public void setSpan(Lifespan span) {
|
||||||
@ -777,7 +843,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void showHiddenChanged() {
|
protected void showHiddenChanged() {
|
||||||
reload();
|
reloadSameTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowHidden(boolean showHidden) {
|
public void setShowHidden(boolean showHidden) {
|
||||||
@ -793,7 +859,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void showPrimitivesChanged() {
|
protected void showPrimitivesChanged() {
|
||||||
reload();
|
reloadSameTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowPrimitives(boolean showPrimitives) {
|
public void setShowPrimitives(boolean showPrimitives) {
|
||||||
@ -809,7 +875,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void showMethodsChanged() {
|
protected void showMethodsChanged() {
|
||||||
reload();
|
reloadSameTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowMethods(boolean showMethods) {
|
public void setShowMethods(boolean showMethods) {
|
||||||
|
@ -153,7 +153,7 @@ public class ObjectsTreePanel extends JPanel {
|
|||||||
if (limitToSnap) {
|
if (limitToSnap) {
|
||||||
treeModel.setSpan(Lifespan.at(current.getSnap()));
|
treeModel.setSpan(Lifespan.at(current.getSnap()));
|
||||||
}
|
}
|
||||||
tree.filterChanged();
|
//tree.filterChanged();
|
||||||
// Repaint for bold current path is already going to happen
|
// Repaint for bold current path is already going to happen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,7 +299,6 @@ public class ObjectsTreePanel extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setSelectedObject(TraceObject object) {
|
public void setSelectedObject(TraceObject object) {
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
tree.clearSelectionPaths();
|
tree.clearSelectionPaths();
|
||||||
|
@ -410,7 +410,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
|||||||
GTree tree = modelProvider.objectsTreePanel.tree;
|
GTree tree = modelProvider.objectsTreePanel.tree;
|
||||||
GTreeNode node = waitForPass(() -> {
|
GTreeNode node = waitForPass(() -> {
|
||||||
GTreeNode n = Unique.assertOne(tree.getSelectedNodes());
|
GTreeNode n = Unique.assertOne(tree.getSelectedNodes());
|
||||||
assertEquals("Processes\n0", n.getName());
|
assertEquals("Processes@0", n.getName());
|
||||||
return n;
|
return n;
|
||||||
});
|
});
|
||||||
clickTreeNode(tree, node, MouseEvent.BUTTON1);
|
clickTreeNode(tree, node, MouseEvent.BUTTON1);
|
||||||
|
Loading…
Reference in New Issue
Block a user