Debugger: Ide, Watches reduce notifications in Begin/EndUpdate

This commit is contained in:
Martin 2022-01-23 22:36:49 +01:00
parent 867d12b46d
commit fa2ec38d6a
2 changed files with 83 additions and 30 deletions

View File

@ -149,6 +149,7 @@ type
FWatchesInView: TIdeWatches;
FPowerImgIdx, FPowerImgIdxGrey: Integer;
FUpdateAllNeeded, FUpdatingAll: Boolean;
FWatchInUpDateItem: TIdeWatch;
FStateFlags: TWatchesDlgStateFlags;
function GetSelected: TIdeWatch; // The focused Selected Node
function GetThreadId: Integer;
@ -165,6 +166,7 @@ type
function GetSelectedSnapshot: TSnapshot;
property Watches: TIdeWatches read GetWatches;
protected
procedure DoBeginUpdate; override;
procedure DoEndUpdate; override;
procedure DoWatchesChanged; override;
function ColSizeGetter(AColId: Integer; var ASize: Integer): Boolean;
@ -345,6 +347,7 @@ var
VNode: PVirtualNode;
begin
if FUpdatingAll then exit;
if IsUpdating then exit;
if GetSelectedSnapshot <> nil then begin
actToggleCurrentEnable.Enabled := False;
actToggleCurrentEnable.Checked := False;
@ -534,13 +537,14 @@ var
begin
try
DisableAllActions;
BeginUpdate;
for VNode in tvWatches.SelectedNodes do
begin
VNdWatch := TIdeWatch(tvWatches.NodeItem[VNode]);
VNdWatch.Enabled := True;
end;
finally
tvWatchesChange(nil, nil);
EndUpdate;
end;
end;
@ -569,13 +573,14 @@ var
begin
try
DisableAllActions;
BeginUpdate;
for VNode in tvWatches.SelectedNodes do
begin
VNdWatch := TIdeWatch(tvWatches.NodeItem[VNode]);
VNdWatch.Enabled := False;
end;
finally
tvWatchesChange(nil, nil);
EndUpdate;
end;
end;
@ -634,7 +639,8 @@ begin
Include(FStateFlags, wdsfNeedDeleteAll);
if wdsfUpdating in FStateFlags then exit;
Exclude(FStateFlags, wdsfNeedDeleteAll);
tvWatches.BeginUpdate;
DisableAllActions;
BeginUpdate;
try
DisableAllActions;
VNode := tvWatches.GetFirst;
@ -643,8 +649,7 @@ begin
VNode := tvWatches.GetFirst;
end;
finally
tvWatches.EndUpdate;
tvWatchesChange(nil, nil);
EndUpdate;
end;
end;
@ -653,7 +658,7 @@ var
NewWatches: TIdeWatches;
begin
DebugLn(DBG_DATA_MONITORS, ['DebugDataWindow: TWatchesDlg.SnapshotChanged ', DbgSName(Sender), ' Upd:', IsUpdating]);
tvWatches.BeginUpdate;
BeginUpdate;
// prevent lvWatchesSelectItem when deleting the itews. Snapsot may have been deleted
FUpdatingAll := True; // will be reset by UpdateAll
try
@ -664,7 +669,7 @@ begin
UpdateAll;
finally
FUpdatingAll := False; // wan reset by UpdateAll anyway
tvWatches.EndUpdate;
EndUpdate;
end;
end;
@ -682,6 +687,12 @@ begin
else Result := WatchesMonitor.CurrentWatches;
end;
procedure TWatchesDlg.DoBeginUpdate;
begin
inherited DoBeginUpdate;
tvWatches.BeginUpdate;
end;
procedure TWatchesDlg.DoEndUpdate;
begin
inherited DoEndUpdate;
@ -689,6 +700,10 @@ begin
FUpdateAllNeeded := False;
UpdateAll;
end;
tvWatches.EndUpdate;
if not FUpdatingAll then
tvWatchesChange(nil, nil);
end;
procedure TWatchesDlg.DoWatchesChanged;
@ -727,15 +742,16 @@ begin
Include(FStateFlags, wdsfNeedDeleteCurrent);
if (wdsfUpdating in FStateFlags) then exit;
Exclude(FStateFlags, wdsfNeedDeleteCurrent);
DisableAllActions;
BeginUpdate;
try
DisableAllActions;
VNode := tvWatches.GetFirstSelected;
while VNode <> nil do begin
tvWatches.DeleteNodeEx(VNode, True);
VNode := tvWatches.GetFirstSelected;
end;
finally
tvWatchesChange(nil, nil);
EndUpdate;
end;
end;
@ -746,13 +762,14 @@ var
begin
try
DisableAllActions;
BeginUpdate;
for VNode in tvWatches.NoInitNodes do
begin
VNdWatch := TIdeWatch(tvWatches.NodeItem[VNode]);
VNdWatch.Enabled := False;
end;
finally
tvWatchesChange(nil, nil);
EndUpdate;
end;
end;
@ -763,13 +780,14 @@ var
begin
try
DisableAllActions;
BeginUpdate;
for VNode in tvWatches.NoInitNodes do
begin
VNdWatch := TIdeWatch(tvWatches.NodeItem[VNode]);
VNdWatch.Enabled := True;
end;
finally
tvWatchesChange(nil, nil);
EndUpdate;
end;
end;
@ -779,12 +797,13 @@ var
begin
try
DisableAllActions;
BeginUpdate;
Watch := GetSelected;
if Watch = nil then Exit;
popEnabled.Checked := not popEnabled.Checked;
Watch.Enabled := popEnabled.Checked;
finally
tvWatchesChange(nil, nil);
EndUpdate;
end;
end;
@ -906,8 +925,16 @@ begin
if (ThreadsMonitor = nil) or (CallStackMonitor = nil) then exit;
if GetStackframe < 0 then exit; // TODO need dedicated validity property
if wdsfUpdating in FStateFlags then begin
if FWatchInUpDateItem <> AWatch then // The watch got data while we requested it, that is fine
FUpdateAllNeeded := True;
exit;
end;
BeginUpdate;
include(FStateFlags, wdsfUpdating);
DebugBoss.LockCommandProcessing;
FWatchInUpDateItem := AWatch;
try
tvWatches.NodeText[VNode, COL_WATCH_EXPR-1]:= AWatch.Expression;
WatchValue := AWatch.Values[GetThreadId, GetStackframe];
@ -923,13 +950,15 @@ begin
end
else
tvWatches.NodeText[VNode, COL_WATCH_VALUE-1]:= '<not evaluated>';
finally
FWatchInUpDateItem := nil;
exclude(FStateFlags, wdsfUpdating);
if wdsfNeedDeleteCurrent in FStateFlags then
popDeleteClick(nil);
if wdsfNeedDeleteAll in FStateFlags then
popDeleteAllClick(nil);
finally
EndUpdate;
DebugBoss.UnLockCommandProcessing;
tvWatches.Invalidate;
end;
@ -995,15 +1024,19 @@ procedure TWatchesDlg.WatchAdd(const ASender: TIdeWatches; const AWatch: TIdeWat
var
VNode: PVirtualNode;
begin
VNode := tvWatches.FindNodeForItem(AWatch);
if VNode = nil
then begin
VNode := tvWatches.AddChild(nil, AWatch);
tvWatches.SelectNode(VNode);
BeginUpdate;
try
VNode := tvWatches.FindNodeForItem(AWatch);
if VNode = nil
then begin
VNode := tvWatches.AddChild(nil, AWatch);
tvWatches.SelectNode(VNode);
end;
UpdateItem(VNode, AWatch);
finally
EndUpdate;
end;
UpdateItem(VNode, AWatch);
tvWatchesChange(nil, nil);
end;
procedure TWatchesDlg.WatchUpdate(const ASender: TIdeWatches; const AWatch: TIdeWatch);
@ -1014,15 +1047,18 @@ begin
if AWatch.Collection <> FWatchesInView then exit;
try DebugLnEnter(DBG_DATA_MONITORS, ['DebugDataWindow: TWatchesDlg.WatchUpdate Upd:', IsUpdating, ' Watch=',AWatch.Expression]);
VNode := tvWatches.FindNodeForItem(AWatch);
if VNode = nil
then WatchAdd(ASender, AWatch)
else UpdateItem(VNode, AWatch);
BeginUpdate;
try
VNode := tvWatches.FindNodeForItem(AWatch);
if VNode = nil
then WatchAdd(ASender, AWatch)
else UpdateItem(VNode, AWatch);
finally
EndUpdate;
end;
// TODO: if AWatch <> Selected, then prevent UpdateInspectPane
// Selected may update later, and calling UpdateInspectPane will schedule an unsucesful attemptn to fetch data
if not FUpdatingAll
then tvWatchesChange(nil, nil);
finally DebugLnExit(DBG_DATA_MONITORS, ['DebugDataWindow: TWatchesDlg.WatchUpdate']); end;
end;

View File

@ -701,6 +701,7 @@ type
TCurrentWatch = class(TIdeWatch)
private
FSnapShot: TIdeWatch;
FAdded: Boolean;
procedure SetSnapShot(const AValue: TIdeWatch);
protected
function CreateValueList: TWatchValueList; override;
@ -724,6 +725,7 @@ type
FMonitor: TIdeWatchesMonitor;
FSnapShot: TIdeWatches;
FDestroying: Boolean;
FSkipUpdatedNotification: integer;
procedure SetSnapShot(const AValue: TIdeWatches);
procedure WatchesChanged(Sender: TObject);
protected
@ -5535,13 +5537,18 @@ begin
end;
destructor TCurrentWatch.Destroy;
var
w: TCurrentWatches;
begin
if (TCurrentWatches(Collection) <> nil)
then begin
TCurrentWatches(Collection).NotifyRemove(Self);
TCurrentWatches(Collection).DoModified;
end;
w := TCurrentWatches(Collection);
inc(w.FSkipUpdatedNotification);
inherited Destroy;
dec(w.FSkipUpdatedNotification);
end;
procedure TCurrentWatch.LoadFromXMLConfig(const AConfig: TXMLConfig; const APath: string);
@ -5582,10 +5589,8 @@ end;
function TIdeWatches.Add(const AExpression: String): TIdeWatch;
begin
BeginUpdate;
Result := TIdeWatch(inherited Add);
Result := TIdeWatch(inherited Add); // calls update
Result.Expression := AExpression;
EndUpdate;
end;
function TIdeWatches.GetItem(const AnIndex: Integer): TIdeWatch;
@ -5638,7 +5643,9 @@ var
R: TIdeWatch;
begin
// if this is modified, then also update LoadFromXMLConfig
inc(FSkipUpdatedNotification);
Result := TCurrentWatch(inherited Add(AExpression));
dec(FSkipUpdatedNotification);
if FSnapShot <> nil then begin
R := FSnapShot.Add(AExpression);
Result.SnapShot := R;
@ -5729,6 +5736,11 @@ end;
procedure TCurrentWatches.NotifyAdd(const AWatch: TCurrentWatch);
begin
if UpdateCount > 0 then begin
AWatch.FAdded := True;
exit;
end;
AWatch.FAdded := False;
FMonitor.NotifyAdd(Self, AWatch);
end;
@ -5775,12 +5787,17 @@ procedure TCurrentWatches.Update(Item: TCollectionItem);
var
m, c: Integer;
begin
if (UpdateCount > 0) or (FSkipUpdatedNotification > 0) then
exit;
if Item <> nil then begin
FMonitor.NotifyUpdate(Self, TCurrentWatch(Item));
end else begin
m := 0;
c := Count;
while m < c do begin
if Items[m].FAdded then
NotifyAdd(Items[m]);
FMonitor.NotifyUpdate(Self, Items[m]);
if c <> Count then begin
m := Max(0, m - Max(0, Count - c));