Skip to content

Commit 9e1bdec

Browse files
committed
Merge pull request #944 from Neverbirth/watches_saving
Store watch expressions between sessions
2 parents 6677c62 + f8b0c8d commit 9e1bdec

File tree

8 files changed

+337
-58
lines changed

8 files changed

+337
-58
lines changed

External/Plugins/FlashDebugger/Controls/DataTree/ValueNode.cs

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using flash.tools.debugger;
33
using Double = java.lang.Double;
4+
using System.Text;
45

56
namespace FlashDebugger.Controls.DataTree
67
{
@@ -34,20 +35,18 @@ public override string Value
3435
string temp = null;
3536
if (type == VariableType_.MOVIECLIP || type == VariableType_.OBJECT)
3637
{
37-
string typeStr = "";
38+
string typeStr = m_Value.getTypeName().ToString();
39+
// rename vector
40+
typeStr = typeStr.Replace("__AS3__.vec::Vector.<", "Vector.<");
3841
if (HideFullClasspath)
3942
{
4043
// return class type without classpath
41-
string typeName = m_Value.getTypeName().ToString();
42-
if (typeName.StartsWith("__AS3__.vec::Vector.<") || typeName.StartsWith("Vector.<"))
43-
typeStr = "Vector.<" + typeName.AfterLast("::", true);
44-
else
45-
typeStr = typeName.After("::", 0, true).Replace("::", ".");
44+
typeStr = CleanTypeClassPaths(typeStr);
4645
}
4746
else
4847
{
4948
// return class type with classpath
50-
typeStr = m_Value.getTypeName().ToString().Replace("::", ".");
49+
typeStr = typeStr.Replace("::", ".");
5150
}
5251

5352
// show / hide IDs
@@ -59,12 +58,6 @@ public override string Value
5958
typeStr = typeStr.Replace("[]", "Array");
6059
}
6160

62-
// rename vector
63-
else if (typeStr.StartsWith("__AS3__.vec.Vector.<"))
64-
{
65-
typeStr = typeStr.Replace("__AS3__.vec.Vector.<", "Vector.<");
66-
}
67-
6861
return typeStr;
6962
}
7063
else if (type == VariableType_.NUMBER)
@@ -206,24 +199,6 @@ public bool IsPrimitive
206199
}
207200
}
208201

209-
210-
private string Escape(string text)
211-
{
212-
text = text.Replace("\\", "\\\\");
213-
text = text.Replace("\"", "\\\"");
214-
text = text.Replace("\0", "\\0");
215-
text = text.Replace("\a", "\\a");
216-
text = text.Replace("\b", "\\b");
217-
text = text.Replace("\f", "\\f");
218-
text = text.Replace("\n", "\\n");
219-
text = text.Replace("\r", "\\r");
220-
text = text.Replace("\t", "\\t");
221-
text = text.Replace("\v", "\\v");
222-
if (text.Length > 65533)
223-
text = text.Substring(0, 65533 - 5) + "[...]";
224-
return text;
225-
}
226-
227202
public Value PlayerValue
228203
{
229204
get
@@ -274,6 +249,67 @@ public ValueNode(string text, Value value)
274249
m_Value = value;
275250
}
276251

