Debugger: Add Begin/EndUpdate to WatchValue

This commit is contained in:
Martin 2022-01-29 20:30:09 +01:00
parent d814d37966
commit c1f09236f4
3 changed files with 67 additions and 2 deletions

View File

@ -149,6 +149,33 @@ type
{ TWatchValueIntf }
TWatchValueIntf = interface(TDbgDataRequestIntf)
(* Begin/EndUdate
- shall indicate that the newly set values are now valid. Ready for display.
(Indicated by EndUpdate)
- shall protect the object from destruction.
A debugger backend may access the object during this time, without further checks.
- shall ensure changes outside the backend, will not affect calls by the
backend to any method setting/adding/modifing requested data.
~ I.e. if the backend adds values to an array or structure, further calls
by the backend to add more data must be accepted without failure.
~ However, further data may be discarded internally, if possible without
causing later failures (e.g. if the requested data is no longer needed)
(!) - does NOT affect, if read-only properties/functions can change their value.
E.g., if the requested value is no longer needed, then "Expression" and
other "passed in/provided values" may change (reset to default/empty)
* When used in the IDE (Begin/EndUpdate themself shall only be valid in the main thread),
shall
- allow the backend to read "passed in/provided values" from another thread
- allow the backend to set new values from another thread
(I.e., if the IDE (or any non-backend code) makes changes, they must
consider thread safety)
// Any "frontend" outside the IDE (commandline / dbg-server) doens not
need to consider thread safety, as long as it knows that this in not
required by any of the backends it uses.
*)
procedure BeginUpdate;
procedure EndUpdate;
function GetDisplayFormat: TWatchDisplayFormat;
function GetEvaluateFlags: TWatcheEvaluateFlags;
function GetExpression: String;

View File

@ -639,11 +639,18 @@ type
{ TCurrentWatchValue }
TCurrentWatchValue = class(TIdeWatchValue)
TCurrentWatchValue = class(TIdeWatchValue, TWatchValueIntf)
private
FCurrentExpression: String;
FUpdateCount: Integer;
procedure BeginUpdate;
procedure EndUpdate;
private
FSnapShot: TIdeWatchValue;
procedure SetSnapShot(const AValue: TIdeWatchValue);
protected
function GetExpression: String; override;
procedure RequestData; override;
procedure DoDataValidityChanged({%H-}AnOldValidity: TDebuggerDataState); override;
public
@ -3098,6 +3105,26 @@ end;
{ TCurrentWatchValue }
procedure TCurrentWatchValue.BeginUpdate;
begin
AddReference;
if FUpdateCount = 0 then
FCurrentExpression := Expression;
inc(FUpdateCount);
end;
procedure TCurrentWatchValue.EndUpdate;
begin
dec(FUpdateCount);
if (FUpdateCount = 0) then begin
if Validity <> ddsValid then
SetValidity(ddsValid)
else
DoDataValidityChanged(ddsRequested);
end;
ReleaseReference; // Last statemnet, may call Destroy
end;
procedure TCurrentWatchValue.SetSnapShot(const AValue: TIdeWatchValue);
begin
assert((FSnapShot=nil) or (AValue=nil), 'TCurrentWatchValue already have snapshot');
@ -3107,6 +3134,14 @@ begin
then FSnapShot.Assign(self);
end;
function TCurrentWatchValue.GetExpression: String;
begin
if FUpdateCount > 0 then
Result := FCurrentExpression
else
Result := inherited GetExpression;
end;
procedure TCurrentWatchValue.RequestData;
begin
TCurrentWatch(Watch).RequestData(self);
@ -3114,6 +3149,8 @@ end;
procedure TCurrentWatchValue.DoDataValidityChanged(AnOldValidity: TDebuggerDataState);
begin
if FUpdateCount > 0 then
exit;
if Validity = ddsRequested then exit;
if Watch <> nil then
TCurrentWatches(TCurrentWatch(Watch).Collection).Update(Watch);

View File

@ -14,13 +14,14 @@ type
{ TWatchValue }
TWatchValue = class(TRefCountedObject, TWatchValueIntf)
TWatchValue = class(TRefCountedObject)
private
FWatch: TWatch;
FTypeInfo: TDBGType;
FValue: String;
FValidity: TDebuggerDataState;
protected
function GetDisplayFormat: TWatchDisplayFormat;
function GetEvaluateFlags: TWatcheEvaluateFlags;
function GetRepeatCount: Integer;