====== Bizarreries a étudier ====== ===== class(specialize TFPGMap) ===== THttpHeader = class(specialize TFPGMap) public procedure Parse(const HeaderString: string); constructor Create; end; ===== TLockedEvent = specialize TThreadedData; ===== TLockedEvent = specialize TThreadedData; ... function GetOnClose: TNotifyEvent; procedure SetOnClose(AValue: TNotifyEvent) ... property OnClose: TNotifyEvent read GetOnClose write SetOnClose; ... function TWebsocketCommunicator.GetOnClose: TNotifyEvent; begin try Result := FOnClose.Lock^; finally FOnClose.Unlock; end; end; procedure TWebsocketCommunicator.SetOnClose(AValue: TNotifyEvent); begin try FOnClose.Lock^ := AValue; finally FOnClose.Unlock; end; end; ... constructor TWebsocketCommunicator.Create(AStream: TLockedSocketStream; AMaskMessage: boolean; AssumeMaskedMessages: boolean); begin ... FOnClose.Init(nil); ... end; destructor TWebsocketCommunicator.Destroy; begin ... FOnClose.Done; inherited Destroy; end; procedure TWebsocketCommunicator.Close(ForceClose: boolean); var OnCloseEvent: TNotifyEvent; begin ... OnCloseEvent := OnClose; if Assigned(OnCloseEvent) then OnCloseEvent(Self); ... end; Avec... { TThreadedData } generic TThreadedData = record public type PT = ^T; private FData: T; FLock: TRTLCriticalSection; public procedure Init(const AValue: T); procedure Done; function Lock: PT; procedure Unlock; end;