Alexey_Gawrilow
Advanced Member | Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору { TObjectGuard } type // PPointer = ^pointer; IObjectGuard = interface(IInterface) ['{7A8C03C6-924B-4652-8703-909ABE4BF8EA}'] { Removes Obj from the guard, so it won't be automatically finalized. Useful when e.g. returning created objects from a function. If an exception is raised, Result can be automatically freed. Example:<br> <code> g := NewObjectGuard(TNewObject.Create, Result); DoStuff; // This may raise an exception. Result will be freed by guard. g.Remit; // OK to return Result from function. Result will not be freed by guard. </code> } procedure Remit; function Obj: TObject; end; TObjectGuard = class(TInterfacedObject, IObjectGuard) protected FObj: TObject; FRef: PPointer; procedure Remit; function Obj: TObject; public constructor Create(aObj: TObject); constructor CreateRef(aObj: TObject; aRef: PPointer = nil); destructor Destroy; override; end; TObjectGuardClass = class of TObjectGuard; function NewObjectGuard(Obj: TObject): IObjectGuard; overload; function NewObjectGuard(Obj: TObject; const GuardClass: TObjectGuardClass): IObjectGuard; overload; function NewObjectGuard(Obj: TObject; out Ref): IObjectGuard; overload; function NewObjectGuardRef(Obj: TObject; var Ref): IObjectGuard; /// <summary>Object Guard.</summary> function _gO(Obj: TObject): IObjectGuard; overload; /// <summary>Object Guard.</summary> function _gO(Obj: TObject; out Ref): IObjectGuard; overload; {/TObjectGuard } { Optimized object guard implementation. deleted } { TObjectGuard } procedure TObjectGuard.Remit; begin FObj := nil; end; function TObjectGuard.Obj: TObject; begin Result := FObj; end; constructor TObjectGuard.Create(aObj: TObject); begin inherited Create(); FObj := aObj; FRef := nil; end; constructor TObjectGuard.CreateRef(aObj: TObject; aRef: PPointer = nil); begin inherited Create(); FObj := aObj; FRef := aRef; end; destructor TObjectGuard.Destroy; begin FObj.Free(); if Assigned(FRef) then FRef^ := nil; inherited; end; function NewObjectGuard(Obj: TObject): IObjectGuard; begin Assert(Assigned(Obj), '{1C2EC9F8-C7EC-4570-BDAA-0CF565D7B0D9}'); Result := TObjectGuard.Create(Obj); end; function _gO(Obj: TObject): IObjectGuard; begin Assert(Assigned(Obj), '{2617F77F-1333-4285-8F99-F5AA3442CDCA}'); Result := TObjectGuard.Create(Obj); end; function NewObjectGuard(Obj: TObject; const GuardClass: TObjectGuardClass): IObjectGuard; begin Assert(Assigned(Obj), '{2504F1BF-31B5-4A6C-AABA-9E62D1655768}'); Assert(Assigned(GuardClass), '{D6C502A8-73DE-410E-A71E-13BD18992586}'); Result := GuardClass.Create(Obj); end; function NewObjectGuard(Obj: TObject; out Ref): IObjectGuard; begin Assert(Assigned(Obj), '{E14C6C2A-DFDE-48E8-B19C-16C084C8E812}'); Result := TObjectGuard.Create(Obj); TObject(Ref) := Obj; end; function _gO(Obj: TObject; out Ref): IObjectGuard; begin Assert(Assigned(Obj), '{5162D39A-BF7C-4808-B275-625E0EE5E602}'); Result := TObjectGuard.Create(Obj); TObject(Ref) := Obj; end; function NewObjectGuardRef(Obj: TObject; var Ref): IObjectGuard; begin Assert(Assigned(Obj), '{56C8F8EC-33BC-42CD-A029-DC3F22765087}'); Result := TObjectGuard.CreateRef(Obj, PPointer(Ref)); end; {/TObjectGuard } |