Browse Source

Abort variable refresh if debuggee is stepped

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2810 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 18 years ago
parent
commit
ff0b8866e1
  1. 1
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj
  2. 19
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs
  3. 48
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Adapters/TreeViewNode.cs
  4. 43
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Util.cs
  5. 3
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Expressions/Expression.Evaluate.cs

1
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj

@ -73,6 +73,7 @@
<Compile Include="Src\TreeModel\ISetText.cs" /> <Compile Include="Src\TreeModel\ISetText.cs" />
<Compile Include="Src\TreeModel\ChildNodesOfObject.cs" /> <Compile Include="Src\TreeModel\ChildNodesOfObject.cs" />
<Compile Include="Src\TreeModel\StackFrameNode.cs" /> <Compile Include="Src\TreeModel\StackFrameNode.cs" />
<Compile Include="Src\TreeModel\Util.cs" />
<None Include="COPYING" /> <None Include="COPYING" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

19
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs

@ -106,6 +106,14 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
} }
} }
public TreeViewAdv LocalVarList {
get { return localVarList; }
}
public Process Process {
get { return debuggedProcess; }
}
protected override void InitializeComponents() protected override void InitializeComponents()
{ {
localVarList = new TreeViewAdv(); localVarList = new TreeViewAdv();
@ -167,10 +175,13 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public override void RefreshPad() public override void RefreshPad()
{ {
DateTime start = Debugger.Util.HighPrecisionTimer.Now; DateTime start = Debugger.Util.HighPrecisionTimer.Now;
if (debuggedProcess != null && debuggedProcess.SelectedStackFrame != null) { try {
TreeViewNode.SetContentRecursive(localVarList, localVarList.Root.Children, new StackFrameNode(debuggedProcess.SelectedStackFrame).ChildNodes); if (debuggedProcess != null && debuggedProcess.SelectedStackFrame != null) {
} else { TreeViewNode.SetContentRecursive(this, localVarList.Root.Children, new StackFrameNode(debuggedProcess.SelectedStackFrame).ChildNodes);
TreeViewNode.SetContentRecursive(localVarList, localVarList.Root.Children, null); } else {
TreeViewNode.SetContentRecursive(this, localVarList.Root.Children, null);
}
} catch(AbortedBecauseDebugeeStateExpiredException) {
} }
DateTime end = Debugger.Util.HighPrecisionTimer.Now; DateTime end = Debugger.Util.HighPrecisionTimer.Now;
LoggingService.InfoFormatted("Local Variables pad refreshed ({0} ms)", (end - start).TotalMilliseconds); LoggingService.InfoFormatted("Local Variables pad refreshed ({0} ms)", (end - start).TotalMilliseconds);

48
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Adapters/TreeViewNode.cs

@ -13,6 +13,7 @@ using System.Windows.Forms;
using Aga.Controls.Tree; using Aga.Controls.Tree;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui.Pads;
namespace Debugger.AddIn.TreeModel namespace Debugger.AddIn.TreeModel
{ {
@ -20,6 +21,7 @@ namespace Debugger.AddIn.TreeModel
{ {
static Dictionary<string, bool> expandedNodes = new Dictionary<string, bool>(); static Dictionary<string, bool> expandedNodes = new Dictionary<string, bool>();
LocalVarPad localVarPad;
AbstractNode content; AbstractNode content;
bool childsLoaded; bool childsLoaded;
@ -38,8 +40,9 @@ namespace Debugger.AddIn.TreeModel
} }
} }
public TreeViewNode(TreeViewAdv tree, AbstractNode content): base(tree, new object()) public TreeViewNode(LocalVarPad localVarPad, AbstractNode content): base(localVarPad.LocalVarList, new object())
{ {
this.localVarPad = localVarPad;
SetContentRecursive(content); SetContentRecursive(content);
} }
@ -56,13 +59,19 @@ namespace Debugger.AddIn.TreeModel
this.Collapse(); this.Collapse();
} }
this.Tree.Invalidate(); this.Tree.Invalidate();
// Repaint and process user commands
DebugeeState state = localVarPad.Process.DebugeeState;
Util.DoEvents();
if (state.HasExpired) {
LoggingService.Info("Debugger: Aborted refresh because debugee state expired");
throw new AbortedBecauseDebugeeStateExpiredException();
}
} }
public static void SetContentRecursive(TreeViewAdv tree, IList<TreeNodeAdv> childNodes, IEnumerable<AbstractNode> contentEnum) public static void SetContentRecursive(LocalVarPad localVarPad, IList<TreeNodeAdv> childNodes, IEnumerable<AbstractNode> contentEnum)
{ {
contentEnum = contentEnum ?? new AbstractNode[0]; contentEnum = contentEnum ?? new AbstractNode[0];
DoEvents();
int index = 0; int index = 0;
foreach(AbstractNode content in contentEnum) { foreach(AbstractNode content in contentEnum) {
// Add or overwrite existing items // Add or overwrite existing items
@ -71,9 +80,8 @@ namespace Debugger.AddIn.TreeModel
((TreeViewNode)childNodes[index]).SetContentRecursive(content); ((TreeViewNode)childNodes[index]).SetContentRecursive(content);
} else { } else {
// Add // Add
childNodes.Add(new TreeViewNode(tree, content)); childNodes.Add(new TreeViewNode(localVarPad, content));
} }
DoEvents();
index++; index++;
} }
int count = index; int count = index;
@ -81,20 +89,22 @@ namespace Debugger.AddIn.TreeModel
while(childNodes.Count > count) { while(childNodes.Count > count) {
childNodes.RemoveAt(count); childNodes.RemoveAt(count);
} }
DoEvents();
} }
protected override void OnExpanding() protected override void OnExpanding()
{ {
base.OnExpanding(); base.OnExpanding();
LoadChilds(); try {
LoadChilds();
} catch (AbortedBecauseDebugeeStateExpiredException) {
}
} }
void LoadChilds() void LoadChilds()
{ {
if (!childsLoaded) { if (!childsLoaded) {
childsLoaded = true; childsLoaded = true;
SetContentRecursive(this.Tree, this.Children, this.Content.ChildNodes); SetContentRecursive(localVarPad, this.Children, this.Content.ChildNodes);
this.IsExpandedOnce = true; this.IsExpandedOnce = true;
} }
} }
@ -115,27 +125,5 @@ namespace Debugger.AddIn.TreeModel
base.OnCollapsed(); base.OnCollapsed();
expandedNodes[FullName] = false; expandedNodes[FullName] = false;
} }
static DateTime nextDoEventsTime = Debugger.Util.HighPrecisionTimer.Now;
const double workLoad = 0.75; // Fraction of getting variables vs. repainting
const double maxFPS = 30; // this prevents too much drawing on good machine
const double maxWorkTime = 250; // ms this ensures minimal response on bad machine
static void DoEvents()
{
if (Debugger.Util.HighPrecisionTimer.Now > nextDoEventsTime) {
DateTime start = Debugger.Util.HighPrecisionTimer.Now;
Application.DoEvents();
DateTime end = Debugger.Util.HighPrecisionTimer.Now;
double doEventsDuration = (end - start).TotalMilliseconds;
double minWorkTime = 1000 / maxFPS - doEventsDuration; // ms
double workTime = (doEventsDuration / (1 - workLoad)) * workLoad;
workTime = Math.Max(minWorkTime, Math.Min(maxWorkTime, workTime)); // Clamp
nextDoEventsTime = end.AddMilliseconds(workTime);
double fps = 1000 / (doEventsDuration + workTime);
// LoggingService.InfoFormatted("Rendering: {0} ms => work budget: {1} ms ({2:f1} FPS)", doEventsDuration, workTime, fps);
}
}
} }
} }