252+
internal static string Escape(string text)
253+
{
254+
text = text.Replace("\\", "\\\\");
255+
text = text.Replace("\"", "\\\"");
256+
text = text.Replace("\0", "\\0");
257+
text = text.Replace("\a", "\\a");
258+
text = text.Replace("\b", "\\b");
259+
text = text.Replace("\f", "\\f");
260+
text = text.Replace("\n", "\\n");
261+
text = text.Replace("\r", "\\r");
262+
text = text.Replace("\t", "\\t");
263+
text = text.Replace("\v", "\\v");
264+
if (text.Length > 65533)
265+
text = text.Substring(0, 65533 - 5) + "[...]";
266+
return text;
267+
}
268+
269+
/// <summary>
270+
/// Removes any class path from a fully qualified name. Eg.: flash.display::Sprite becomes Sprite
271+
/// </summary>
272+
/// <param name="qualifiedName">The fully qualified name to clean</param>
273+
/// <returns>The class name with no class paths</returns>
274+
internal static string CleanTypeClassPaths(string qualifiedName)
275+
{
276+
char[] delims = { ',', ' ', '<', '>' };
277+
var buffer = new StringBuilder();
278+
bool inPackage = false;
279+
280+
/**
281+
In order to strip the class-path we are going to traverse the class type in
282+
reverse so we don't need to keep extra buffers or use complex splitting or regexes.
283+
Packages are always separated by colons or dots, so the first time we found one we
284+
are on the package (watch out with Vector.<> notation), and the whole type is always
285+
together, so any delim means that we finished with the type, and since this comes
286+
from the debugger we know that we are not going to find any other type delimiter,
287+
or incomplete/wrong case. We could check for Char.IsWhiteSpace for other uses.
288+
In resume, with this method we could support without much problem even complex cases like:
289+
Collections.Generic.Dictionary<Collections.Generic.Dictionary<String, Test.CustomClassKey>, Collections.Generic.List<Test.CustomClass>>
290+
*/
291+
for (int i = qualifiedName.Length - 1; i >= 0; i--)
292+
{
293+
char c = qualifiedName[i];
294+
295+
if (inPackage)
296+
{
297+
if (Array.IndexOf(delims, c) < 0)
298+
continue;
299+
300+
inPackage = false;
301+
}
302+
else if ((c == '.' && qualifiedName[i + 1] != '<') || c == ':')
303+
{
304+
inPackage = true;
305+
continue;
306+
}
307+
308+
buffer.Insert(0, c);
309+
}
310+
311+
return buffer.ToString();
312+
}
277313
}
278314

279315
}

External/Plugins/FlashDebugger/Controls/WatchUI.cs

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Windows.Forms;
43
using FlashDebugger.Controls.DataTree;
4+
using FlashDebugger.Debugger;
55
using PluginCore;
66
using PluginCore.Localization;
77
using flash.tools.debugger;
@@ -12,20 +12,26 @@ namespace FlashDebugger.Controls
1212
public class WatchUI : DockPanelControl
1313
{
1414
private DataTreeControl treeControl;
15-
private List<string> watches;
15+
private WatchManager watchManager;
1616

17-
public WatchUI()
17+
public WatchUI(WatchManager watchManager)
1818
{
1919
this.AutoKeyHandling = true;
20-
watches = new List<string>();
21-
treeControl = new DataTreeControl(true);
20+
this.treeControl = new DataTreeControl(true);
2221
this.treeControl.Tree.BorderStyle = BorderStyle.None;
2322
this.treeControl.Resize += new EventHandler(this.TreeControlResize);
2423
this.treeControl.Tree.Font = PluginBase.Settings.DefaultFont;
2524
this.treeControl.Dock = DockStyle.Fill;
2625
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
2726
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
2827
this.Controls.Add(this.treeControl);
28+
29+
this.watchManager = watchManager;
30+
this.watchManager.ExpressionAdded += WatchManager_ExpressionAdded;
31+
this.watchManager.ExpressionRemoved += WatchManager_ExpressionRemoved;
32+
this.watchManager.ExpressionReplaced += WatchManager_ExpressionReplaced;
33+
this.watchManager.ExpressionsCleared += WatchManager_ExpressionsCleared;
34+
this.watchManager.ExpressionsLoaded += WatchManager_ExpressionsLoaded;
2935
}
3036

3137
private void TreeControlResize(Object sender, EventArgs e)
@@ -35,50 +41,63 @@ private void TreeControlResize(Object sender, EventArgs e)
3541
this.treeControl.Tree.Columns[1].Width = w - 8;
3642
}
3743

