Browse Source

ObjecObject graph visualizer - refactored ObjectGraph - ordering of children, preparation for expanding nodes.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4202 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Martin Koníček 17 years ago
parent
commit
811e7c2f6a
  1. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/GraphDrawer.cs
  2. 25
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/Tree/TreeLayouter.cs
  3. 4
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectEdge.cs
  4. 4
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraph.cs
  5. 26
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
  6. 93
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectNode.cs
  7. 14
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectProperty.cs
  8. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/VisualizerWinFormsControl.cs

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/GraphDrawer.cs

@ -44,7 +44,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -44,7 +44,7 @@ namespace Debugger.AddIn.Visualizers.Graph
return;
}
double seconds = 1;
double seconds = 0.5;
var durationMove = new Duration(TimeSpan.FromSeconds(seconds));
var durationFade = durationMove;

25
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/Tree/TreeLayouter.cs

@ -68,19 +68,22 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -68,19 +68,22 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
treeNodeFor[objectGraphNode] = newTreeNode;
double subtreeSize = 0;
foreach (ObjectEdge edge in objectGraphNode.Edges)
foreach (ObjectProperty property in objectGraphNode.ComplexProperties)
{
ObjectNode neighbor = edge.TargetNode;
if (seenNodes.ContainsKey(neighbor))
if (property.TargetNode != null)
{
newTreeNode.AdditionalNeighbors.Add(new TreeEdge { Name = edge.Name, SourceNode = newTreeNode, TargetNode = treeNodeFor[neighbor]});
}
else
{
TreeNode newChild = buildTreeRecursive(neighbor);
newTreeNode.ChildEdges.Add(new TreeEdge { Name = edge.Name, SourceNode = newTreeNode, TargetNode = newChild});
subtreeSize += newChild.SubtreeSize;
ObjectNode neighbor = property.TargetNode;
if (seenNodes.ContainsKey(neighbor))
{
newTreeNode.AdditionalNeighbors.Add(new TreeEdge { Name = property.Name, SourceNode = newTreeNode, TargetNode = treeNodeFor[neighbor]});
}
else
{
TreeNode newChild = buildTreeRecursive(neighbor);
newTreeNode.ChildEdges.Add(new TreeEdge { Name = property.Name, SourceNode = newTreeNode, TargetNode = newChild});
subtreeSize += newChild.SubtreeSize;
}
}
}
subtreeSize = Math.Max(newTreeNode.LateralSizeWithMargin, subtreeSize);

4
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectEdge.cs

@ -13,7 +13,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -13,7 +13,7 @@ namespace Debugger.AddIn.Visualizers.Graph
/// <summary>
/// Named edge in the <see cref="ObjectGraph" />.
/// </summary>
public class ObjectEdge : NamedEdge<ObjectNode>
/*public class ObjectEdge : NamedEdge<ObjectNode>
{
}
}*/
}

4
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraph.cs

@ -41,7 +41,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -41,7 +41,7 @@ namespace Debugger.AddIn.Visualizers.Graph
/// <summary>
/// All edges in the graph.
/// </summary>
public IEnumerable<ObjectEdge> Edges
/*public IEnumerable<ObjectEdge> Edges
{
get
{
@ -53,6 +53,6 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -53,6 +53,6 @@ namespace Debugger.AddIn.Visualizers.Graph
}
}
}
}
}*/
}
}

26
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs

