Code: Alles auswählen
TCustomGeoList = specialize TFPGObjectList<TGeo>;
TGeoList = class ( TCustomGeoList )
public
procedure Draw(Canvas : TCanvas);
end;
implementation
procedure TGeoList.Draw(Canvas: TCanvas);
var i : integer;
enum : TFPGListEnumeratorSpec;
begin
enum := GetEnumerator;
try
while enum.MoveNext do
begin
geo := enum.Current;
if geo.Visible then
begin
geo.PrepareCanvas(Canvas);
geo.Draw(Canvas);
end;
end;
finally
enum.Free;
end;
end;
Das mit diesem Enumerator ist mMn äusserst umständlich. Vor 30 Jahren hatte ich ähnliche Aufgaben mit TList.ForEach gelöst.
Da sah das dann so aus.
Code: Alles auswählen
procedure TGeoList.Draw(Canvas : TCanvas);
procedure All(geo : TGeo);
begin
if (geo.Visible) then
begin
geo.PrepareCanvas(Canvas);
geo.Draw(Canvas);
end;
end;
begin // TGeoList.Draw
ForEach(@All);
end;
Ich habe spaßeshalber diese ForEach Methode mal implementiert und die funktioniert auch einwandfrei.
Code: Alles auswählen
type
TGeoList = class ( TCustomGeoList )
procedure ForEach (Action: Pointer; Forward : boolean = True); // Führt "Action" für jeden Eintrag der Liste aus
end;
implementation
type
PointerIntLocal = function(_EBP: Pointer; Param1 : Pointer; Param2 : Integer) : Pointer;
function callpointerintlocal(Func: Pointer; Frame : Pointer; Param1 : Pointer; Param2 : Integer) : Pointer;
begin
CallPointerIntLocal := PointerIntLocal(Func)(Frame, Param1, Param2);
end;
procedure TGeoList.ForEach(Action: Pointer; Forward: boolean);
var
item : Pointer;
i : Integer;
begin
if forward then i := 0 else i := Pred(Count);
while ((forward) and (i < count)) or (not (forward) and (i >= 0)) do
begin
item := items[i];
if assigned (item) then
CallPointerIntLocal(action, get_caller_frame(get_frame), item, i);
if forward then inc (i) else dec(i);
end;
end;
Meint ihr man kann die FPC Entwickler (PascalDragon?) dazu überreden, diesen Code in die TFPList / TFPGObjectList etc. aufzunehmen?
TList hatte ausserdem noch die beiden Methoden FirstThat und LastThat, die auf gleiche Weise eine lokale boolsche Funktion aufgerufen haben und den Eintrag zurücklieferten für den diese Funktion true zurückgeliefert hatte. Ich hab die beiden ebenfalls erfolgreich implementiert.