Browse Source

Add support for manual reference counting of reference counted class instances.

rtl/inc/objpas{h}.inc, TObject:
  + new method "IsRefCounted" to determine whether the class of an instance was declared as "refcounted"
  + new method "RefCount" to determine the current reference count of a class; if it is not reference counted the result is -1
  + new methods "IncRef" and "DecRef" to manually influence the reference count
  + new private method "RefCountOffset" to retrieve the offset of the reference count field using the VMT

git-svn-id: branches/svenbarth/arc@28811 -
svenbarth 10 years ago
parent
commit
2a4e3a5c3b
2 changed files with 48 additions and 0 deletions
  1. 40 0
      rtl/inc/objpas.inc
  2. 8 0
      rtl/inc/objpash.inc

+ 40 - 0
rtl/inc/objpas.inc

@@ -986,6 +986,46 @@
           result:=ClassName;
         end;
 
+      procedure TObject.IncRef;
+        var
+          offset: LongInt;
+        begin
+          offset := RefCountOffset;
+          if offset > 0 then
+            refcountclass_incr_ref(Pointer(Self), offset);
+        end;
+
+      procedure TObject.DecRef;
+        var
+          offset: LongInt;
+        begin
+          offset := RefCountOffset;
+          if offset > 0 then
+            refcountclass_decr_ref(Pointer(Self), offset);
+        end;
+
+      function TObject.RefCount: LongInt;
+        var
+          offset: LongInt;
+        begin
+          offset := RefCountOffset;
+          if offset > 0 then
+            Result := PLongInt(Pointer(Self) + offset)^
+          else
+            Result := -1;
+        end;
+
+      function TObject.IsRefCounted: Boolean;
+        begin
+          Result := PVmt(Self.ClassType)^.vRefCountOfs > 0;
+        end;
+
+      function TObject.RefCountOffset: LongInt;
+        begin
+          Result := PVmt(Self.ClassType)^.vRefCountOfs;
+        end;
+
+
 {****************************************************************************
                                TINTERFACEDOBJECT
 ****************************************************************************}

+ 8 - 0
rtl/inc/objpash.inc

@@ -241,6 +241,14 @@
           function Equals(Obj: TObject) : boolean;virtual;
           function GetHashCode: PtrInt;virtual;
           function ToString: ansistring;virtual;
+
+          { methods for reference counting }
+          procedure IncRef;inline;
+          procedure DecRef;inline;
+          function RefCount: LongInt;inline;
+          function IsRefCounted: Boolean;inline;
+       private
+          function RefCountOffset: LongInt;inline;
        end;
 
        IUnknown = interface