Search code examples
delphigenericsdelphi-2009

generic locked pool, adding generic to non generic tlist


I tried my hand at a generic class, and on a second attempt I've tried to make a generic locked pool. I almost got it to work I stumble on the spot where I want to put a generic typed class into a locked tlist obtained from tthreadlist.

The main question is:

  • Does anybody know a solution to this problem? (see "problem spot" in the source)

Hints, minor questions:

  • Do I need an additional constraint that signals reference? (I tried adding ,reference to the already existing class and constructor)
  • Does sb know a good overview page of all "special" generic constraints (class,constructor) . Couldn't find much in the manual.
  • the company is at D2009, but I've a single license DXE for migration preparation purposes.

The objects used by this pool are tobject, and worse, some of them have some crucial methods that must be inlined. (it is an image processing app, which is also why I'm not that concerned with relative simply locks. Granularity is coarse). I mention this, since it might make interface based solutions difficult.

type
     TLockedPool<T:class,constructor>   =   class
                                  private
                                    lst : tthreadlist;
                                  public
                                    type sometype =t;  // part of workarounds.
                                    destructor  destroy;
                                    constructor create;
                                    function    getitem:T;
                                    procedure   putitem(var b:T);
                                   end;

 constructor TLockedPool<T>.create;
 begin
  lst:=TThreadlist.Create;
 end;

destructor TLockedPool<T>.destroy;
var i : integer;
    v: tlist;
begin
  v:=lst.locklist;
  for i:=0 to v.count-1 do
    Tobject(v[i]).Free;
  lst.unlocklist;
  v.clear;
  freeandnil(lst);
 inherited;
end;

function TLockedPool<T>.getitem: T;
var cnt:integer;
   v : tlist;
begin
  v:=lst.LockList;
  cnt:=v.Count;
  if cnt>0 then
    begin
      result:=tobject(v[cnt-1]);
      v.delete(cnt-1);
    end
  else
    begin
     result:=T.create;
    end;
  lst.UnlockList;
end;

procedure TLockedPool<T>.putitem(var b: T);
var  v : Tlist;
 x : sometype;
begin
if assigned(b) then // some older parts of the framework are dirty and try to put in NILs.
    begin
      v:=lst.LockList;
      x:=b;
      v.Add(pointer(sometype(x)));  // <--- the problemspot
      lst.unlocklist;
    end;
 b:=nil;
end;

Solution

  • Use v.Add(TObject(x)) or, if you must (it may not work in 2009, awkward for me to check), v.Add(PPointer(@x)^).