{********************************************************

 SlavaNap source code.

 Copyright 2001,2002 by SlavaNap development team
 Released under GNU General Public License

 Latest version is available at
 http://www.slavanap.org

**********************************************************

 Unit: class_doublecmdlist

 TNapDoubleCmd and TNapDoubleCmdList declarations

*********************************************************}
unit class_doublecmdlist;

interface

uses
 Windows, Classes2, SysUtils, class_cmdlist;

{$I defines.pas}

type
  TNapDoubleCmd         = record
       id1,id2    : Integer;
       cmd1,cmd2  : String;
  end;
  PNapDoubleCmd         = ^TNapDoubleCmd;
  TNapDoubleCmdList     = class(TMyList)
    function  Add(Value: TNapDoubleCmd):Integer;
    procedure Insert(Index:Integer; Value: TNapDoubleCmd);
    procedure Clear; override;
    procedure Delete(Index: Integer);
    procedure AddDoubleCmd(id1,id2: Integer; cmd1,cmd2:String);
    function  Cmd(index :Integer): TNapDoubleCmd;
    function  Cmd1(index: Integer):TNapCmd;
    function  Cmd2(index: Integer):TNapCmd;
    constructor Create;
    destructor Destroy; override;
  end;

function  CreateDoubleCmdList: TNapDoubleCmdList;
procedure FreeDoubleCmdList(list: TNapDoubleCmdList);
{$IFNDEF DISABLE_MEMORY_MANAGER}
procedure ExpireDoubleCmdLists;
{$ENDIF}

var
 count_napdoublecmdlist,
 count_napdoublecmdlist_max: Integer;
 count_napdoublecmdlist_items,
 count_napdoublecmdlist_items_max: Integer;

implementation

uses vars, thread, stypes, memory_manager;

{$IFNDEF DISABLE_MEMORY_MANAGER}
var
 lists, items: TMyList; 
{$ENDIF}

function  CreateDoubleCmdList: TNapDoubleCmdList;
begin
{$IFNDEF DISABLE_MEMORY_MANAGER}
 if lists.count>0 then
 begin
  Result:=lists.Items[lists.count-1];
  lists.Delete(lists.count-1);
 end
 else
{$ENDIF}
  Result:=TNapDoubleCmdList.Create;
end;

procedure FreeDoubleCmdList(list: TNapDoubleCmdList);
begin
{$IFDEF DISABLE_MEMORY_MANAGER}
 list.Clear;
 list.Free;
{$ELSE}
 list.Clear;
 lists.Add(list);
{$ENDIF}
end;

function CreateItem: PNapDoubleCmd;
var
 data: PNapDoubleCmd;
begin
{$IFNDEF DISABLE_MEMORY_MANAGER}
 if items.count>0 then
 begin
  data:=items.Items[items.count-1];
  items.Delete(items.count-1);
 end
 else
 begin
{$ENDIF}
  data:=AllocMem(sizeof(TNapDoubleCmd));
  Pointer(data^.cmd1):=nil;
  Pointer(data^.cmd2):=nil;
  inc(count_napdoublecmdlist_items);
  if count_napdoublecmdlist_items>count_napdoublecmdlist_items_max then count_napdoublecmdlist_items_max:=count_napdoublecmdlist_items;
{$IFNDEF DISABLE_MEMORY_MANAGER}
 end;  
{$ENDIF}
 Result:=data;
end;

procedure FreeItem(item: PNapDoubleCmd);
begin
 if Pointer(item^.cmd1)<>nil then SetLength(item^.cmd1,0);
 if Pointer(item^.cmd2)<>nil then SetLength(item^.cmd2,0);
 Finalize(item^);
 FreeMem(item,sizeof(TNapDoubleCmd));
 dec(count_napdoublecmdlist_items);
end;

procedure DeleteItem(item: PNapDoubleCmd);
begin
{$IFDEF DISABLE_MEMORY_MANAGER}
 FreeItem(item);
{$ELSE}
 if Pointer(item^.cmd1)<>nil then SetLength(item^.cmd1,0);
 if Pointer(item^.cmd2)<>nil then SetLength(item^.cmd2,0);
 items.Add(item);
{$ENDIF}
end;

{$IFNDEF DISABLE_MEMORY_MANAGER}
procedure ExpireDoubleCmdLists;
var
 list: TNapDoubleCmdList;
 item: PNapDoubleCmd;
