GridDrawableMask = (GridTagBack or GridTagStep or GridTagWall or GridTagDoor or GridTagAcid1 or GridTagAcid2 or GridTagWater or GridTagFore);
+type
+ TBinHeapPanelDrawCmp = class
+ public
+ class function less (const a, b: TPanel): Boolean; inline;
+ end;
+
+ TBinHeapPanelDraw = specialize TBinaryHeapBase<TPanel, TBinHeapPanelDrawCmp>;
+
var
gWalls: TPanelArray;
gRenderBackgrounds: TPanelArray;
gdbg_map_use_accel_render: Boolean = true;
gdbg_map_use_accel_coldet: Boolean = true;
profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY!
- gDrawPanelList: TBinaryHeapObj = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()`
+ gDrawPanelList: TBinHeapPanelDraw = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()`
gCurrentMap: TDynRecord = nil;
gCurrentMapFileName: AnsiString = ''; // so we can skip texture reloading
end;
-function dplLess (a, b: TObject): Boolean;
-var
- pa, pb: TPanel;
+class function TBinHeapPanelDrawCmp.less (const a, b: TPanel): Boolean; inline;
begin
- pa := TPanel(a);
- pb := TPanel(b);
- if (pa.tag < pb.tag) then begin result := true; exit; end;
- if (pa.tag > pb.tag) then begin result := false; exit; end;
- result := (pa.arrIdx < pb.arrIdx);
+ if (a.tag < b.tag) then begin result := true; exit; end;
+ if (a.tag > b.tag) then begin result := false; exit; end;
+ result := (a.arrIdx < b.arrIdx);
end;
procedure dplClear ();
begin
- if (gDrawPanelList = nil) then gDrawPanelList := TBinaryHeapObj.Create(@dplLess) else gDrawPanelList.clear();
+ if (gDrawPanelList = nil) then gDrawPanelList := TBinHeapPanelDraw.Create() else gDrawPanelList.clear();
end;
x, y: Integer;
end;
+ TBinHeapKeyHitTime = class
+ public
+ class function less (const a, b: Integer): Boolean; inline;
+ end;
+
// indicies in `wgunHitTime` array
- TBinaryHeapHitTimes = specialize TBinaryHeapBase<Integer>;
+ TBinaryHeapHitTimes = specialize TBinaryHeapBase<Integer, TBinHeapKeyHitTime>;
var
WaterMap: array of array of DWORD = nil;
wgunHitTimeUsed: Integer = 0;
-function hitTimeLess (a, b: Integer): Boolean;
+class function TBinHeapKeyHitTime.less (const a, b: Integer): Boolean;
var
hta, htb: PHitTime;
begin
g_Texture_CreateWADEx('TEXTURE_SHELL_SHELL', GameWAD+':TEXTURES\ESHELL');
//wgunMonHash := hashNewIntInt();
- wgunHitHeap := TBinaryHeapHitTimes.Create(hitTimeLess);
+ wgunHitHeap := TBinaryHeapHitTimes.Create();
end;
procedure g_Weapon_FreeData();
interface
+(*
+ * CmpObjT: class that contains class methods:
+ * class function less (const[ref] a, b: KeyT): Boolean;
+ *)
type
// WARNING! don't put structures into heap, use ponters or ids!
- generic TBinaryHeapBase<ITP> = class(TObject)
- private
- type
- TBinaryHeapLessFn = function (a, b: ITP): Boolean;
-
+ generic TBinaryHeapBase<ITP, CmpObjT> = class(TObject)
private
elem: array of ITP;
elemUsed: Integer;
- lessfn: TBinaryHeapLessFn;
private
procedure heapify (root: Integer);
public
- constructor Create (alessfn: TBinaryHeapLessFn);
+ constructor Create ();
destructor Destroy (); override;
procedure clear ();
type
- TBinaryHeapObj = specialize TBinaryHeapBase<TObject>;
- TBinaryHeapInt = specialize TBinaryHeapBase<Integer>;
+ TBinHeapKeyIntLess = class
+ public
+ class function less (const a, b: Integer): Boolean; inline;
+ end;
+
+ TBinHeapKeyIntGreat = class
+ public
+ class function less (const a, b: Integer): Boolean; inline;
+ end;
-function binHeapNewIntLess (): TBinaryHeapInt;
-function binHeapNewIntGreat (): TBinaryHeapInt;
+type
+ TBinaryHeapIntLess = specialize TBinaryHeapBase<Integer, TBinHeapKeyIntLess>;
+ TBinaryHeapIntGreat = specialize TBinaryHeapBase<Integer, TBinHeapKeyIntGreat>;
implementation
// ////////////////////////////////////////////////////////////////////////// //
-function intLess (a, b: Integer): Boolean; begin result := (a < b); end;
-function intGreat (a, b: Integer): Boolean; begin result := (a > b); end;
-
-
-function binHeapNewIntLess (): TBinaryHeapInt; begin result := TBinaryHeapInt.Create(@intLess); end;
-function binHeapNewIntGreat (): TBinaryHeapInt; begin result := TBinaryHeapInt.Create(@intGreat); end;
+class function TBinHeapKeyIntLess.less (const a, b: Integer): Boolean; inline; begin result := (a < b); end;
+class function TBinHeapKeyIntGreat.less (const a, b: Integer): Boolean; inline; begin result := (a > b); end;
// ////////////////////////////////////////////////////////////////////////// //
-constructor TBinaryHeapBase.Create (alessfn: TBinaryHeapLessFn);
+constructor TBinaryHeapBase.Create ();
begin
- if not assigned(alessfn) then raise Exception.Create('wutafuck?!');
- lessfn := alessfn;
SetLength(elem, 128); // 'cause why not?
elemUsed := 0;
end;
smallest := 2*root+1; // left child
if (smallest >= elemUsed) then break; // anyway
right := smallest+1; // right child
- if not lessfn(elem[smallest], elem[root]) then smallest := root;
- if (right < elemUsed) and (lessfn(elem[right], elem[smallest])) then smallest := right;
+ if not CmpObjT.less(elem[smallest], elem[root]) then smallest := root;
+ if (right < elemUsed) and (CmpObjT.less(elem[right], elem[smallest])) then smallest := right;
if (smallest = root) then break;
// swap
tmp := elem[root];
while (i <> 0) do
begin
par := (i-1) div 2; // parent
- if not lessfn(val, elem[par]) then break;
+ if not CmpObjT.less(val, elem[par]) then break;
elem[i] := elem[par];
i := par;
end;