Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit 41d6410

Browse files
authored
Merge pull request #9355 from mono/jstedfast-debugger-load-children-incrementally
[Debugger] Incrementally load new children rather than remove-all and…
2 parents 37234f1 + 261a2ad commit 41d6410

File tree

4 files changed

+92
-47
lines changed

4 files changed

+92
-47
lines changed

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/LocalsPad.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,36 @@
2525
//
2626
//
2727

28+
using System;
29+
2830
using Mono.Debugging.Client;
2931

3032
namespace MonoDevelop.Debugger
3133
{
3234
public class LocalsPad : ObjectValuePad
3335
{
36+
static readonly bool EnableFakeNodes;
37+
38+
static LocalsPad ()
39+
{
40+
var env = Environment.GetEnvironmentVariable ("VSMAC_DEBUGGER_TESTING");
41+
42+
if (!string.IsNullOrEmpty (env)) {
43+
var options = env.Split (new char [] { ',' });
44+
45+
for (int i = 0; i < options.Length; i++) {
46+
var option = options[i].Trim ();
47+
48+
if (option == "fake-locals") {
49+
EnableFakeNodes = true;
50+
return;
51+
}
52+
}
53+
}
54+
55+
EnableFakeNodes = false;
56+
}
57+
3458
public LocalsPad ()
3559
{
3660
if (UseNewTreeView) {
@@ -41,7 +65,6 @@ public LocalsPad ()
4165
}
4266
}
4367

44-
#if ADD_FAKE_NODES
4568
void AddFakeNodes ()
4669
{
4770
var xx = new System.Collections.Generic.List<ObjectValueNode> ();
@@ -60,7 +83,6 @@ void AddFakeNodes ()
6083

6184
controller.AddValues (xx);
6285
}
63-
#endif
6486

6587
void ReloadValues ()
6688
{
@@ -84,9 +106,10 @@ void ReloadValues ()
84106
} finally {
85107
_treeview.EndUpdates ();
86108
}
87-
#if ADD_FAKE_NODES
88-
AddFakeNodes ();
89-
#endif
109+
110+
111+
if (EnableFakeNodes)
112+
AddFakeNodes ();
90113
} else {
91114
tree.ClearValues ();
92115
tree.AddValues (locals);

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueTreeView.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -348,19 +348,13 @@ public void ExpandNode (ObjectValueNode node)
348348

349349
public override void ExpandItem (NSObject item, bool expandChildren)
350350
{
351-
NSAnimationContext.BeginGrouping ();
352-
NSAnimationContext.CurrentContext.Duration = 0;
353351
base.ExpandItem (item, expandChildren);
354-
NSAnimationContext.EndGrouping ();
355352
OptimizeColumnSizes ();
356353
}
357354

358355
public override void ExpandItem (NSObject item)
359356
{
360-
NSAnimationContext.BeginGrouping ();
361-
NSAnimationContext.CurrentContext.Duration = 0;
362357
base.ExpandItem (item);
363-
NSAnimationContext.EndGrouping ();
364358
OptimizeColumnSizes ();
365359
}
366360

@@ -376,19 +370,13 @@ public void CollapseNode (ObjectValueNode node)
376370

377371
public override void CollapseItem (NSObject item, bool collapseChildren)
378372
{
379-
NSAnimationContext.BeginGrouping ();
380-
NSAnimationContext.CurrentContext.Duration = 0;
381373
base.CollapseItem (item, collapseChildren);
382-
NSAnimationContext.EndGrouping ();
383374
OptimizeColumnSizes ();
384375
}
385376

386377
public override void CollapseItem (NSObject item)
387378
{
388-
NSAnimationContext.BeginGrouping ();
389-
NSAnimationContext.CurrentContext.Duration = 0;
390379
base.CollapseItem (item);
391-
NSAnimationContext.EndGrouping ();
392380
OptimizeColumnSizes ();
393381
}
394382

@@ -551,7 +539,7 @@ void OnChildrenLoaded (ObjectValueNode node, int startIndex, int count)
551539
if (disposed)
552540
return;
553541

554-
dataSource.ReloadChildren (node);
542+
dataSource.LoadChildren (node, startIndex, count);
555543
OptimizeColumnSizes ();
556544
}
557545

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueTreeViewDataSource.cs

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ void Insert (MacObjectValueNode parent, int index, ObjectValueNode node)
8989
var value = new MacObjectValueNode (parent, node);
9090
mapping[node] = value;
9191

92-
parent.Children.Insert (index, value);
92+
if (index < parent.Children.Count)
93+
parent.Children.Insert (index, value);
94+
else
95+
parent.Children.Add (value);
9396

9497
if (treeView.AllowExpanding) {
9598
foreach (var child in node.Children)
@@ -181,44 +184,74 @@ public void Replace (ObjectValueNode node, ObjectValueNode[] replacementNodes)
181184
removed[i].Dispose ();
182185
}
183186

184-
public void ReloadChildren (ObjectValueNode node)
187+
public void LoadChildren (ObjectValueNode node, int startIndex, int count)
185188
{
186189
if (!TryGetValue (node, out var parent))
187190
return;
188191

189192
treeView.BeginUpdates ();
190193

191194
try {
192-
NSIndexSet indexes;
195+
int lastIndex = parent.Children.Count - 1;
196+
bool needShowMore = !node.ChildrenLoaded;
197+
bool haveShowMore = false;
198+
NSIndexSet indexes = null;
193199
NSRange range;
194200

195-
if (parent.Children.Count > 0) {
196-
range = new NSRange (0, parent.Children.Count);
197-
indexes = NSIndexSet.FromNSRange (range);
201+
if (lastIndex >= 0 && parent.Children[lastIndex].Target is ShowMoreValuesObjectValueNode)
202+
haveShowMore = true;
198203

204+
if (startIndex < parent.Children.Count) {
205+
// Note: This can only happen if we have either a "Loading..." node or a "Show More" node.
199206
var removed = new List<MacObjectValueNode> ();
200-
foreach (var child in parent.Children)
201-
Remove (child, removed);
202-
203-
parent.Children.Clear ();
204-
205-
if (parent.Target is RootObjectValueNode)
206-
treeView.RemoveItems (indexes, null, NSTableViewAnimation.None);
207-
else
208-
treeView.RemoveItems (indexes, parent, NSTableViewAnimation.None);
209-
210-
for (int i = 0; i < removed.Count; i++)
211-
removed[i].Dispose ();
207+
int extra = parent.Children.Count - startIndex;
208+
209+
if (lastIndex == 0 && parent.Children[0].Target is LoadingObjectValueNode) {
210+
// Remove the "Loading..." node
211+
indexes = NSIndexSet.FromIndex (0);
212+
Remove (parent.Children[0], removed);
213+
parent.Children.Clear ();
214+
} else if (haveShowMore && extra == 1) {
215+
// Only remove the "Show More" node if we don't need it anymore...
216+
if (!needShowMore) {
217+
indexes = NSIndexSet.FromIndex (lastIndex);
218+
Remove (parent.Children[lastIndex], removed);
219+
parent.Children.RemoveAt (lastIndex);
220+
}
221+
} else {
222+
// Unexpected, but let's try to deal with this...
223+
range = new NSRange (startIndex, extra);
224+
indexes = NSIndexSet.FromNSRange (range);
225+
226+
for (int i = parent.Children.Count - 1; i >= startIndex; i--) {
227+
Remove (parent.Children[i], removed);
228+
parent.Children.RemoveAt (i);
229+
}
230+
231+
haveShowMore = false;
232+
}
233+
234+
if (indexes != null) {
235+
if (parent.Target is RootObjectValueNode)
236+
treeView.RemoveItems (indexes, null, NSTableViewAnimation.None);
237+
else
238+
treeView.RemoveItems (indexes, parent, NSTableViewAnimation.None);
239+
240+
for (int i = 0; i < removed.Count; i++)
241+
removed[i].Dispose ();
242+
}
212243
}
213244

214-
for (int i = 0; i < node.Children.Count; i++)
215-
Add (parent, node.Children[i]);
245+
for (int i = startIndex; i < startIndex + count; i++)
246+
Insert (parent, i, node.Children[i]);
216247

217-
// if we did not load all the children, add a Show More node
218-
if (!node.ChildrenLoaded)
248+
// Add a "Show More" node only if we need one and don't already have one.
249+
if (needShowMore && !haveShowMore) {
219250
Add (parent, new ShowMoreValuesObjectValueNode (node));
251+
count++;
252+
}
220253

221-
range = new NSRange (0, parent.Children.Count);
254+
range = new NSRange (startIndex, count);
222255
indexes = NSIndexSet.FromNSRange (range);
223256

224257
if (parent.Target is RootObjectValueNode)

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/ObjectValueTreeViewController.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -670,21 +670,22 @@ async Task ExpandNodeAsync (ObjectValueNode node)
670670

671671
node.IsExpanded = true;
672672

673-
int loadedCount = 0;
673+
int index = node.Children.Count;
674+
int count = 0;
675+
674676
if (node.IsEnumerable) {
675677
// if we already have some loaded, don't load more - that is a specific user gesture
676-
if (node.Children.Count == 0) {
678+
if (index == 0) {
677679
// page the children in, instead of loading them all at once
678-
loadedCount = await FetchChildrenAsync (node, MaxEnumerableChildrenToFetch, cancellationTokenSource.Token);
680+
count = await FetchChildrenAsync (node, MaxEnumerableChildrenToFetch, cancellationTokenSource.Token);
679681
}
680682
} else {
681-
loadedCount = await FetchChildrenAsync (node, 0, cancellationTokenSource.Token);
683+
count = await FetchChildrenAsync (node, -1, cancellationTokenSource.Token);
682684
}
683685

684686
await Runtime.RunInMainThread (() => {
685687
// tell the view about the children, even if there are, in fact, none
686-
view.LoadNodeChildren (node, 0, node.Children.Count);
687-
688+
view.LoadNodeChildren (node, index, count);
688689
view.OnNodeExpanded (node);
689690
});
690691
}

0 commit comments

Comments
 (0)