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

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

@ -106,6 +106,14 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -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()
{
localVarList = new TreeViewAdv();
@ -167,10 +175,13 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -167,10 +175,13 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public override void RefreshPad()
{
DateTime start = Debugger.Util.HighPrecisionTimer.Now;
if (debuggedProcess != null && debuggedProcess.SelectedStackFrame != null) {
TreeViewNode.SetContentRecursive(localVarList, localVarList.Root.Children, new StackFrameNode(debuggedProcess.SelectedStackFrame).ChildNodes);
} else {
TreeViewNode.SetContentRecursive(localVarList, localVarList.Root.Children, null);
try {
if (debuggedProcess != null && debuggedProcess.SelectedStackFrame != null) {
TreeViewNode.SetContentRecursive(this, localVarList.Root.Children, new StackFrameNode(debuggedProcess.SelectedStackFrame).ChildNodes);
} else {
TreeViewNode.SetContentRecursive(this, localVarList.Root.Children, null);
}
} catch(AbortedBecauseDebugeeStateExpiredException) {
}
DateTime end = Debugger.Util.HighPrecisionTimer.Now;
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; @@ -13,6 +13,7 @@ using System.Windows.Forms;
using Aga.Controls.Tree;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui.Pads;
namespace Debugger.AddIn.TreeModel
{
@ -20,6 +21,7 @@ namespace Debugger.AddIn.TreeModel @@ -20,6 +21,7 @@ namespace Debugger.AddIn.TreeModel
{
static Dictionary<string, bool> expandedNodes = new Dictionary<string, bool>();
LocalVarPad localVarPad;
AbstractNode content;
bool childsLoaded;
@ -38,8 +40,9 @@ namespace Debugger.AddIn.TreeModel @@ -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);
}
@ -56,13 +59,19 @@ namespace Debugger.AddIn.TreeModel @@ -56,13 +59,19 @@ namespace Debugger.AddIn.TreeModel
this.Collapse();
}
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];
DoEvents();
int index = 0;
foreach(AbstractNode content in contentEnum) {
// Add or overwrite existing items
@ -71,9 +80,8 @@ namespace Debugger.AddIn.TreeModel @@ -71,9 +80,8 @@ namespace Debugger.AddIn.TreeModel
((TreeViewNode)childNodes[index]).SetContentRecursive(content);
} else {
// Add
childNodes.Add(new TreeViewNode(tree, content));
childNodes.Add(new TreeViewNode(localVarPad, content));
}
DoEvents();
index++;
}
int count = index;
@ -81,20 +89,22 @@ namespace Debugger.AddIn.TreeModel @@ -81,20 +89,22 @@ namespace Debugger.AddIn.TreeModel
while(childNodes.Count > count) {
childNodes.RemoveAt(count);
}
DoEvents();
}
protected override void OnExpanding()
{
base.OnExpanding();
LoadChilds();
try {
LoadChilds();
} catch (AbortedBecauseDebugeeStateExpiredException) {
}
}
void LoadChilds()
{
if (!childsLoaded) {
childsLoaded = true;
SetContentRecursive(this.Tree, this.Children, this.Content.ChildNodes);
SetContentRecursive(localVarPad, this.Children, this.Content.ChildNodes);
this.IsExpandedOnce = true;
}
}
@ -115,27 +125,5 @@ namespace Debugger.AddIn.TreeModel @@ -115,27 +125,5 @@ namespace Debugger.AddIn.TreeModel
base.OnCollapsed();
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 @@ @@ -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 @@ -19,7 +19,8 @@ namespace Debugger
{
public Value Evaluate(StackFrame context)
{
// context.Process.TraceMessage("Evaluating " + this.Code);
if (context == null) throw new ArgumentNullException("context");
EvaluateAstVisitor astVisitor = new EvaluateAstVisitor(context);
Value result = (Value)this.AbstractSynatxTree.AcceptVisitor(astVisitor, null);
context.Process.TraceMessage("Evaluated " + this.Code);

Loading…
Cancel
Save