Reputation: 2276
I have implemented a bitmap adapter to extent bitmap functionality as follow:
unit UBitmapHelper;
IBmpUtils = interface
procedure SomeNewRoutine;
end;
TBitmapUtilsAdapter = class (TInterfacedObject, IBmpUtils)
public
constructor Create (ABitmap: TBitmap);
//IBmpUtils
procedure SomeNewRoutine;
end;
TBitmapHelper = class helper for TBitmap
function Utils: IBmpUtils; //method factory pattern
end;
function TBitmapHelper.Utils: IBmpUtils;
begin
Result := TBitmapUtilsAdapter.Create(Self);
end;
so I now can use this adapter as follow:
uses UBitmapHelper;
procedure Test;
var
MyBitmap: TBitmap;
i: Integer;
begin
MyBitmap := TBitmap.Create;
MyBitmap.SetSize(50, 50);
for i := 1 to 100 do
MyBitmap.Utils.SomeNewRoutine;
FreeAndNil(MyBitmap);
end;
I don't need to free Utils as my adapter inherited from TInterfacedObject so it will be automatically freed when go out Test procedure scope, fine! but maybe there is a little performance problem.
Does the compiler create a new Utils instance for each iteration or it is smart enough in this case to reuse the same Utils instance while it's in the same scope?
Obviously I can get the instance before the for-loop then use it inside but I am trying to find out how to use the notation MyBitmap.Utils.SomeNewRoutine anywhere without a big deal with performance. Is any way to do it?
Note: I am using Delphi 10.3
Edit
To be more clear:
Is there any way to accomplish this without a performance penalty like one described above (i.e use the notation inside a loop)?
Upvotes: 1
Views: 103
Reputation: 109003
In the comments, it turns out that the main goal is to be able to write things like bm.Utils.SomeProcA
, bm.Utils.SomeProcB
for every TBitmap
value bm
, with as little overhead (performance penalty) as possible. My first idea would be to try
type
TBitmapUtils = record
private
FBitmap: TBitmap;
public
procedure MyProc1;
procedure MyProc2;
end;
TBitmapHelper = class helper for TBitmap
function Utils: TBitmapUtils; inline;
end;
where
{ TBitmapUtils }
procedure TBitmapUtils.MyProc1;
begin
ShowMessageFmt('The width of the bitmap is %d.', [FBitmap.Width]);
end;
procedure TBitmapUtils.MyProc2;
begin
ShowMessageFmt('The height of the bitmap is %d.', [FBitmap.Height]);
end;
{ TBitmapHelper }
function TBitmapHelper.Utils: TBitmapUtils;
begin
Result.FBitmap := Self;
end;
Upvotes: 2