@ -107,13 +107,20 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -107,13 +107,20 @@ namespace Debugger.AddIn.Visualizers.Graph
{
ObjectNode thisNode = createNewNode(rootValue);
// David: by calling this, we get an array of values, most of them probably invalid,
// it would be nice to be able to get a collection of 'values'
// that are valid (basically a snapshot of object's state)
// - a collection of custom objects,
// that contain the string value and DebugType,
// and can enumerate child values.
// It would be also nice to return IEnumerable or ReadonlyCollection
// http://blogs.msdn.com/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx
/*string[] memberValues = rootValue.GetMemberValuesAsString(_bindingFlags);
foreach (string memberValue in memberValues)
{
//Value memberValuePerm = memberValue.GetPermanentReference();
}*/
foreach(Expression memberExpr in rootValue.Expression.AppendObjectMembers(rootValue.Type, _bindingFlags))
{
@ -123,27 +130,30 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -123,27 +130,30 @@ namespace Debugger.AddIn.Visualizers.Graph
if (isOfAtomicType(memberExpr))
{
// atomic members are added to the list of node's "properties"
string memberValueAsString = memberExpr.Evaluate(debuggerService.DebuggedProcess).AsString;
thisNode.AddProperty(memberName, memberValueAsString);
string memberValueAsString = memberExpr.Evaluate(debuggerService.DebuggedProcess).AsString;
thisNode.AddAtomicProperty(memberName, memberValueAsString, memberExpr);
}
else
{
ObjectNode targetNode = null;
if (!isNull(memberExpr))
{
// for object members, edges are added
Value memberValue = getPermanentReference(memberExpr);
// if node for memberValue already exists, only add edge to it (so loops etc. are solved correctly)
ObjectNode targetNode = getNodeForValue(memberValue);
targetNode = getNodeForValue(memberValue);
if (targetNode == null)
{
// if no node for memberValue exists, build the subgraph for the value
targetNode = buildGraphRecursive(memberValue);
}
// add the edge
thisNode.AddNamedEdge(targetNode, memberName);
}
else
{
targetNode = null;
}
thisNode.AddComplexProperty(memberName, "", memberExpr, targetNode);
}
}
@ -203,7 +213,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -203,7 +213,7 @@ namespace Debugger.AddIn.Visualizers.Graph
/// <returns>Hash code of the object in the debugee.</returns>
private int invokeGetHashCode(Value value)
{
// Dadid: I had hard time finding out how to invoke static method
// David: I had hard time finding out how to invoke static method
// value.InvokeMethod is nice for instance methods.
// what about MethodInfo.Invoke() ?
// also, there could be an overload that takes 1 parameter instead of array

93
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectNode.cs

@ -7,21 +7,22 @@ @@ -7,21 +7,22 @@
using System;
using System.Collections.Generic;
using System.Text;
using Debugger.Expressions;
namespace Debugger.AddIn.Visualizers.Graph
{
/// <summary>
/// Node in the <see cref="ObjectGraph" />.
/// </summary>
public class ObjectNode
{
/// <summary>
public class ObjectNode
{
/// <summary>
/// Additional info useful for internal algorithms, not to be visible to the user.
/// </summary>
internal Debugger.Value PermanentReference { get; set; }
internal int HashCode { get; set; }
private List<ObjectEdge> _edges = new List<ObjectEdge>();
internal Debugger.Value PermanentReference { get; set; }
internal int HashCode { get; set; }
/*private List<ObjectEdge> _edges = new List<ObjectEdge>();
/// <summary>
/// Outgoing edges.
/// </summary>
@ -36,23 +37,67 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -36,23 +37,67 @@ namespace Debugger.AddIn.Visualizers.Graph
internal void AddNamedEdge(ObjectNode targetNode, string edgeName)
{
_edges.Add(new ObjectEdge { Name = edgeName, SourceNode = this, TargetNode = targetNode });
}
}*/
class PropertyComparer : IComparer<ObjectProperty>
{
public int Compare(ObjectProperty prop1, ObjectProperty prop2)
{
return prop1.Name.CompareTo(prop2.Name);
}
}
private static PropertyComparer propertySortComparer = new PropertyComparer();
private bool sorted = false;
private List<ObjectProperty> _properties = new List<ObjectProperty>();
/// <summary>
/// Properties representing atomic string values as part of the node.
/// </summary>
public List<ObjectProperty> Properties
{
get { return _properties; }
}
private List<ObjectProperty> _properties = new List<ObjectProperty>();
/// <summary>
/// Properties (either atomic or complex) of the object this node represents.
/// </summary>
public List<ObjectProperty> Properties
{
get
{
if (!sorted)
{
_properties.Sort(propertySortComparer);
sorted = true;
}
return _properties;
}
}
/// <summary>
/// Only complex properties filtered out of <see cref="Properties"/>
/// </summary>
public IEnumerable<ObjectProperty> ComplexProperties
{
get
{
foreach (var property in Properties)
{
if (!property.IsAtomic)
yield return property;
}
}
}
/// <summary>
/// Adds string property.
/// </summary>
internal void AddProperty(string name, string value)
{
_properties.Add(new ObjectProperty { Name = name, Value = value });
}
}
/// <summary>
/// Adds primitive property.
/// </summary>
internal void AddAtomicProperty(string name, string value, Expression expression)
{
_properties.Add(new ObjectProperty
{ Name = name, Value = value, Expression = expression, IsAtomic = true, TargetNode = null });
}
/// <summary>
/// Adds complex property.
/// </summary>
internal void AddComplexProperty(string name, string value, Expression expression, ObjectNode targetNode)
{
_properties.Add(new ObjectProperty
{ Name = name, Value = value, Expression = expression, IsAtomic = false, TargetNode = targetNode });
}
}
}

14
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectProperty.cs

@ -11,7 +11,7 @@ using System.Text; @@ -11,7 +11,7 @@ using System.Text;
namespace Debugger.AddIn.Visualizers.Graph
{
/// <summary>
/// Primitive property (int, string, etc.) of an object, in string form.
/// Primitive property of an object, in string form.
/// </summary>
public class ObjectProperty
{
@ -23,5 +23,17 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -23,5 +23,17 @@ namespace Debugger.AddIn.Visualizers.Graph
/// e.g. "19"
/// </summary>
public string Value { get; set; }
/// <summary>
/// Expression used for obtaining this property
/// </summary>
public Debugger.Expressions.Expression Expression { get; set; }
/// <summary>
/// Node that this property points to. Can be null. Always null if <see cref="IsAtomic"/> is true.
/// </summary>
public ObjectNode TargetNode { get; set; }
/// <summary>
/// Is this property of atomic type? (int, string, etc.)
/// </summary>
public bool IsAtomic { get; set; }
}
}

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/VisualizerWinFormsControl.cs

@ -72,7 +72,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -72,7 +72,7 @@ namespace Debugger.AddIn.Visualizers.Graph
}
// just a simple message for checking the graph is build ok, will be replaced by graph drawing of course
lblInfo.Text = string.Format("Done. Number of graph nodes: {0}, number of edges: {1}", graph.Nodes.Count(), graph.Edges.Count());
//lblInfo.Text = string.Format("Done. Number of graph nodes: {0}, number of edges: {1}", graph.Nodes.Count(), graph.Edges.Count());
}
void guiHandleException(System.Exception ex)

Loading…
Cancel
Save