program Project1;
{$MODE OBJFPC}
uses fgl;

type

  { TBase }

  TBase = class
    class function FromData(data: string): TBase;virtual;
    class procedure RegisterSelf;
  end;

  TBaseClass = class of TBase;
  TClassesList = specialize TFPGMap<string, TBaseClass>;

  { TChild1 }

  TChild1 = class(TBase)
    class function FromData(data: string): TBase;override;
  end;

  TSomeList = specialize TFPGMap<string, TChild1>;

var
  aClasses: TClassesList;
  SomeList: TSomeList;

{ TChild1 }

class function TChild1.FromData(data: string): TBase;
begin
  if data = '' then
    Result:=inherited FromData('default')
  else
  begin
    writeln('Finding '+ClassName+' by name: '+data);
    Result := SomeList.KeyData[data];
  end;
end;


class function TBase.FromData(data: string): TBase;
begin
  writeln('created new '+ClassName+' with params: '+data);
  Result := self.Create;
end;

class procedure TBase.RegisterSelf;
begin
  if not Assigned(aClasses) then aClasses := TClassesList.Create;
  aClasses.Add(ClassName,TBaseClass(ClassType));
end;


const

  SavedFile: array[1..4, 1..2] of string =
    (
    ('TBase','123'),
    ('TBase','test'),
    ('TChild1',''),
    ('TChild1','test')
    );

function StrToClass(s: string): TBaseClass;
begin
  Result := aClasses.KeyData[s];
end;


var
  i: integer;
begin
  TBase.RegisterSelf;
  TChild1.RegisterSelf;

  SomeList := TSomeList.Create;
  SomeList.Add('test', TChild1.Create);

  for i := 1 to 4 do
      StrToClass(SavedFile[i, 1]).FromData(SavedFile[i, 2]);

  readln;
end.
