unit ModActu;
{$i define.pas}
interface
uses
  Classes, ModuType;

type
  TModuleAction = class(TObject)
  private
    FActionID: TModuleActionID;
    FPriority: integer;
      { Priority of the action, the higher the value, the higher the priority.
        If priority > 0, then if action got from ActionList in DoTimer,
        the following message will be processed in the same DoTimer call
        (otherwise next action will be handled in the next DoTimer call) }
    FInfo: integer;
      { Eventual additional info for the Action }
    FSize: integer;
      { if > 0, than info is pointer to memory buffer of size = Size }
  public
    procedure SetInfo(AInfo: integer; ASize: integer);
    {  If ASize > 0, then allocates memory and copies AInfo^ to it.
      (I.e. AInfo is not handled in any way further (should be eventually
      disposed by the caller if was allocated). }
    destructor Destroy;override;

    property ActionID: TModuleActionID read FActionID write FActionID;
    property Priority: integer read FPriority write FPriority;
    property Info: integer read FInfo;
    property Size: integer read FSize;
  end;

  TModuleActionList = class(TList)
    function AddAction(AActionID: TModuleActionID; APriority: integer;
      AInfo: longint): TModuleAction;
      { Creates and adds Action object to the list. Returns pointer to created Action
        (nil if failed). }
    function FindAction(AActionID: TModuleActionID;
      var AAction: TModuleAction): boolean;
    function PeekAction(var AAction: TModuleAction): boolean;
      { Return pointer to the first action in the list (leave it
        in the list). Return false if there are no actions. }
    function GetAction(var AAction: TModuleAction): boolean;
      { Delete first action in the list from the list
        and return pointer to it. Returns false if there is no
        actions. }
  end;

implementation

{TModuleAction}
procedure TModuleAction.SetInfo(AInfo: integer; ASize: integer);
begin
  if Size <> 0 then begin
    FreeMem(pointer(Info));
    FSize := 0;
    FInfo := 0;
  end;
  if ASize = 0 then begin
    FInfo := AInfo;
  end else begin
    GetMem(pointer(FInfo), ASize);
    Move(pointer(AInfo)^, pointer(FInfo)^, ASize);
  end;
  FSize := ASize;
end;

destructor TModuleAction.Destroy;
begin
  SetInfo(0,0);
  inherited Destroy;
end;
{/TModuleAction}

{TModuleActionList}
function TModuleActionList.AddAction(AActionID: TModuleActionID;
  APriority: integer; AInfo: longint): TModuleAction;
var A: TModuleAction;
begin
  Result := nil;
  A := TModuleAction.Create;
  A.ActionID := AActionID;
  A.Priority := APriority;
  if AInfo <> 0 then
    A.SetInfo(AInfo, 0);
  if Add(A) >= 0 then begin
    Result := A;
  end else begin
    A.Free;
  end;
end;

function TModuleActionList.FindAction(AActionID: TModuleActionID;
      var AAction: TModuleAction): boolean;
var
  i: integer;
  a: TModuleAction;
begin
  Result := false;
  AAction := nil;
  for i := 0 to Count - 1 do begin
    a := TModuleAction(Items[i]);
    if a.ActionID = AActionID then begin
      AAction := a;
      Result := true;
    end;
  end;
end;

function TModuleActionList.PeekAction(var AAction: TModuleAction): boolean;
      { Return pointer to the first action in the list (leave it
        in the list). Return false if there are no actions. }
begin
  Result := false;
  if Count > 0 then begin
    Result := true;
    AAction := TModuleAction(Items[0]);
  end;
end;

function TModuleActionList.GetAction(var AAction: TModuleAction): boolean;
      { Delete first action in the list from the list
        and return pointer to it. Returns false if there is no
        actions. }
begin
  Result := false;
  if Count = 0 then
    exit;
  AAction := TModuleAction(Items[0]);
  Delete(0);{tlist}
  Result := true;
end;
{/TModuleActionList}

end.
