unit ASTree;
{$WARN SYMBOL_PLATFORM OFF}
{$WARN DUPLICATE_CTOR_DTOR OFF}
interface
uses
SysUtils, Types, Classes, Generics.Defaults, Generics.Collections,
ASKernelDefs;
type
TTreeNode = class;
TTreeNodeClass = class of TTreeNode;
TTree = class
strict private
FRoot: TTreeNode;
protected
procedure DoCreateRoot(ARootNodeClass: TTreeNodeClass); virtual;
public
constructor Create(ARootNodeClass: TTreeNodeClass);
destructor Destroy; override;
property Root: TTreeNode read FRoot;
end;
TTreeNode = class
strict private
FTree: TTree;
FParent: TTreeNode;
FChildren: TObjectList<TTreeNode>;
function GetChild(Index: Integer): TTreeNode; inline;
function GetChildCount: Integer; inline;
function GetCapacity: Integer; inline;
procedure SetCapacity(const Value: Integer); inline;
protected
procedure InitNode; virtual;
procedure ValidateParent(ATree: TTree; AParent: TTreeNode); virtual;
function DoAddChild(ANodeClass: TTreeNodeClass): TTreeNode; virtual;
constructor Create(ATree: TTree; AParent: TTreeNode); overload; virtual;
public
constructor Create; overload;
destructor Destroy; override;
property Parent: TTreeNode read FParent;
property Tree: TTree read FTree;
property Capacity: Integer read GetCapacity write SetCapacity;
property Children[Index: Integer]: TTreeNode read GetChild;
property ChildCount: Integer read GetChildCount;
function AddChild(ANodeClass: TTreeNodeClass): TTreeNode; inline;
procedure RemoveChild(Index: Integer); inline;
procedure ClearChildren; inline;
procedure Clear; virtual;
function IsLeaf: Boolean; inline;
end;
implementation
constructor TTree.Create(ARootNodeClass: TTreeNodeClass);
begin
DoCreateRoot(ARootNodeClass);
end;
destructor TTree.Destroy;
begin
FreeAndNil(FRoot);
inherited;
end;
procedure TTree.DoCreateRoot(ARootNodeClass: TTreeNodeClass);
begin
FRoot := ARootNodeClass.Create(Self, nil);
end;
function TTreeNode.AddChild(ANodeClass: TTreeNodeClass): TTreeNode;
begin
Result := DoAddChild(ANodeClass);
end;
procedure TTreeNode.Clear;
begin
FChildren.Clear;
end;
procedure TTreeNode.ClearChildren;
begin
FChildren.Clear;
end;
constructor TTreeNode.Create;
begin
raise Exception.Create(SNoStandaloneNode);
end;
constructor TTreeNode.Create(ATree: TTree; AParent: TTreeNode);
begin
ValidateParent(ATree, AParent);
FTree := ATree;
FParent := AParent;
FChildren := TObjectList<TTreeNode>.Create(true);
InitNode;
end;
destructor TTreeNode.Destroy;
begin
FreeAndNil(FChildren);
inherited;
end;
function TTreeNode.GetCapacity: Integer;
begin
Result := FChildren.Capacity;
end;
function TTreeNode.GetChild(Index: Integer): TTreeNode;
begin
Result := FChildren[Index];
end;
function TTreeNode.GetChildCount: Integer;
begin
Result := FChildren.Count;
end;
function TTreeNode.DoAddChild(ANodeClass: TTreeNodeClass): TTreeNode;
begin
Result := FChildren[FChildren.Add(ANodeClass.Create(FTree, Self))];
end;
procedure TTreeNode.InitNode;
begin
end;
function TTreeNode.IsLeaf: Boolean;
begin
Result := FChildren.Count = 0;
end;
procedure TTreeNode.RemoveChild(Index: Integer);
begin
FChildren.Delete(Index);
end;
procedure TTreeNode.SetCapacity(const Value: Integer);
begin
FChildren.Capacity := Value;
end;
procedure TTreeNode.ValidateParent(ATree: TTree; AParent: TTreeNode);
begin
end;
end.