begin
 if lists.count>1000 then
 while (lists.count * 3) > count_napdoublecmdlist do
 try
   list:=lists.items[lists.count-1];
   lists.Delete(lists.count-1);
   list.Free;
  except
 end;
 if items.count>10000 then
 while (items.count * 3) > count_napdoublecmdlist_items do
 try
   item:=items.Items[items.count-1];
   items.Delete(items.count-1);
   FreeItem(item);
  except
 end;
end;
{$ENDIF}

{* * * * *  TNapDoubleCmdList  * * * * *}

function TNapDoubleCmdList.Add(Value: TNapDoubleCmd):Integer;
var
 data:PNapDoubleCmd;
begin
 data:=CreateItem;
 with data^ do
 begin
  cmd1:=Value.cmd1;
  cmd2:=Value.cmd2;
  id1:=Value.id1;
  id2:=Value.id2;
 end;
 Result:=inherited Add(data);
end;

procedure TNapDoubleCmdList.Insert(Index:Integer; Value: TNapDoubleCmd);
var
 data:PNapDoubleCmd;
begin
 data:=CreateItem;
 with data^ do
 begin
  cmd1:=Value.cmd1;
  cmd2:=Value.cmd2;
  id1:=Value.id1;
  id2:=Value.id2;
 end;
 inherited Insert(Index,data);
end;

procedure TNapDoubleCmdList.Clear;
begin
 while count>0 do
  Delete(count-1);
 inherited Clear;
end;

procedure TNapDoubleCmdList.Delete(Index: Integer);
begin
 if (Index<0) or (Index>=Count) then exit;
 if Items[Index]<>nil then
  DeleteItem(Items[Index]);
 Inherited Delete(index);
end;

procedure TNapDoubleCmdList.AddDoubleCmd(id1,id2: Integer; cmd1,cmd2:String);
var
 data:TNapDoubleCmd;
begin
 data.id1:=id1;
 data.id2:=id2;
 data.cmd1:=cmd1;
 data.cmd2:=cmd2;
 Add(data);
end;

function TNapDoubleCmdList.Cmd(index :Integer): TNapDoubleCmd;
var
 data:TNapDoubleCmd;
begin
 if (index>=0) and (index<count) then
 begin
  data:=TNapDoubleCmd(Items[index]^);
  Result:=data;
  exit;
 end;
 data.id1:=-1;
 data.cmd1:='';
 data.id2:=-1;
 data.cmd2:='';
 Result:=data;
end;

function  TNapDoubleCmdList.Cmd1(index: Integer):TNapCmd;
var
 data:TNapCmd;
 item:PNapDoubleCmd;
begin
 if (index>=0) and (index<count) then
 begin
   item:=Items[index];
   data.id:=item^.id1;
   data.cmd:=item^.cmd1;
   Result:=data;
   exit;
 end;
 data.id:=-1;
 data.cmd:='';
 Result:=data;
end;

function  TNapDoubleCmdList.Cmd2(index: Integer):TNapCmd;
var
 data:TNapCmd;
 item:PNapDoubleCmd;
begin
 if (index>=0) and (index<count) then
 begin
   item:=Items[index];
   data.id:=item^.id2;
   data.cmd:=item^.cmd2;
   Result:=data;
   exit;
 end;
 data.id:=-1;
 data.cmd:='';
 Result:=data;
end;

constructor TNapDoubleCmdList.Create;
begin
 inc(count_napdoublecmdlist);
 if count_napdoublecmdlist>count_napdoublecmdlist_max then count_napdoublecmdlist_max:=count_napdoublecmdlist;
 inherited Create;
end;

destructor TNapDoubleCmdList.Destroy;
begin
 Clear;
 dec(count_napdoublecmdlist);
 inherited Destroy;
end;

{$IFNDEF DISABLE_MEMORY_MANAGER}
procedure ClearDoubleCmdLists;
var
 i: Integer;
 p: PNapDoubleCmd;
begin
 for i:=0 to lists.count-1 do
  TNapDoubleCmdList(lists.items[i]).Free;
 lists.Clear;
 for i:=0 to items.count-1 do
 begin
   p:=items.Items[i];
   FreeItem(p);
 end;
 items.Clear;
end;
{$ENDIF}

initialization
begin
 count_napdoublecmdlist:=0;
 count_napdoublecmdlist_max:=0;
 count_napdoublecmdlist_items:=0;
 count_napdoublecmdlist_items_max:=0;
{$IFNDEF DISABLE_MEMORY_MANAGER}
 lists:=TMyList.Create;
 items:=TMyList.Create;
{$ENDIF}
end;

{$IFNDEF DISABLE_MEMORY_MANAGER}
finalization
begin
 ClearDoubleCmdLists;
 lists.Free;
 items.Free;
end;
{$ENDIF}
end.
