AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Multi-ObjectLists (Objekte mehrmals in einer Liste)
Thema durchsuchen
Ansicht
Themen-Optionen

Multi-ObjectLists (Objekte mehrmals in einer Liste)

Ein Thema von himitsu · begonnen am 12. Jul 2010 · letzter Beitrag vom 12. Jul 2010
 
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.345 Beiträge
 
Delphi 12 Athens
 
#1

Multi-ObjectLists (Objekte mehrmals in einer Liste)

  Alt 12. Jul 2010, 10:23
Nja, was soll man dazu sagen?

Dieses sind einfach nur Listen, in welchen das selbe Objekt mehrmals enthalten sein kann, ohne das es Probleme geben könnte.

> Es gibt nur Auswirkungen, wenn OwnsObjects auf TRUE steht,
> sonst reagieren diese Listen, wie ihre "normalen" Verwandten.

Ist ein Objekt mehrmals vorhanden, dann wird es erst freigegeben, wenn keine Instanzen mehr in der Liste stecken.
(bei den normalen Listen wird das Objekt ja ohne Prüfung sofort freigegeben)

Delphi-Quellcode:
unit MultiLists;

interface
  {$DEFINE UseGenerics}

  uses
    Classes, Contnrs {$IFDEF UseGenerics}, Generics.Collections{$ENDIF};

  type
    TMultiObjectList = class(TObjectList)
    protected
      procedure Notify(Ptr: Pointer; Action: TListNotification); override;
    public
      function Remove(AObject: TObject; RemoveAll: Boolean): Integer; overload;
      procedure RemoveAll(AObject: TObject); inline;
    end;

    TMultiObjectStringList = class(TStringList)
    protected
      procedure PutObject(Index: Integer; AObject: TObject); override;
    public
      destructor Destroy; override;
      procedure Clear; override;
      procedure Delete(Index: Integer); override;
    end;

    {$IFDEF UseGenerics}

      TMultiObjectList<T: class> = class(TObjectList<T>)
      protected
        procedure Notify(const Value: T; Action: TCollectionNotification); override;
      public
        function Remove(const Value: T; RemoveAll: Boolean): Integer; overload;
        procedure RemoveAll(const Value: T); inline;
      end;

    {$ENDIF}

implementation
  procedure TMultiObjectList.Notify(Ptr: Pointer; Action: TListNotification);
  begin
    if (Action = lnDeleted) and OwnsObjects then begin
      if IndexOf(TObject(Ptr)) < 0 then
        TObject(Ptr).Free;
    end else inherited;
  end;

  function TMultiObjectList.Remove(AObject: TObject; RemoveAll: Boolean): Integer;
  var
    i: Integer;
  begin
    if RemoveAll then begin
      Result := -1;
      repeat
        i := Remove(AObject);
        if i >= 0 then Result := i;
      until i < 0;
    end else Result := Remove(AObject);
  end;

  procedure TMultiObjectList.RemoveAll(AObject: TObject);
  begin
    while Remove(AObject) >= 0 do ;
  end;

  procedure TMultiObjectStringList.PutObject(Index: Integer; AObject: TObject);
  var
    Temp: TObject;
    B: Boolean;
    i: Integer;
  begin
    if Assigned(AObject) then begin
      Temp := Objects[Index];
      if Temp <> AObject then begin
        inherited;
        if IndexOf(Temp) < 0 then
          Temp.Free;
      end;
    end else inherited;
  end;

  destructor TMultiObjectStringList.Destroy;
  begin
    OnChange := nil;
    OnChanging := nil;
    Clear;
    inherited;
  end;

  procedure TMultiObjectStringList.Clear;
  var
    i, i2: Integer;
    Temp: Tobject;
  begin
    BeginUpdate;
    try
      if (Count <> 0) and OwnsObjects then
        for i := Count - 1 downto 0 do begin
          Temp := Objects[i];
          for i2 := i - 1 downto 0 do
            if Objects[i2] = Temp then Objects[i2] := nil;
          Objects[i] := nil;
          Temp.Free;
        end;
      inherited;
    finally
      EndUpdate;
    end;
  end;

  procedure TMultiObjectStringList.Delete(Index: Integer);
  var
    Temp: Tobject;
    i: Integer;
  begin
    if OwnsObjects then begin
      BeginUpdate;
      try
        Temp := Objects[Index];
        for i := Count - 1 downto 0 do
          if (i <> Index) and (Objects[i] = Temp) then begin
            Objects[Index] := nil;
            break;
          end;
        inherited;
      finally
        EndUpdate;
      end;
    end else inherited;
  end;

  {$IFDEF UseGenerics}

    procedure TMultiObjectList<T>.Notify(const Value: T; Action: TCollectionNotification);
    var
      B: Boolean;
      i: Integer;
    begin
      if (Action = cnRemoved) and OwnsObjects then begin
        if Assigned(OnNotify) then OnNotify(Self, Value, cnRemoved);
        if IndexOf(Value) < 0 then Value.Free;
      end else inherited;
    end;

    function TMultiObjectList<T>.Remove(const Value: T; RemoveAll: Boolean): Integer;
    var
      i: Integer;
    begin
      if RemoveAll then begin
        Result := -1;
        repeat
          i := Remove(Value);
          if i >= 0 then Result := i;
        until i < 0;
      end else Result := Remove(AObject);
    end;

    procedure TMultiObjectList<T>.RemoveAll(const Value: T);
    begin
      while Remove(Value) >= 0 do ;
    end;

  {$ENDIF}

end.
[edits]
- kleine Optimierungen (einige For-Schleifen gegen IndexOf ersetzt)
- RemoveAll und Co. eingeführt
- RemoveAll-Parameter wird nun auch beachtet
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (12. Jul 2010 um 12:00 Uhr)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz