mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-06 07:58:07 +02:00
Debugger: Change TWatchesMonitor/Supplier to use new Interface.
This commit is contained in:
parent
6f2adbbcb2
commit
7642aaff78
@ -51,7 +51,7 @@ uses
|
||||
LazClasses, {$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif}, LazFileUtils, LazStringUtils, Maps, LazMethodList,
|
||||
// DebuggerIntf
|
||||
DbgIntfBaseTypes, DbgIntfMiscClasses, DbgIntfPseudoTerminal,
|
||||
DbgIntfCommonStrings, LazDebuggerIntf;
|
||||
DbgIntfCommonStrings, LazDebuggerIntf, LazDebuggerTemplate;
|
||||
|
||||
const
|
||||
DebuggerIntfVersion = 0;
|
||||
@ -92,58 +92,6 @@ type
|
||||
);
|
||||
TDBGCommands = set of TDBGCommand;
|
||||
|
||||
{ Debugger states
|
||||
--------------------------------------------------------------------------
|
||||
dsNone:
|
||||
The debug object is created, but no instance of an external debugger
|
||||
exists.
|
||||
Initial state, leave with Init, enter with Done
|
||||
|
||||
dsIdle:
|
||||
The external debugger is started, but no filename (or no other params
|
||||
required to start) were given.
|
||||
|
||||
dsStop:
|
||||
(Optional) The execution of the target is stopped
|
||||
The external debugger is loaded and ready to (re)start the execution
|
||||
of the target.
|
||||
Breakpoints, watches etc can be defined
|
||||
|
||||
dsPause:
|
||||
The debugger has paused the target. Target variables can be examined
|
||||
|
||||
dsInternalPause:
|
||||
Pause, not visible to user.
|
||||
For examble auto continue breakpoint: Allow collection of Snapshot data
|
||||
|
||||
dsInit:
|
||||
(Optional, Internal) The debugger is about to run
|
||||
|
||||
dsRun:
|
||||
The target is running.
|
||||
|
||||
dsError:
|
||||
Something unforseen has happened. A shutdown of the debugger is in
|
||||
most cases needed.
|
||||
|
||||
-dsDestroying
|
||||
The debugger is about to be destroyed.
|
||||
Should normally happen immediate on calling Release.
|
||||
But the debugger may be in nested calls, and has to exit them first.
|
||||
--------------------------------------------------------------------------
|
||||
}
|
||||
TDBGState = (
|
||||
dsNone,
|
||||
dsIdle,
|
||||
dsStop,
|
||||
dsPause,
|
||||
dsInternalPause,
|
||||
dsInit,
|
||||
dsRun,
|
||||
dsError,
|
||||
dsDestroying
|
||||
);
|
||||
|
||||
TDBGLocationRec = record
|
||||
Address: TDBGPtr;
|
||||
FuncName: String;
|
||||
@ -201,62 +149,74 @@ type
|
||||
private
|
||||
FNotifiedState: TDBGState;
|
||||
FOldState: TDBGState;
|
||||
FUpdateCount: Integer;
|
||||
protected
|
||||
//procedure DoModified; virtual; // user-modified / xml-storable data modified
|
||||
procedure DoStateEnterPause; virtual;
|
||||
procedure DoStateLeavePause; virtual;
|
||||
procedure DoStateLeavePauseClean; virtual;
|
||||
procedure DoStateChangeEx(const AOldState, ANewState: TDBGState); virtual;
|
||||
property NotifiedState: TDBGState read FNotifiedState; // The last state seen by DoStateChange
|
||||
property OldState: TDBGState read FOldState; // The state before last DoStateChange
|
||||
|
||||
procedure DoBeginUpdate; virtual;
|
||||
procedure DoEndUpdate; virtual;
|
||||
public
|
||||
//destructor Destroy; override;
|
||||
procedure BeginUpdate;
|
||||
procedure EndUpdate;
|
||||
function IsUpdating: Boolean;
|
||||
end;
|
||||
|
||||
{ TDebuggerDataMonitor }
|
||||
|
||||
TDebuggerDataMonitor = class(TDebuggerDataHandler)
|
||||
private
|
||||
FUpdateCount: Integer;
|
||||
FSupplier: TDebuggerDataSupplier;
|
||||
procedure SetSupplier(const AValue: TDebuggerDataSupplier);
|
||||
protected
|
||||
procedure DoModified; virtual; // user-modified / xml-storable data modified
|
||||
procedure DoNewSupplier; virtual;
|
||||
procedure DoBeginUpdate; virtual;
|
||||
procedure DoEndUpdate; virtual;
|
||||
|
||||
property Supplier: TDebuggerDataSupplier read FSupplier write SetSupplier;
|
||||
public
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure BeginUpdate;
|
||||
procedure EndUpdate;
|
||||
function IsUpdating: Boolean;
|
||||
end;
|
||||
|
||||
|
||||
{ TDebuggerDataSupplierBase }
|
||||
|
||||
TDebuggerDataSupplierBase = class(TDebuggerDataHandler)
|
||||
private
|
||||
FDebugger: TDebuggerIntf;
|
||||
protected
|
||||
procedure DoStateLeavePauseClean; override;
|
||||
|
||||
property Debugger: TDebuggerIntf read FDebugger write FDebugger;
|
||||
public
|
||||
constructor Create(const ADebugger: TDebuggerIntf);
|
||||
end;
|
||||
|
||||
{ TDebuggerDataSupplier }
|
||||
|
||||
TDebuggerDataSupplier = class(TDebuggerDataHandler)
|
||||
TDebuggerDataSupplier = class(TDebuggerDataSupplierBase)
|
||||
private
|
||||
FDebugger: TDebuggerIntf;
|
||||
FUpdateCount: Integer;
|
||||
FMonitor: TDebuggerDataMonitor;
|
||||
procedure SetMonitor(const AValue: TDebuggerDataMonitor);
|
||||
property Monitor: TDebuggerDataMonitor read FMonitor write SetMonitor;
|
||||
protected
|
||||
procedure DoNewMonitor; virtual;
|
||||
property Debugger: TDebuggerIntf read FDebugger write FDebugger;
|
||||
protected
|
||||
|
||||
procedure DoStateLeavePauseClean; override;
|
||||
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||
|
||||
property NotifiedState: TDBGState read FNotifiedState; // The last state seen by DoStateChange
|
||||
property OldState: TDBGState read FOldState; // The state before last DoStateChange
|
||||
procedure DoBeginUpdate; override;
|
||||
procedure DoEndUpdate; override;
|
||||
procedure DoBeginUpdate; virtual;
|
||||
procedure DoEndUpdate; virtual;
|
||||
public
|
||||
constructor Create(const ADebugger: TDebuggerIntf);
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure BeginUpdate;
|
||||
procedure EndUpdate;
|
||||
function IsUpdating: Boolean;
|
||||
end;
|
||||
|
||||
{$region Breakpoints **********************************************************}
|
||||
@ -618,34 +578,16 @@ type
|
||||
******************************************************************************
|
||||
******************************************************************************}
|
||||
|
||||
TWatchesMonitor = class;
|
||||
|
||||
{ TWatchesSupplier }
|
||||
|
||||
TWatchesSupplier = class(TDebuggerDataSupplier)
|
||||
private
|
||||
function GetMonitor: TWatchesMonitor;
|
||||
procedure SetMonitor(AValue: TWatchesMonitor);
|
||||
property Monitor: TWatchesMonitor read GetMonitor write SetMonitor;
|
||||
TWatchesSupplier = class(specialize TWatchesSupplierClassTemplate<TDebuggerDataSupplierBase>, TWatchesSupplierIntf)
|
||||
protected
|
||||
procedure DoStateChange(const AOldState: TDBGState); override; // workaround for state changes during TWatchValue.GetValue
|
||||
procedure DoStateChange(const AOldState: TDBGState); override;
|
||||
procedure InternalRequestData(AWatchValue: TWatchValueIntf); virtual;
|
||||
public
|
||||
constructor Create(const ADebugger: TDebuggerIntf);
|
||||
procedure TriggerInvalidateWatchValues;
|
||||
procedure RequestData(AWatchValue: TWatchValueIntf);
|
||||
end;
|
||||
|
||||
{ TWatchesMonitor }
|
||||
|
||||
TWatchesMonitor = class(TDebuggerDataMonitor)
|
||||
private
|
||||
function GetSupplier: TWatchesSupplier;
|
||||
procedure SetSupplier(AValue: TWatchesSupplier);
|
||||
protected
|
||||
procedure InvalidateWatchValues; virtual;
|
||||
public
|
||||
property Supplier: TWatchesSupplier read GetSupplier write SetSupplier;
|
||||
destructor Destroy; override;
|
||||
procedure RequestData(AWatchValue: TWatchValueIntf); reintroduce;
|
||||
end;
|
||||
|
||||
{%endregion ^^^^^ Watches ^^^^^ }
|
||||
@ -1722,6 +1664,7 @@ type
|
||||
function GetRunErrorText(ARunError: Integer): string;
|
||||
//function GetUnitInfoProvider: TDebuggerUnitInfoProvider;
|
||||
function GetState: TDBGState;
|
||||
function GetWatches: TWatchesSupplierIntf;
|
||||
function ReqCmd(const ACommand: TDBGCommand;
|
||||
const AParams: array of const): Boolean; overload;
|
||||
function ReqCmd(const ACommand: TDBGCommand;
|
||||
@ -1858,6 +1801,7 @@ type
|
||||
class function SupportedCommandsFor(AState: TDBGState): TDBGCommands; virtual;
|
||||
property TargetWidth: Byte read GetTargetWidth; // Currently only 32 or 64
|
||||
//property Waiting: Boolean read GetWaiting; // Set when the debugger is wating for a command to complete
|
||||
property WatchSupplier: TWatchesSupplierIntf read GetWatches; // list of all watches etc
|
||||
property Watches: TWatchesSupplier read FWatches; // list of all watches etc
|
||||
property Threads: TThreadsSupplier read FThreads;
|
||||
property WorkingDir: String read FWorkingDir write FWorkingDir; // The working dir of the exe being debugged
|
||||
@ -2616,36 +2560,6 @@ begin
|
||||
DebugLnExit(DBG_DATA_MONITORS, [ClassName, ': <<EXIT: ', ClassName, '.DoStateChange']);
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataHandler.DoBeginUpdate;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataHandler.DoEndUpdate;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataHandler.BeginUpdate;
|
||||
begin
|
||||
inc(FUpdateCount);
|
||||
if FUpdateCount = 1 then
|
||||
DoBeginUpdate;
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataHandler.EndUpdate;
|
||||
begin
|
||||
assert(FUpdateCount > 0, 'TDebuggerDataMonitor.EndUpdate: FUpdateCount > 0');
|
||||
dec(FUpdateCount);
|
||||
if FUpdateCount = 0 then
|
||||
DoEndUpdate;
|
||||
end;
|
||||
|
||||
function TDebuggerDataHandler.IsUpdating: Boolean;
|
||||
begin
|
||||
Result := FUpdateCount > 0;
|
||||
end;
|
||||
|
||||
{ TRegisterSupplier }
|
||||
|
||||
function TRegisterSupplier.GetCurrentRegistersList: TRegistersList;
|
||||
@ -3126,6 +3040,49 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataMonitor.DoBeginUpdate;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataMonitor.DoEndUpdate;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataMonitor.BeginUpdate;
|
||||
begin
|
||||
inc(FUpdateCount);
|
||||
if FUpdateCount = 1 then
|
||||
DoBeginUpdate;
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataMonitor.EndUpdate;
|
||||
begin
|
||||
assert(FUpdateCount > 0, 'TDebuggerDataMonitor.EndUpdate: FUpdateCount > 0');
|
||||
dec(FUpdateCount);
|
||||
if FUpdateCount = 0 then
|
||||
DoEndUpdate;
|
||||
end;
|
||||
|
||||
function TDebuggerDataMonitor.IsUpdating: Boolean;
|
||||
begin
|
||||
Result := FUpdateCount > 0;
|
||||
end;
|
||||
|
||||
{ TDebuggerDataSupplierBase }
|
||||
|
||||
procedure TDebuggerDataSupplierBase.DoStateLeavePauseClean;
|
||||
begin
|
||||
DoStateLeavePause;
|
||||
end;
|
||||
|
||||
constructor TDebuggerDataSupplierBase.Create(const ADebugger: TDebuggerIntf);
|
||||
begin
|
||||
FDebugger := ADebugger;
|
||||
inherited Create;
|
||||
end;
|
||||
|
||||
{ TDebuggerDataSupplier }
|
||||
|
||||
procedure TDebuggerDataSupplier.SetMonitor(const AValue: TDebuggerDataMonitor);
|
||||
@ -3141,11 +3098,6 @@ begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataSupplier.DoStateLeavePauseClean;
|
||||
begin
|
||||
DoStateLeavePause;
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataSupplier.DoStateChange(const AOldState: TDBGState);
|
||||
begin
|
||||
if (Debugger = nil) then Exit;
|
||||
@ -3154,18 +3106,32 @@ begin
|
||||
Monitor.DoStateChangeEx(AOldState, FDebugger.State);
|
||||
end;
|
||||
|
||||
constructor TDebuggerDataSupplier.Create(const ADebugger: TDebuggerIntf);
|
||||
begin
|
||||
FDebugger := ADebugger;
|
||||
inherited Create;
|
||||
end;
|
||||
|
||||
destructor TDebuggerDataSupplier.Destroy;
|
||||
begin
|
||||
if FMonitor <> nil then FMonitor.Supplier := nil;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataSupplier.BeginUpdate;
|
||||
begin
|
||||
inc(FUpdateCount);
|
||||
if FUpdateCount = 1 then
|
||||
DoBeginUpdate;
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataSupplier.EndUpdate;
|
||||
begin
|
||||
assert(FUpdateCount > 0, 'TDebuggerDataSupplier.EndUpdate: FUpdateCount > 0');
|
||||
dec(FUpdateCount);
|
||||
if FUpdateCount = 0 then
|
||||
DoEndUpdate;
|
||||
end;
|
||||
|
||||
function TDebuggerDataSupplier.IsUpdating: Boolean;
|
||||
begin
|
||||
Result := FUpdateCount > 0;
|
||||
end;
|
||||
|
||||
procedure TDebuggerDataSupplier.DoBeginUpdate;
|
||||
begin
|
||||
FMonitor.BeginUpdate;
|
||||
@ -3956,22 +3922,17 @@ begin
|
||||
else AWatchValue.SetValidity(ddsInvalid);
|
||||
end;
|
||||
|
||||
function TWatchesSupplier.GetMonitor: TWatchesMonitor;
|
||||
begin
|
||||
Result := TWatchesMonitor(inherited Monitor);
|
||||
end;
|
||||
|
||||
procedure TWatchesSupplier.SetMonitor(AValue: TWatchesMonitor);
|
||||
begin
|
||||
inherited Monitor := AValue;
|
||||
end;
|
||||
|
||||
procedure TWatchesSupplier.DoStateChange(const AOldState: TDBGState);
|
||||
begin
|
||||
// workaround for state changes during TWatchValue.GetValue
|
||||
inc(DbgStateChangeCounter);
|
||||
if DbgStateChangeCounter = high(DbgStateChangeCounter) then DbgStateChangeCounter := 0;
|
||||
inherited DoStateChange(AOldState);
|
||||
|
||||
if (Debugger = nil) then Exit;
|
||||
|
||||
DoStateChangeEx(AOldState, Debugger.State);
|
||||
if Monitor <> nil then
|
||||
Monitor.DoStateChange(AOldState, Debugger.State);
|
||||
end;
|
||||
|
||||
procedure TWatchesSupplier.InternalRequestData(AWatchValue: TWatchValueIntf);
|
||||
@ -3979,33 +3940,16 @@ begin
|
||||
AWatchValue.SetValidity(ddsInvalid);
|
||||
end;
|
||||
|
||||
procedure TWatchesSupplier.TriggerInvalidateWatchValues;
|
||||
begin
|
||||
if Monitor <> nil then
|
||||
Monitor.InvalidateWatchValues;
|
||||
end;
|
||||
|
||||
constructor TWatchesSupplier.Create(const ADebugger: TDebuggerIntf);
|
||||
begin
|
||||
inherited Create(ADebugger);
|
||||
FNotifiedState := dsNone;
|
||||
end;
|
||||
|
||||
{ TWatchesMonitor }
|
||||
|
||||
function TWatchesMonitor.GetSupplier: TWatchesSupplier;
|
||||
destructor TWatchesSupplier.Destroy;
|
||||
begin
|
||||
Result := TWatchesSupplier(inherited Supplier);
|
||||
end;
|
||||
|
||||
procedure TWatchesMonitor.SetSupplier(AValue: TWatchesSupplier);
|
||||
begin
|
||||
inherited Supplier := AValue;
|
||||
end;
|
||||
|
||||
procedure TWatchesMonitor.InvalidateWatchValues;
|
||||
begin
|
||||
//
|
||||
DoDestroy;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TLocalsSupplier }
|
||||
@ -5792,6 +5736,11 @@ begin
|
||||
Result := FState;
|
||||
end;
|
||||
|
||||
function TDebuggerIntf.GetWatches: TWatchesSupplierIntf;
|
||||
begin
|
||||
Result := FWatches;
|
||||
end;
|
||||
|
||||
function TDebuggerIntf.ReqCmd(const ACommand: TDBGCommand;
|
||||
const AParams: array of const): Boolean;
|
||||
var
|
||||
|
@ -47,7 +47,7 @@ uses
|
||||
// DebuggerIntf
|
||||
DbgIntfDebuggerBase,
|
||||
// LazDebuggerGdbmi
|
||||
DebugUtils;
|
||||
DebugUtils, LazDebuggerIntf;
|
||||
|
||||
type
|
||||
|
||||
|
@ -35,7 +35,7 @@ uses
|
||||
// DebuggerIntf
|
||||
DbgIntfDebuggerBase,
|
||||
// LazDebuggerGdbmi
|
||||
DebugUtils;
|
||||
DebugUtils, LazDebuggerIntf;
|
||||
|
||||
type
|
||||
|
||||
|
@ -35,7 +35,7 @@ uses
|
||||
// DebuggerIntf
|
||||
DbgIntfDebuggerBase,
|
||||
// CmdLineDebuggerBase
|
||||
DebuggerPropertiesBase,
|
||||
DebuggerPropertiesBase, LazDebuggerIntf,
|
||||
// LazDebuggerGdbmi
|
||||
GDBMIDebugger, GDBMIMiscClasses, GdbmiStringConstants;
|
||||
|
||||
|
@ -47,7 +47,7 @@ uses
|
||||
// DebuggerIntf
|
||||
DbgIntfDebuggerBase,
|
||||
// LazDebuggerGdbmi
|
||||
GDBMIDebugger, GdbmiStringConstants;
|
||||
GDBMIDebugger, GdbmiStringConstants, LazDebuggerIntf;
|
||||
|
||||
type
|
||||
|
||||
|
@ -25,17 +25,76 @@ uses
|
||||
|
||||
type
|
||||
|
||||
{ Debugger states
|
||||
--------------------------------------------------------------------------
|
||||
dsNone:
|
||||
The debug object is created, but no instance of an external debugger
|
||||
exists.
|
||||
Initial state, leave with Init, enter with Done
|
||||
|
||||
dsIdle:
|
||||
The external debugger is started, but no filename (or no other params
|
||||
required to start) were given.
|
||||
|
||||
dsStop:
|
||||
(Optional) The execution of the target is stopped
|
||||
The external debugger is loaded and ready to (re)start the execution
|
||||
of the target.
|
||||
Breakpoints, watches etc can be defined
|
||||
|
||||
dsPause:
|
||||
The debugger has paused the target. Target variables can be examined
|
||||
|
||||
dsInternalPause:
|
||||
Pause, not visible to user.
|
||||
For examble auto continue breakpoint: Allow collection of Snapshot data
|
||||
|
||||
dsInit:
|
||||
(Optional, Internal) The debugger is about to run
|
||||
|
||||
dsRun:
|
||||
The target is running.
|
||||
|
||||
dsError:
|
||||
Something unforseen has happened. A shutdown of the debugger is in
|
||||
most cases needed.
|
||||
|
||||
-dsDestroying
|
||||
The debugger is about to be destroyed.
|
||||
Should normally happen immediate on calling Release.
|
||||
But the debugger may be in nested calls, and has to exit them first.
|
||||
--------------------------------------------------------------------------
|
||||
}
|
||||
TDBGState = (
|
||||
dsNone,
|
||||
dsIdle,
|
||||
dsStop,
|
||||
dsPause,
|
||||
dsInternalPause,
|
||||
dsInit,
|
||||
dsRun,
|
||||
dsError,
|
||||
dsDestroying
|
||||
);
|
||||
|
||||
{$REGION ***** Internal types ***** }
|
||||
|
||||
TInternalDbgMonitorIntfType = interface end;
|
||||
TInternalDbgSupplierIntfType = interface end;
|
||||
|
||||
generic TInternalDbgMonitorIntf<_SUPPLIER_INTF> = interface(TInternalDbgMonitorIntfType)
|
||||
procedure SetSupplier(AValue: _SUPPLIER_INTF);
|
||||
function GetSupplier: _SUPPLIER_INTF;
|
||||
procedure SetSupplier(ASupplier: _SUPPLIER_INTF);
|
||||
|
||||
procedure DoStateChange(const AOldState, ANewState: TDBGState);
|
||||
|
||||
property Supplier: _SUPPLIER_INTF read GetSupplier write SetSupplier;
|
||||
end;
|
||||
|
||||
generic TInternalDbgSupplierIntf<_MONITOR_INTF> = interface(TInternalDbgSupplierIntfType)
|
||||
procedure SetMonitor(AMonitor: _MONITOR_INTF);
|
||||
|
||||
procedure DoStateChange(const AOldState: TDBGState);
|
||||
end;
|
||||
|
||||
{$ENDREGION}
|
||||
@ -118,7 +177,7 @@ type
|
||||
|
||||
TWatchesSupplierIntf = interface;
|
||||
|
||||
TWatchesMonitorIntf = interface(specialize TInternalDbgMonitorIntf<TWatchesSupplierIntf>)
|
||||
TWatchesMonitorIntf = interface(specialize TInternalDbgMonitorIntf<TWatchesSupplierIntf>)
|
||||
procedure InvalidateWatchValues;
|
||||
end;
|
||||
|
||||
|
@ -25,78 +25,156 @@ uses
|
||||
|
||||
type
|
||||
|
||||
{ TInternalDbgMonitorBase }
|
||||
|
||||
generic TInternalDbgMonitorBase<
|
||||
_BASE: TObject;
|
||||
_SUPPLIER_INTF: TInternalDbgSupplierIntfType
|
||||
_MONITOR_INTF: TInternalDbgMonitorIntfType;
|
||||
_SUPPLIER_INTF//: TInternalDbgSupplierIntfType
|
||||
>
|
||||
= class(_BASE)
|
||||
private
|
||||
strict private
|
||||
FSupplier: _SUPPLIER_INTF;
|
||||
private
|
||||
function GetSupplier: _SUPPLIER_INTF;
|
||||
procedure SetSupplier(ASupplier: _SUPPLIER_INTF);
|
||||
|
||||
protected
|
||||
property Supplier: _SUPPLIER_INTF read FSupplier;
|
||||
procedure DoNewSupplier; virtual;
|
||||
procedure DoStateChange(const AOldState, ANewState: TDBGState); virtual;
|
||||
|
||||
procedure DoDestroy; // FPC can not compile "destructor Destroy; override;"
|
||||
public
|
||||
procedure SetSupplier(AValue: _SUPPLIER_INTF); virtual;
|
||||
property Supplier: _SUPPLIER_INTF read GetSupplier write SetSupplier;
|
||||
end;
|
||||
|
||||
{ TInternalDbgSupplierBase }
|
||||
|
||||
generic TInternalDbgSupplierBase<
|
||||
_BASE: TObject;
|
||||
_MONITOR_INTF: TInternalDbgMonitorIntfType
|
||||
_MONITOR_INTF//: TInternalDbgMonitorIntfType
|
||||
>
|
||||
= class(_BASE)
|
||||
private
|
||||
strict private
|
||||
FMonitor: _MONITOR_INTF;
|
||||
protected
|
||||
property Monitor: _MONITOR_INTF read FMonitor;
|
||||
public
|
||||
private
|
||||
procedure SetMonitor(AMonitor: _MONITOR_INTF);
|
||||
protected
|
||||
procedure DoNewMonitor; virtual;
|
||||
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||
|
||||
procedure DoDestroy; // FPC can not compile "destructor Destroy; override;"
|
||||
|
||||
property Monitor: _MONITOR_INTF read FMonitor;
|
||||
end;
|
||||
|
||||
|
||||
type
|
||||
|
||||
{ TWatchesMonitorBase }
|
||||
{ TWatchesMonitorClassTemplate }
|
||||
|
||||
generic TWatchesMonitorBase<_BASE: TObject> = class(specialize TInternalDbgMonitorBase<_BASE, TWatchesSupplierIntf>, TWatchesMonitorIntf)
|
||||
procedure InvalidateWatchValues;
|
||||
generic TWatchesMonitorClassTemplate<_BASE: TObject> = class(
|
||||
specialize TInternalDbgMonitorBase<_BASE, TWatchesMonitorIntf, TWatchesSupplierIntf>,
|
||||
TWatchesMonitorIntf
|
||||
)
|
||||
protected
|
||||
procedure InvalidateWatchValues; virtual;
|
||||
end;
|
||||
|
||||
{ TWatchesSupplierBase }
|
||||
{ TWatchesSupplierClassTemplate }
|
||||
|
||||
generic TWatchesSupplierBase<_BASE: TObject> = class(specialize TInternalDbgSupplierBase<_BASE, TWatchesMonitorIntf>, TWatchesSupplierIntf)
|
||||
procedure RequestData(AWatchValue: TWatchValueIntf);
|
||||
procedure TriggerInvalidateWatchValues;
|
||||
generic TWatchesSupplierClassTemplate<_BASE: TObject> = class(
|
||||
specialize TInternalDbgSupplierBase<_BASE, TWatchesMonitorIntf>,
|
||||
TWatchesSupplierIntf
|
||||
)
|
||||
protected
|
||||
public
|
||||
procedure RequestData(AWatchValue: TWatchValueIntf); virtual;
|
||||
procedure TriggerInvalidateWatchValues; virtual;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TInternalDbgMonitorBase.SetSupplier(AValue: _SUPPLIER_INTF);
|
||||
{ TInternalDbgMonitorBase }
|
||||
|
||||
function TInternalDbgMonitorBase.GetSupplier: _SUPPLIER_INTF;
|
||||
begin
|
||||
FSupplier := AValue;
|
||||
Result := FSupplier;
|
||||
end;
|
||||
|
||||
procedure TInternalDbgMonitorBase.SetSupplier(ASupplier: _SUPPLIER_INTF);
|
||||
begin
|
||||
if FSupplier = ASupplier then exit;
|
||||
assert((FSupplier=nil) or (ASupplier=nil), 'TInternalDbgMonitorBase.SetSupplier: (FSupplier=nil) or (ASupplier=nil)');
|
||||
|
||||
if FSupplier <> nil then FSupplier.SetMonitor(nil);
|
||||
FSupplier := ASupplier;
|
||||
if FSupplier <> nil then FSupplier.SetMonitor(Self as _MONITOR_INTF);
|
||||
|
||||
DoNewSupplier;
|
||||
end;
|
||||
|
||||
procedure TInternalDbgMonitorBase.DoNewSupplier;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TInternalDbgMonitorBase.DoStateChange(const AOldState,
|
||||
ANewState: TDBGState);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TInternalDbgMonitorBase.DoDestroy;
|
||||
begin
|
||||
Supplier := nil;
|
||||
end;
|
||||
|
||||
{ TInternalDbgSupplierBase }
|
||||
|
||||
procedure TInternalDbgSupplierBase.SetMonitor(AMonitor: _MONITOR_INTF);
|
||||
begin
|
||||
if FMonitor = AMonitor then exit;
|
||||
assert((FMonitor=nil) or (AMonitor=nil), 'TInternalDbgSupplierBase.SetMonitor: (FMonitor=nil) or (AMonitor=nil)');
|
||||
FMonitor := AMonitor;
|
||||
|
||||
DoNewMonitor;
|
||||
end;
|
||||
|
||||
{ TWatchesMonitorBase }
|
||||
|
||||
procedure TWatchesMonitorBase.InvalidateWatchValues;
|
||||
procedure TInternalDbgSupplierBase.DoNewMonitor;
|
||||
begin
|
||||
|
||||
//
|
||||
end;
|
||||
|
||||
{ TWatchesSupplierBase }
|
||||
|
||||
procedure TWatchesSupplierBase.RequestData(AWatchValue: TWatchValueIntf);
|
||||
procedure TInternalDbgSupplierBase.DoStateChange(const AOldState: TDBGState);
|
||||
begin
|
||||
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TWatchesSupplierBase.TriggerInvalidateWatchValues;
|
||||
procedure TInternalDbgSupplierBase.DoDestroy;
|
||||
begin
|
||||
if FMonitor <> nil then
|
||||
FMonitor.Supplier := nil;
|
||||
end;
|
||||
|
||||
{ TWatchesMonitorClassTemplate }
|
||||
|
||||
procedure TWatchesMonitorClassTemplate.InvalidateWatchValues;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
{ TWatchesSupplierClassTemplate }
|
||||
|
||||
procedure TWatchesSupplierClassTemplate.RequestData(AWatchValue: TWatchValueIntf);
|
||||
begin
|
||||
AWatchValue.Validity := ddsError;
|
||||
end;
|
||||
|
||||
procedure TWatchesSupplierClassTemplate.TriggerInvalidateWatchValues;
|
||||
begin
|
||||
if Monitor <> nil then
|
||||
Monitor.InvalidateWatchValues;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ uses
|
||||
// IdeIntf
|
||||
IDEWindowIntf, IDECommands, IDEImagesIntf,
|
||||
// DebuggerIntf
|
||||
DbgIntfBaseTypes, DbgIntfDebuggerBase,
|
||||
DbgIntfBaseTypes, DbgIntfDebuggerBase, LazDebuggerIntf,
|
||||
// IDE
|
||||
DebuggerDlg, Debugger, BaseDebugManager, EditorOptions, SourceEditor;
|
||||
|
||||
|
@ -3537,7 +3537,7 @@ end;
|
||||
procedure TIdeWatchesMonitor.RequestData(AWatchValue: TCurrentWatchValue);
|
||||
begin
|
||||
if Supplier <> nil
|
||||
then Supplier.RequestData(AWatchValue)
|
||||
then Supplier.RequestData(TWatchValueIntf(AWatchValue))
|
||||
else AWatchValue.Validity := ddsInvalid;
|
||||
end;
|
||||
|
||||
|
@ -44,7 +44,7 @@ uses
|
||||
// LazUtils
|
||||
FileUtil, UTF8Process, LazFileUtils, LazLoggerBase,
|
||||
// DebuggerIntf
|
||||
DbgIntfDebuggerBase,
|
||||
DbgIntfDebuggerBase, LazDebuggerIntf,
|
||||
// IDE
|
||||
ProcessList, Debugger;
|
||||
|
||||
|
@ -3278,7 +3278,7 @@ begin
|
||||
end
|
||||
else begin
|
||||
TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
||||
FWatches.Supplier := FDebugger.Watches;
|
||||
FWatches.Supplier := FDebugger.WatchSupplier;
|
||||
FThreads.Supplier := FDebugger.Threads;
|
||||
FThreads.UnitInfoProvider := FUnitInfoProvider;
|
||||
FLocals.Supplier := FDebugger.Locals;
|
||||
|
@ -6,7 +6,7 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, DbgIntfDebuggerBase, DbgIntfMiscClasses, LazClasses,
|
||||
LazLoggerBase, LazDebuggerIntf;
|
||||
LazLoggerBase, LazDebuggerIntf, LazDebuggerTemplate;
|
||||
|
||||
type
|
||||
|
||||
@ -137,6 +137,17 @@ type
|
||||
property Items[const AnIndex: Integer]: TWatch read GetItemBase write SetItemBase; default;
|
||||
end;
|
||||
|
||||
{ TWatchesMonitor }
|
||||
|
||||
TWatchesMonitor = class(specialize TWatchesMonitorClassTemplate<TDebuggerDataHandler>, TWatchesMonitorIntf)
|
||||
protected
|
||||
procedure DoStateChange(const AOldState, ANewState: TDBGState); reintroduce;
|
||||
|
||||
// from TDebuggerDataMonitor
|
||||
procedure DoModified; virtual; // user-modified / xml-storable data modified
|
||||
public
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
@ -477,6 +488,24 @@ begin
|
||||
Result := FList.Count;
|
||||
end;
|
||||
|
||||
{ TWatchesMonitor }
|
||||
|
||||
procedure TWatchesMonitor.DoStateChange(const AOldState, ANewState: TDBGState);
|
||||
begin
|
||||
DoStateChangeEx(AOldState, ANewState);
|
||||
end;
|
||||
|
||||
procedure TWatchesMonitor.DoModified;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
destructor TWatchesMonitor.Destroy;
|
||||
begin
|
||||
DoDestroy;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
initialization
|
||||
DBG_DATA_MONITORS := DebugLogger.FindOrRegisterLogGroup('DBG_DATA_MONITORS' {$IFDEF DBG_DATA_MONITORS} , True {$ENDIF} );
|
||||
|
||||
|
@ -69,7 +69,7 @@ uses
|
||||
IDEWindowIntf, ProjectIntf, MacroDefIntf, ToolBarIntf, IDEDialogs, IDECommands,
|
||||
EditorSyntaxHighlighterDef,
|
||||
// DebuggerIntf
|
||||
DbgIntfDebuggerBase,
|
||||
DbgIntfDebuggerBase, LazDebuggerIntf,
|
||||
// IDE units
|
||||
IDECmdLine, LazarusIDEStrConsts, EditorOptions,
|
||||
EnvironmentOpts, WordCompletion, FindReplaceDialog, IDEProcs, IDEOptionDefs,
|
||||
|
Loading…
Reference in New Issue
Block a user