{*************************************************************************** * * * This unit is distributed under the LGPL version 2 * * * * Additionally this unit can be used under any newer version (3 or up) * * of the LGPL * * * * Users are also granted the same "linking exception" as defined * * for the LCL. * * See the LCL license for details * * * * * *************************************************************************** @author(Martin Friebe) } unit LazDebuggerTemplate; {$mode objfpc}{$H+} {$INTERFACES CORBA} // no ref counting needed interface uses Classes, SysUtils, fgl, LazDebuggerIntf; type { TDbgDataRequestTemplateBase } generic TDbgDataRequestTemplateBase<_BASE: TObject; _SENDER_INTF: IDbgDataRequestIntf> = class(_BASE) private type TDbgDataRequestEventList = specialize TFPGList; strict private FEventLists: array [TDbgDataRequestEventType] of TDbgDataRequestEventList; FUpdateCount: Integer; function GetIsUpdating: boolean; inline; protected procedure AddNotification(AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent); procedure RemoveNotification(AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent); procedure CallNotifications(AnEventType: TDbgDataRequestEventType; AnEventData: TDbgDataRequestEventData); procedure BeginUpdate; procedure EndUpdate; procedure DoBeginUpdating; virtual; procedure DoEndUpdating; virtual; property UpdateCount: Integer read FUpdateCount; property IsUpdating: boolean read GetIsUpdating; procedure DoDestroy; // FPC can not compile "destructor Destroy; override;" end; { TDbgDataRequestTemplate } generic TDbgDataRequestTemplate<_BASE: TObject; _SENDER_INTF: IDbgDataRequestIntf> = class(specialize TDbgDataRequestTemplateBase<_BASE, _SENDER_INTF>, IDbgDataRequestIntf) private type TNotifyEventList = specialize TFPGList; strict private FFreeNotifyList: TNotifyEventList; protected procedure AddFreeNotification(ANotification: TNotifyEvent); procedure RemoveFreeNotification(ANotification: TNotifyEvent); procedure CallFreeNotifications; procedure DoDestroy; // FPC can not compile "destructor Destroy; override;" end; { TInternalDbgMonitorBase } generic TInternalDbgMonitorBase< _BASE: TObject; _MONITOR_INTF: IInternalDbgMonitorIntfType; _SUPPLIER_INTF//: IInternalDbgSupplierIntfType > = class(_BASE) strict private FSupplier: _SUPPLIER_INTF; private procedure SetSupplier(ASupplier: _SUPPLIER_INTF); procedure RemoveSupplier(ASupplier: _SUPPLIER_INTF); protected procedure DoNewSupplier; virtual; procedure DoDestroy; // FPC can not compile "destructor Destroy; override;" public property Supplier: _SUPPLIER_INTF read FSupplier write SetSupplier; end; { TInternalDbgSupplierBase } generic TInternalDbgSupplierBase< _BASE: TObject; _SUPPLIER_INTF: IInternalDbgSupplierIntfType; _MONITOR_INTF //: IInternalDbgMonitorIntfType > = class(_BASE) strict private FMonitor: _MONITOR_INTF; private procedure SetMonitor(AMonitor: _MONITOR_INTF); protected procedure DoNewMonitor; virtual; procedure DoDestroy; // FPC can not compile "destructor Destroy; override;" property Monitor: _MONITOR_INTF read FMonitor; end; type { TWatchesMonitorClassTemplate } generic TWatchesMonitorClassTemplate<_BASE: TObject> = class( specialize TInternalDbgMonitorBase<_BASE, IDbgWatchesMonitorIntf, IDbgWatchesSupplierIntf>, IDbgWatchesMonitorIntf ) protected procedure InvalidateWatchValues; virtual; procedure DoStateChange(const AOldState, ANewState: TDBGState); virtual; // deprecated; end; { TWatchesSupplierClassTemplate } generic TWatchesSupplierClassTemplate<_BASE: TObject> = class( specialize TInternalDbgSupplierBase<_BASE, IDbgWatchesSupplierIntf, IDbgWatchesMonitorIntf>, IDbgWatchesSupplierIntf ) protected public procedure RequestData(AWatchValue: IDbgWatchValueIntf); virtual; procedure TriggerInvalidateWatchValues; virtual; end; { TLocalsMonitorClassTemplate } generic TLocalsMonitorClassTemplate<_BASE: TObject> = class( specialize TInternalDbgMonitorBase<_BASE, IDbgLocalsMonitorIntf, IDbgLocalsSupplierIntf>, IDbgLocalsMonitorIntf ) protected procedure InvalidateLocalValues; virtual; procedure DoStateChange(const AOldState, ANewState: TDBGState); virtual; // deprecated; end; { TLocalsSupplierClassTemplate } generic TLocalsSupplierClassTemplate<_BASE: TObject> = class( specialize TInternalDbgSupplierBase<_BASE, IDbgLocalsSupplierIntf, IDbgLocalsMonitorIntf>, IDbgLocalsSupplierIntf ) protected public procedure RequestData(ALocalsList: IDbgLocalsListIntf); virtual; procedure TriggerInvalidateLocalsValues; virtual; end; implementation { TDbgDataRequestTemplateBase } function TDbgDataRequestTemplateBase.GetIsUpdating: boolean; begin Result := FUpdateCount > 0; end; procedure TDbgDataRequestTemplateBase.AddNotification( AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent); begin if FEventLists[AnEventType] = nil then FEventLists[AnEventType] := TDbgDataRequestEventList.Create; FEventLists[AnEventType].Add(AnEvent); end; procedure TDbgDataRequestTemplateBase.RemoveNotification( AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent); begin if FEventLists[AnEventType] = nil then exit; FEventLists[AnEventType].Remove(AnEvent); end; procedure TDbgDataRequestTemplateBase.CallNotifications( AnEventType: TDbgDataRequestEventType; AnEventData: TDbgDataRequestEventData); var i: integer; begin if FEventLists[AnEventType] = nil then exit; for i := FEventLists[AnEventType].Count - 1 downto 0 do FEventLists[AnEventType][i](Self as _SENDER_INTF, AnEventData) end; procedure TDbgDataRequestTemplateBase.BeginUpdate; begin inc(FUpdateCount); if FUpdateCount = 1 then DoBeginUpdating; end; procedure TDbgDataRequestTemplateBase.EndUpdate; begin dec(FUpdateCount); if FUpdateCount = 0 then DoEndUpdating; end; procedure TDbgDataRequestTemplateBase.DoBeginUpdating; begin // end; procedure TDbgDataRequestTemplateBase.DoEndUpdating; begin // end; procedure TDbgDataRequestTemplateBase.DoDestroy; var i: TDbgDataRequestEventType; begin for i := low(TDbgDataRequestEventType) to high(TDbgDataRequestEventType) do FEventLists[i].Free; end; { TDbgDataRequestTemplate } procedure TDbgDataRequestTemplate.AddFreeNotification( ANotification: TNotifyEvent); begin if FFreeNotifyList = nil then FFreeNotifyList := TNotifyEventList.Create; FFreeNotifyList.Add(ANotification); end; procedure TDbgDataRequestTemplate.RemoveFreeNotification( ANotification: TNotifyEvent); begin if FFreeNotifyList = nil then exit; FFreeNotifyList.Remove(ANotification); end; procedure TDbgDataRequestTemplate.CallFreeNotifications; var i: integer; begin if FFreeNotifyList = nil then exit; for i := FFreeNotifyList.Count - 1 downto 0 do FFreeNotifyList[i](nil) end; procedure TDbgDataRequestTemplate.DoDestroy; begin FFreeNotifyList.Free; inherited DoDestroy; end; { TInternalDbgMonitorBase } 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.RemoveSupplier(ASupplier: _SUPPLIER_INTF); begin if Supplier = ASupplier then Supplier := nil; end; procedure TInternalDbgMonitorBase.DoNewSupplier; 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; procedure TInternalDbgSupplierBase.DoNewMonitor; begin // end; procedure TInternalDbgSupplierBase.DoDestroy; begin if FMonitor <> nil then FMonitor.RemoveSupplier(Self as _SUPPLIER_INTF); end; { TWatchesMonitorClassTemplate } procedure TWatchesMonitorClassTemplate.InvalidateWatchValues; begin // end; procedure TWatchesMonitorClassTemplate.DoStateChange(const AOldState, ANewState: TDBGState); begin // end; { TWatchesSupplierClassTemplate } procedure TWatchesSupplierClassTemplate.RequestData(AWatchValue: IDbgWatchValueIntf); begin AWatchValue.Validity := ddsError; end; procedure TWatchesSupplierClassTemplate.TriggerInvalidateWatchValues; begin if (Self <> nil) and (Monitor <> nil) then Monitor.InvalidateWatchValues; end; { TLocalsMonitorClassTemplate } procedure TLocalsMonitorClassTemplate.InvalidateLocalValues; begin // end; procedure TLocalsMonitorClassTemplate.DoStateChange(const AOldState, ANewState: TDBGState); begin // end; { TLocalsSupplierClassTemplate } procedure TLocalsSupplierClassTemplate.RequestData(ALocalsList: IDbgLocalsListIntf ); begin ALocalsList.Validity := ddsError; end; procedure TLocalsSupplierClassTemplate.TriggerInvalidateLocalsValues; begin if (Self <> nil) and (Monitor <> nil) then Monitor.InvalidateLocalValues; end; end.