From: Ketmar Dark Date: Fri, 25 Aug 2017 13:01:20 +0000 (+0300) Subject: use idpool to allocate new item object X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=31c92166ce1ba9decf93e39f77e77833f879c4b4;p=d2df-sdl.git use idpool to allocate new item object --- diff --git a/src/game/Doom2DF.dpr b/src/game/Doom2DF.dpr index 1276f72..97b451e 100644 --- a/src/game/Doom2DF.dpr +++ b/src/game/Doom2DF.dpr @@ -100,6 +100,7 @@ uses xprofiler in '../shared/xprofiler.pas', binheap in '../shared/binheap.pas', hashtable in '../shared/hashtable.pas', + idpool in '../shared/idpool.pas', BinEditor in '../shared/BinEditor.pas', envvars in '../shared/envvars.pas', g_panel in 'g_panel.pas', diff --git a/src/game/g_items.pas b/src/game/g_items.pas index b0a053d..5ec5ddb 100644 --- a/src/game/g_items.pas +++ b/src/game/g_items.pas @@ -28,7 +28,6 @@ Type //treeNode: Integer; slotIsUsed: Boolean; arrIdx: Integer; // in ggItems - nextFree: Integer; // in item array public ItemType: Byte; @@ -87,7 +86,7 @@ uses g_basic, e_graphics, g_sound, g_main, g_gfx, g_map, Math, g_game, g_triggers, g_console, SysUtils, g_player, g_net, g_netmsg, e_log, - g_grid, binheap; + g_grid, binheap, idpool; var @@ -96,8 +95,7 @@ var // ////////////////////////////////////////////////////////////////////////// // var - //freeIds: TBinaryHeapInt = nil; // free item ids - freeListHead: Integer = -1; + freeIds: TIdPool = nil; // ////////////////////////////////////////////////////////////////////////// // @@ -265,7 +263,7 @@ begin InitTextures(); - //freeIds := binHeapNewIntLess(); + freeIds := TIdPool.Create(); end; @@ -322,7 +320,8 @@ begin g_Texture_Delete('ITEM_MEDKIT_BLACK'); g_Texture_Delete('ITEM_JETPACK'); - //freeIds.Free(); + freeIds.Free(); + freeIds := nil; end; @@ -331,8 +330,9 @@ var it: PItem; begin if (idx < 0) or (idx > High(ggItems)) then raise Exception.Create('releaseItem: invalid item id'); + if not freeIds.hasAlloced[LongWord(idx)] then raise Exception.Create('releaseItem: trying to release unallocated item (0)'); it := @ggItems[idx]; - if not it.slotIsUsed then raise Exception.Create('releaseItem: trying to release unallocated item'); + if not it.slotIsUsed then raise Exception.Create('releaseItem: trying to release unallocated item (1)'); if (it.arrIdx <> idx) then raise Exception.Create('releaseItem: arrIdx inconsistency'); it.slotIsUsed := false; if (it.Animation <> nil) then @@ -343,34 +343,11 @@ begin it.Live := False; it.SpawnTrigger := -1; it.ItemType := ITEM_NONE; - //freeIds.insert(it.arrIdx); - it.nextFree := freeListHead; - freeListHead := idx; + freeIds.release(LongWord(idx)); end; -procedure rebuildFreeList (reservedIdx: Integer=-1); -var - i, lfi: Integer; - it: PItem; -begin - // rebuild free list - freeListHead := -1; - lfi := -1; - for i := 0 to High(ggItems) do - begin - it := @ggItems[i]; - if (i <> reservedIdx) and (not it.slotIsUsed) then - begin - if (lfi = -1) then freeListHead := i else ggItems[lfi].nextFree := lfi; - lfi := i; - end; - end; - if (lfi <> -1) then ggItems[lfi].nextFree := -1; -end; - - -procedure growItemArrayTo (newsz: Integer; rebuildList: Boolean=true); +procedure growItemArrayTo (newsz: Integer); var i, olen: Integer; it: PItem; @@ -384,29 +361,20 @@ begin it := @ggItems[i]; it.slotIsUsed := false; it.arrIdx := i; - it.nextFree := i+1; it.ItemType := ITEM_NONE; it.Animation := nil; it.Live := false; it.SpawnTrigger := -1; it.Respawnable := false; - //freeIds.insert(i); + //if not freeIds.hasFree[LongWord(i)] then raise Exception.Create('internal error in item idx manager'); end; - if rebuildList then rebuildFreeList(); end; function allocItem (): DWORD; begin - if (freeListHead = -1) then - begin - growItemArrayTo(Length(ggItems)+64); - if (freeListHead = -1) then raise Exception.Create('internal error in item manager'); - end; - - result := DWORD(freeListHead); - freeListHead := ggItems[freeListHead].nextFree; - + result := freeIds.alloc(); + if (result >= Length(ggItems)) then growItemArrayTo(Integer(result)+64); if (Integer(result) > High(ggItems)) then raise Exception.Create('allocItem: freeid list corrupted'); if (ggItems[result].arrIdx <> Integer(result)) then raise Exception.Create('allocItem: arrIdx inconsistency'); end; @@ -417,21 +385,20 @@ function wantItemSlot (slot: Integer): Integer; var olen: Integer; it: PItem; - rebuildList: Boolean = false; begin if (slot < 0) or (slot > $0fffffff) then raise Exception.Create('wantItemSlot: bad item slot request'); // do we need to grow item storate? olen := Length(ggItems); - if (slot >= olen) then - begin - growItemArrayTo(slot+64, false); - rebuildList := true; - end; + if (slot >= olen) then growItemArrayTo(slot+64); it := @ggItems[slot]; - if rebuildList or (not it.slotIsUsed) then + if not it.slotIsUsed then + begin + freeIds.alloc(LongWord(slot)); + end + else begin - rebuildFreeList(slot); + if not freeIds.hasAlloced[slot] then raise Exception.Create('wantItemSlot: internal error in item idx manager'); end; it.slotIsUsed := false; @@ -459,8 +426,7 @@ begin for i := 0 to High(ggItems) do ggItems[i].Animation.Free(); ggItems := nil; end; - //freeIds.clear(); - freeListHead := -1; + freeIds.clear(); end; diff --git a/src/shared/idpool.pas b/src/shared/idpool.pas index 7817cc1..8cb99e6 100644 --- a/src/shared/idpool.pas +++ b/src/shared/idpool.pas @@ -14,7 +14,7 @@ * along with this program. If not, see . *) {$INCLUDE a_modes.inc} -{$DEFINE IDPOOL_CHECKS} +{.$DEFINE IDPOOL_CHECKS} unit idpool; interface