Changeset 344 for trunk/ItemList.pas


Ignore:
Timestamp:
Dec 23, 2024, 8:16:05 AM (10 hours ago)
Author:
chronos
Message:
  • Modified: Improved implementation of TItemList class to be generic class to avoid explicit typecasting.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ItemList.pas

    r342 r344  
    77
    88type
    9   TItemList = class;
     9  //TItemList<T> = class;
    1010  TUndefinedEnum = (eeNone);
    1111
     
    3434    function AddField(Index: Integer; SysName, Name: string; DataType: TDataType): TItemField;
    3535    function SearchByIndex(Index: Integer): TItemField;
     36  end;
     37
     38  { IList }
     39
     40  IList<T> = interface
     41    function GetName: string;
     42    function GetCount: SizeInt;
     43    function GetItem(Index: SizeInt): T;
     44    function Remove(constref AValue: T): SizeInt;
     45    function Add(constref AValue: T): SizeInt;
     46    function CreateBaseItem(Name: string = ''): T;
     47    function GetNextAvailableName(Name: string): string;
     48    function GetItemFields: TItemFields;
     49    procedure SetItem(Index: SizeInt; AValue: T);
     50    property Count: SizeInt read GetCount;
     51    property Items[Index: SizeInt]: T read GetItem write SetItem; default;
    3652  end;
    3753
     
    7187    class function GetClassSysName: string; virtual;
    7288    class function GetClassName: string; virtual;
    73     function GetReferenceList(Index: Integer): TItemList; virtual;
     89    function GetReferenceList(Index: Integer): IList<TItem>; virtual;
    7490    constructor Create; virtual;
    7591  end;
     
    7793  TItemClass = class of TItem;
    7894
     95  IItemList = interface(IList<TItem>)
     96  end;
     97
    7998  { TItemList }
    8099
    81   TItemList = class(TObjectList<TItem>)
     100  TItemList<T: TItem> = class(TObjectList<T>, IList<TItem>)
    82101  private
    83102    procedure RecalculateNewId(Reset: Boolean);
    84103    procedure RecalculateItemsId;
     104    function GetItem(Index: SizeInt): TItem;
     105    procedure SetItem(Index: SizeInt; AValue: TItem);
     106  protected
     107    function GetCount: SizeInt; override;
    85108  public
     109  type
     110  var
    86111    NewId: Integer;
    87     class function GetItemClass: TItemClass; virtual;
     112    function GetName: string;
     113    function GetItemFields: TItemFields;
     114    function Remove(constref AValue: TItem): SizeInt;
     115    function Add(constref AValue: TItem): SizeInt;
     116    function CreateItem(Name: string = ''): T; virtual;
     117    function CreateBaseItem(Name: string = ''): TItem;
    88118    function IncrementName(Name: string): string;
    89119    function GetNextAvailableName(Name: string): string;
    90     function FindById(Id: Integer): TItem;
    91     function FindByName(Name: string): TItem;
     120    function FindById(Id: Integer): T;
     121    function FindByName(Name: string): T;
    92122    function GetNewId: Integer;
    93123    function ToString: string; override;
    94     procedure Assign(Source: TItemList); virtual;
    95     function Compare(ItemList: TItemList): Boolean; virtual;
    96     function AddItem(Name: string = ''): TItem; virtual;
    97     function CreateItem(Name: string = ''): TItem; virtual;
     124    procedure Assign(Source: TItemList<T>); virtual;
     125    function Compare(ItemList: TItemList<T>): Boolean; virtual;
     126    function AddItem(Name: string = ''): T; virtual;
    98127    procedure LoadFromNode(Node: TDOMNode); virtual;
    99128    procedure SaveToNode(Node: TDOMNode); virtual;
    100129    constructor Create(FreeObjects: Boolean = True);
     130    function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
     131    function _AddRef: Longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
     132    function _Release: Longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
    101133  end;
    102134
     
    145177{ TItemList }
    146178
    147 procedure TItemList.Assign(Source: TItemList);
     179procedure TItemList<T>.Assign(Source: TItemList<T>);
    148180var
    149181  I: Integer;
     
    155187end;
    156188
    157 function TItemList.Compare(ItemList: TItemList): Boolean;
     189function TItemList<T>.Compare(ItemList: TItemList<T>): Boolean;
    158190var
    159191  I: Integer;
     
    167199end;
    168200
    169 function TItemList.AddItem(Name: string): TItem;
    170 begin
    171   Result := CreateItem(Name);
     201function TItemList<T>.AddItem(Name: string): T;
     202begin
     203  Result := T.Create;
     204  Result.Name := Name;
    172205  Result.Id := GetNewId;
    173206  Add(Result);
    174207end;
    175208
    176 function TItemList.CreateItem(Name: string): TItem;
    177 begin
    178   Result := GetItemClass.Create;
     209function TItemList<T>.CreateItem(Name: string): T;
     210begin
     211  Result := T.Create;
    179212  Result.Name := Name;
    180213end;
    181214
    182 procedure TItemList.LoadFromNode(Node: TDOMNode);
     215function TItemList<T>.CreateBaseItem(Name: string): TItem;
     216begin
     217  Result := TItem(CreateItem(Name));
     218end;
     219
     220procedure TItemList<T>.LoadFromNode(Node: TDOMNode);
    183221var
    184222  Node2: TDOMNode;
    185   NewItem: TItem;
     223  NewItem: T;
    186224begin
    187225  Count := 0;
    188226  Node2 := Node.FirstChild;
    189   while Assigned(Node2) and (Node2.NodeName = UnicodeString(GetItemClass.GetClassSysName)) do begin
     227  while Assigned(Node2) and (Node2.NodeName = UnicodeString(T.GetClassSysName)) do begin
    190228    NewItem := CreateItem;
    191229    NewItem.LoadFromNode(Node2);
     
    195233end;
    196234
    197 procedure TItemList.SaveToNode(Node: TDOMNode);
     235procedure TItemList<T>.SaveToNode(Node: TDOMNode);
    198236var
    199237  I: Integer;
     
    203241  for I := 0 to Count - 1 do
    204242  with TItem(Items[I]) do begin
    205     NewNode2 := Node.OwnerDocument.CreateElement(UnicodeString(GetItemClass.GetClassSysName));
     243    NewNode2 := Node.OwnerDocument.CreateElement(UnicodeString(T.GetClassSysName));
    206244    Node.AppendChild(NewNode2);
    207245    SaveToNode(NewNode2);
     
    209247end;
    210248
    211 constructor TItemList.Create(FreeObjects: Boolean);
     249constructor TItemList<T>.Create(FreeObjects: Boolean);
    212250begin
    213251  inherited;
     
    215253end;
    216254
    217 procedure TItemList.RecalculateNewId(Reset: Boolean);
     255function TItemList<T>.QueryInterface(constref iid: tguid; out obj): longint;
     256  stdcall;
     257begin
     258end;
     259
     260function TItemList<T>._AddRef: Longint; stdcall;
     261begin
     262end;
     263
     264function TItemList<T>._Release: Longint; stdcall;
     265begin
     266end;
     267
     268function TItemList<T>.GetCount: SizeInt;
     269begin
     270  Result := Count;
     271end;
     272
     273function TItemList<T>.GetName: string;
     274begin
     275  Result := T.GetClassName;
     276end;
     277
     278function TItemList<T>.GetItemFields: TItemFields;
     279begin
     280  Result := T.GetFields;
     281end;
     282
     283function TItemList<T>.Remove(constref AValue: TItem): SizeInt;
     284begin
     285  Result := inherited Remove(T(AValue));
     286end;
     287
     288function TItemList<T>.Add(constref AValue: TItem): SizeInt;
     289begin
     290  Result := inherited Add(T(AValue));
     291end;
     292
     293procedure TItemList<T>.RecalculateNewId(Reset: Boolean);
    218294var
    219295  I: Integer;
     
    226302end;
    227303
    228 procedure TItemList.RecalculateItemsId;
     304procedure TItemList<T>.RecalculateItemsId;
    229305var
    230306  I: Integer;
     
    235311end;
    236312
    237 class function TItemList.GetItemClass: TItemClass;
    238 begin
    239   Result := TItem;
    240 end;
    241 
    242 function TItemList.IncrementName(Name: string): string;
     313function TItemList<T>.GetItem(Index: SizeInt): TItem;
     314begin
     315  Result := inherited GetItem(Index);
     316end;
     317
     318procedure TItemList<T>.SetItem(Index: SizeInt; AValue: TItem);
     319begin
     320  inherited SetItem(Index, T(AValue));
     321end;
     322
     323function TItemList<T>.IncrementName(Name: string): string;
    243324var
    244325  I: Integer;
     
    253334end;
    254335
    255 function TItemList.GetNextAvailableName(Name: string): string;
     336function TItemList<T>.GetNextAvailableName(Name: string): string;
    256337begin
    257338  Result := Name;
     
    260341end;
    261342
    262 function TItemList.FindById(Id: Integer): TItem;
     343function TItemList<T>.FindById(Id: Integer): T;
    263344var
    264345  I: Integer;
     
    270351end;
    271352
    272 function TItemList.FindByName(Name: string): TItem;
     353function TItemList<T>.FindByName(Name: string): T;
    273354var
    274355  I: Integer;
     
    280361end;
    281362
    282 function TItemList.GetNewId: Integer;
     363function TItemList<T>.GetNewId: Integer;
    283364begin
    284365  Result := NewId;
     
    286367end;
    287368
    288 function TItemList.ToString: string;
     369function TItemList<T>.ToString: string;
    289370var
    290371  I: Integer;
     
    370451var
    371452  ReadId: Integer;
    372   ReferenceList: TItemList;
     453  ReferenceList: IList<TItem>;
    373454begin
    374455  if Field.DataType = dtString then begin
     
    389470  if Field.DataType = dtReference then begin
    390471    ReadId := ReadInteger(Node, Field.SysName, 0);
    391     ReferenceList := GetReferenceList(Field.Index);
     472    ReferenceList := IList<TItem>(GetReferenceList(Field.Index));
    392473    if (ReadId > 0) and Assigned(ReferenceList) then
    393474      SetValueReference(Field.Index, TItem(ReferenceList[ReadId]));
     
    632713end;
    633714
    634 function TItem.GetReferenceList(Index: Integer): TItemList;
     715function TItem.GetReferenceList(Index: Integer): IList<TItem>;
    635716begin
    636717  Result := nil;
Note: See TracChangeset for help on using the changeset viewer.