43
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Util.cs

@ -0,0 +1,43 @@
// <file>
// <copyright license="BSD-new" see="prj:///COPYING"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows.Forms;
namespace Debugger.AddIn.TreeModel
{
public static partial class Util
{
static DateTime nextDoEventsTime = Debugger.Util.HighPrecisionTimer.Now;
const double workLoad = 0.75; // Fraction of getting variables vs. repainting
const double maxFPS = 30; // this prevents too much drawing on good machine
const double maxWorkTime = 250; // ms this ensures minimal response on bad machine
public static void DoEvents()
{
if (Debugger.Util.HighPrecisionTimer.Now > nextDoEventsTime) {
DateTime start = Debugger.Util.HighPrecisionTimer.Now;
Application.DoEvents();
DateTime end = Debugger.Util.HighPrecisionTimer.Now;
double doEventsDuration = (end - start).TotalMilliseconds;
double minWorkTime = 1000 / maxFPS - doEventsDuration; // ms
double workTime = (doEventsDuration / (1 - workLoad)) * workLoad;
workTime = Math.Max(minWorkTime, Math.Min(maxWorkTime, workTime)); // Clamp
nextDoEventsTime = end.AddMilliseconds(workTime);
double fps = 1000 / (doEventsDuration + workTime);
// LoggingService.InfoFormatted("Rendering: {0} ms => work budget: {1} ms ({2:f1} FPS)", doEventsDuration, workTime, fps);
}
}
}
public class AbortedBecauseDebugeeStateExpiredException: System.Exception
{
public AbortedBecauseDebugeeStateExpiredException(): base()
{
}
}
}

3
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Expressions/Expression.Evaluate.cs

@ -19,7 +19,8 @@ namespace Debugger
{ {
public Value Evaluate(StackFrame context) public Value Evaluate(StackFrame context)
{ {
// context.Process.TraceMessage("Evaluating " + this.Code); if (context == null) throw new ArgumentNullException("context");
EvaluateAstVisitor astVisitor = new EvaluateAstVisitor(context); EvaluateAstVisitor astVisitor = new EvaluateAstVisitor(context);
Value result = (Value)this.AbstractSynatxTree.AcceptVisitor(astVisitor, null); Value result = (Value)this.AbstractSynatxTree.AcceptVisitor(astVisitor, null);
context.Process.TraceMessage("Evaluated " + this.Code); context.Process.TraceMessage("Evaluated " + this.Code);

Loading…
Cancel
Save