unit ObjectRegister;

interface

uses Classes, IniFiles;

type
  TNamedObject = class(TObject)
  private
    FName: string;
  public
    constructor Create(const Name: string); virtual;
    destructor Destroy; override;
    property Name: string read FName;
  end;

  TObjectRegister = class(TObject)
  private
    FItems: TList;
    FNames: TStringHash;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    function Add(const Name: string; const Instance: TObject): Integer;
    function Find(const Name: string): TObject;
    procedure Clear;
    procedure Remove(const Instance: TObject);
  end;

var
  RegisterObject: TObjectRegister;

implementation

uses SysUtils;

{ TObjectRegister }

function TObjectRegister.Add(const Name: string;
  const Instance: TObject): Integer;
begin
  Result:= FItems.Add(Instance);
  FNames.Add(UpperCase(Name), Result);
end;

procedure TObjectRegister.Clear;
begin
  FItems.Clear;
  FNames.Clear;
end;

constructor TObjectRegister.Create;
begin
  inherited Create;
  FItems:= TList.Create;
  FNames:= TStringHash.Create;
end;

destructor TObjectRegister.Destroy;
begin
  Clear;
  FreeAndNil(FItems);
  FreeAndNil(FNames);
  inherited;
end;

function TObjectRegister.Find(const Name: string): TObject;
var
  LIndex: Integer;
begin
  LIndex:= FNames.ValueOf(UpperCase(Name));
  if LIndex <> -1 then
    Result:= TObject(FItems[LIndex])
  else
    Result:= nil;
end;

procedure TObjectRegister.Remove(const Instance: TObject);
var
  LIndex: Integer;
begin
  LIndex:= FItems.IndexOf(Instance);

  if LIndex <> -1 then
  begin
    FNames.Remove(UpperCase(TNamedObject(Instance).Name));
    FItems.Delete(LIndex);
  end;
end;

{ TNamedObject }

constructor TNamedObject.Create(const Name: string);
begin
  inherited Create;
  FName:= Name;
  RegisterObject.Add(Name, Self);
end;

destructor TNamedObject.Destroy;
begin
  RegisterObject.Remove(Self);
  inherited;
end;

initialization
  RegisterObject:= TObjectRegister.Create;

finalization
  FreeAndNil(RegisterObject);

end.