unit dallocator_fixed;

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

interface

type
TAllocatorFixed = object
public type
  PInitializer = ^TInitializer;
  TInitializer = record
    MemStart: Pointer;
    MemSize: SizeUInt;
  end;
private
  FCursor: Pointer;
  FMemStart: Pointer;
  FMemEnd: Pointer;
  FInHeap: Boolean;
public
  procedure Init(Initializer: PInitializer = nil); inline;
  procedure Done; inline;
  function GetMem(Size: SizeUInt): Pointer; inline;
  procedure FreeMem(P: Pointer); inline;
end;

TAllocatorFixed512 = object(TAllocatorFixed)
public
  procedure Init; inline;
end;

TAllocatorFixed4MB = object(TAllocatorFixed)
public
  procedure Init; inline;
end;

implementation

procedure TAllocatorFixed.Init(Initializer: PInitializer = nil);
begin
  if Initializer = nil then begin
    FMemStart := System.GetMem(512);
    FMemEnd := FMemStart + 512;
    FCursor := FMemStart;
    FInHeap := True;
  end else begin
    if Initializer^.MemStart <> nil then begin
      FMemStart := Initializer^.MemStart;
      FInHeap := False;
    end else begin
      FMemStart := System.GetMem(Initializer^.MemSize);
      FInHeap := True;
    end;
    FMemEnd := FMemStart + Initializer^.MemSize;
    FCursor := FMemStart;
  end;
end;

procedure TAllocatorFixed.Done;
begin
  System.FreeMem(FMemStart);
end;

function TAllocatorFixed.GetMem(Size: SizeUInt): Pointer;
begin
  if FCursor + Size < FMemEnd then begin
    Result := FCursor;
    Inc(FCursor, Size);
    Writeln('INFO: Allocted ', Size, ', ', FMemEnd - FCursor, ' left');
    Exit;
  end else
    Exit(nil);
end;

procedure TAllocatorFixed.FreeMem(P: Pointer);
begin
end;

procedure TAllocatorFixed512.Init;
var
  Initializer: TInitializer;
begin
  Initializer.MemStart := nil;
  Initializer.MemSize := 512;
  inherited Init(@Initializer);
end;

procedure TAllocatorFixed4MB.Init;
var
  Initializer: TInitializer;
begin
  Initializer.MemStart := nil;
  Initializer.MemSize := 4 * 1024 * 1024;
  inherited Init(@Initializer);
end;

end.
