unit dobjects;

{$MODE FPC}
{$MODESWITCH DEFAULTPARAMETERS}
{$MODESWITCH RESULT}

interface

type
PObject = ^TObject;
TObject = object
public
  constructor Init;
  destructor Done; virtual;
  procedure Free;
end;

// This class contains only own Obj and a VMT
// No addition fields allowed
// No destructors allowed
// Pass only by value, never by reference
IInterface = object
protected
  Obj: Pointer;
public
  constructor Init(aObj: Pointer = nil);
  procedure Done; inline;
  function IsNil: Boolean; inline;
end;

TInitialize = procedure (Obj: Pointer);
TFinalize = procedure (Obj: Pointer);

TClass = object
  Size: SizeInt;
  Initialize: TInitialize;
  Finalize: TFinalize;
  Name: PAnsiChar; // may be ''
end;

function MakeClass(Size: SizeInt; Initialize: TInitialize; Finalize: TFinalize; Name: PAnsiChar = ''): TClass;

implementation

constructor TObject.Init;
begin
end;

destructor TObject.Done;
begin
end;

procedure TObject.Free;
begin
  if @Self <> nil then
    Dispose(PObject(@Self), Done);
end;

constructor IInterface.Init(aObj: Pointer = nil);
begin
  Obj := aObj;
end;

procedure IInterface.Done;
begin
end;

function IInterface.IsNil: Boolean;
begin
  Result := Obj = nil;
end;

function MakeClass(Size: SizeInt; Initialize: TInitialize; Finalize: TFinalize; Name: PAnsiChar = ''): TClass;
begin
  Result.Size := Size;
  Result.Initialize := Initialize;
  Result.Finalize := Finalize;
  Result.Name := Name;
end;

end.
