unit vDependence; {$mode ObjFPC}{$H+} interface uses g_node_splay, g23tree; type TvReleaseCb=function(Sender:TObject):Boolean of object; { TvReleaseCompare=object function c(a,b:TvReleaseCb):Integer; static; end; TvRelease=specialize T23treeSet; } PvReleaseNode=^TvReleaseNode; TvReleaseNode=object // OnRelease:TvReleaseCb; //Must be the first element in memory // pLeft :PvReleaseNode; pRight:PvReleaseNode; // function c(a,b:PvReleaseNode):Integer; static; end; TvRelease=specialize TNodeSplay; TvRefsObject=class FRefs:Integer; FHold:Integer; function Acquire(Sender:TObject):Boolean; virtual; function Release(Sender:TObject):Boolean; virtual; function Hold (Sender:TObject):Boolean; virtual; function Drop (Sender:TObject):Boolean; virtual; end; TvDependenciesObject=class(TvRefsObject) FDep_lock :Pointer; FDependencies:TvRelease; // function OnAlloc(size:Ptruint):Pointer; virtual; Procedure OnFree (P:Pointer ); virtual; function IsLinearAlloc:Boolean; virtual; function RefTo(obj:TvRefsObject):Boolean; virtual; function AddDependence(cb:TvReleaseCb):Boolean; function DelDependence(cb:TvReleaseCb):Boolean; function HasDependence:Boolean; Procedure ReleaseAllDependencies(Sender:TObject); Procedure FreeAllDependencies; Destructor Destroy; override; end; TObjectCompare=object function c(a,b:TObject):Integer; static; end; TObjectSet=specialize T23treeSet; TObjectSetLock=object(TObjectSet) lock:Pointer; Procedure Lock_rd; Procedure Lock_wr; Procedure Unlock_rd; Procedure Unlock_wr; function Insert (Const K:TObject):Boolean; Function Contains(Const K:TObject):Boolean; Function delete (Const R:TObject):Boolean; Function Release (Const R:TObject):Boolean; end; procedure ReleaseAndNil(var obj); implementation uses kern_rwlock; { function TvReleaseCompare.c(a,b:TvReleaseCb):Integer; begin Result:=Integer(TMethod(a).Code>TMethod(b).Code)-Integer(TMethod(a).Code0) then Exit; Result:=Integer(TMethod(a).Data>TMethod(b).Data)-Integer(TMethod(a).DataTMethod(b^.OnRelease).Code)- Integer(TMethod(a^.OnRelease).Code0) then Exit; // Result:=Integer(TMethod(a^.OnRelease).Data>TMethod(b^.OnRelease).Data)- Integer(TMethod(a^.OnRelease).Datanil) then begin Result:=FDependencies.delete(node); OnFree(node); end; rw_wunlock(FDep_lock); end; function TvDependenciesObject.HasDependence:Boolean; begin Result:=(FDependencies.pRoot<>nil); end; Procedure TvDependenciesObject.ReleaseAllDependencies(Sender:TObject); var node:PvReleaseNode; cb:TvReleaseCb; begin rw_wlock(FDep_lock); node:=FDependencies.Min; while (node<>nil) do begin cb:=node^.OnRelease; FDependencies.delete(node); OnFree(node); if (cb<>nil) then begin rw_wunlock(FDep_lock); cb(Sender); rw_wlock(FDep_lock); end; node:=FDependencies.Min; end; rw_wunlock(FDep_lock); end; Procedure TvDependenciesObject.FreeAllDependencies; var node,next:PvReleaseNode; begin rw_wlock(FDep_lock); node:=FDependencies.Min; while (node<>nil) do begin FDependencies.delete(node); OnFree(node); node:=FDependencies.Min; end; rw_wunlock(FDep_lock); end; Destructor TvDependenciesObject.Destroy; begin FreeAllDependencies; inherited; end; // function TObjectCompare.c(a,b:TObject):Integer; begin Result:=Integer(Pointer(a)>Pointer(b))-Integer(Pointer(a)