38-
public bool AddElement(string item)
44+
private void WatchManager_ExpressionAdded(Object sender, WatchExpressionArgs e)
3945
{
40-
if (watches.Contains(item)) return false;
41-
watches.Add(item);
42-
treeControl.Nodes.Insert(watches.Count - 1, GetExpressionNode(item));
46+
treeControl.Nodes.Insert(e.Position, GetExpressionNode(e.Expression));
4347
UpdateElements();
44-
return true;
48+
}
49+
50+
private void WatchManager_ExpressionRemoved(Object sender, WatchExpressionArgs e)
51+
{
52+
UpdateElements();
53+
}
54+
55+
private void WatchManager_ExpressionReplaced(Object sender, WatchExpressionReplaceArgs e)
56+
{
57+
treeControl.Nodes[e.Position] = GetExpressionNode(e.NewExpression);
58+
}
59+
60+
private void WatchManager_ExpressionsCleared(Object sender, EventArgs e)
61+
{
62+
treeControl.Nodes.Clear();
63+
}
64+
65+
private void WatchManager_ExpressionsLoaded(Object sender, EventArgs e)
66+
{
67+
UpdateElements();
68+
}
69+
70+
public bool AddElement(string item)
71+
{
72+
return watchManager.Add(item);
4573
}
4674

4775
public void RemoveElement(string item)
4876
{
49-
if (watches.Remove(item)) UpdateElements();
77+
watchManager.Remove(item);
5078
}
5179

5280
public void RemoveElement(int itemN)
5381
{
54-
if (itemN < watches.Count) watches.RemoveAt(itemN);
55-
treeControl.Nodes.RemoveAt(itemN);
82+
watchManager.RemoveAt(itemN);
5683
}
5784

5885
public bool ReplaceElement(string oldItem, string newItem)
5986
{
60-
if (watches.Contains(newItem)) return false;
61-
int itemN = watches.IndexOf(oldItem);
62-
if (itemN == -1) AddElement(newItem);
63-
else
64-
{
65-
watches[itemN] = newItem;
66-
treeControl.Nodes[itemN] = GetExpressionNode(newItem);
67-
}
68-
return true;
87+
return watchManager.Replace(oldItem, newItem);
6988
}
7089

7190
public void Clear()
7291
{
73-
watches.Clear();
74-
treeControl.Nodes.Clear();
92+
watchManager.ClearAll();
7593
}
7694

7795
public void UpdateElements()
7896
{
7997
treeControl.Tree.BeginUpdate();
8098
treeControl.SaveState();
8199
treeControl.Nodes.Clear();
100+
var watches = watchManager.Watches;
82101
foreach (string item in watches)
83102
{
84103
treeControl.AddNode(GetExpressionNode(item));
@@ -94,6 +113,11 @@ private DataNode GetExpressionNode(string item)
94113
DataNode node;
95114
try
96115
{
116+
if (!PluginMain.debugManager.FlashInterface.isDebuggerStarted || !PluginMain.debugManager.FlashInterface.isDebuggerSuspended )
117+
{
118+
return new ErrorNode(item, new Exception(""));
119+
}
120+
97121
IASTBuilder builder = new ASTBuilder(false);
98122
ValueExp exp = builder.parse(new java.io.StringReader(item));
99123
var ctx = new ExpressionContext(PluginMain.debugManager.FlashInterface.Session, PluginMain.debugManager.FlashInterface.GetFrames()[PluginMain.debugManager.CurrentFrame]);

External/Plugins/FlashDebugger/Debugger/DebuggerManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ private void flashInterface_DisconnectedEvent(object sender)
384384
}
385385
PanelsHelper.localsUI.TreeControl.Nodes.Clear();
386386
PanelsHelper.stackframeUI.ClearItem();
387-
PanelsHelper.watchUI.Clear();
387+
PanelsHelper.watchUI.UpdateElements();
388388
PanelsHelper.threadsUI.ClearItem();
389389
PluginMain.breakPointManager.ResetAll();
390390
PluginBase.MainForm.ProgressBar.Visible = false;

0 commit comments

Comments
 (0)