diff --git a/src/k_bheap.c b/src/k_bheap.c index 4f2285f9c..3b3d0fad9 100644 --- a/src/k_bheap.c +++ b/src/k_bheap.c @@ -143,6 +143,15 @@ static void K_BHeapSwapItems(bheap_t *heap, bheapitem_t *item1, bheapitem_t *ite // Swap the heap index on each item to be correct item2->heapindex = item1->heapindex; item1->heapindex = tempitemindex; + + if (item1->indexchanged != NULL) + { + item1->indexchanged(item1->data, item1->heapindex); + } + if (item2->indexchanged != NULL) + { + item2->indexchanged(item2->data, item2->heapindex); + } } } @@ -430,11 +439,11 @@ boolean K_BHeapValid(bheap_t *const heap) } /*-------------------------------------------------- - boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value) + boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value, updateindexfunc changeindexcallback) See header file for description. --------------------------------------------------*/ -boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value) +boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value, updateindexfunc changeindexcallback) { boolean pushsuccess = false; if (heap == NULL) @@ -455,6 +464,7 @@ boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value) } else { + bheapitem_t *newitem = NULL; // If the capacity of the heap has been reached, a realloc is needed // I'm just doing a basic double of capacity for simplicity if (heap->count >= heap->capacity) @@ -470,10 +480,18 @@ boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value) heap->capacity = newarraycapacity; } - heap->array[heap->count].heapindex = heap->count; - heap->array[heap->count].owner = heap; - heap->array[heap->count].data = item; - heap->array[heap->count].value = value; + newitem = &heap->array[heap->count]; + + newitem->heapindex = heap->count; + newitem->owner = heap; + newitem->data = item; + newitem->value = value; + newitem->indexchanged = changeindexcallback; + + if (newitem->indexchanged != NULL) + { + newitem->indexchanged(newitem->data, newitem->heapindex); + } heap->count++; @@ -517,6 +535,11 @@ boolean K_BHeapPop(bheap_t *const heap, bheapitem_t *const returnitemstorage) returnitemstorage->owner = NULL; returnitemstorage->heapindex = SIZE_MAX; + if (returnitemstorage->indexchanged != NULL) + { + returnitemstorage->indexchanged(returnitemstorage->data, returnitemstorage->heapindex); + } + heap->count--; heap->array[0] = heap->array[heap->count]; @@ -531,11 +554,11 @@ boolean K_BHeapPop(bheap_t *const heap, bheapitem_t *const returnitemstorage) } /*-------------------------------------------------- - boolean K_UpdateHeapItemValue(bheapitem_t *const item, const UINT32 newvalue) + boolean K_UpdateBHeapItemValue(bheapitem_t *const item, const UINT32 newvalue) See header file for description. --------------------------------------------------*/ -boolean K_UpdateHeapItemValue(bheapitem_t *const item, const UINT32 newvalue) +boolean K_UpdateBHeapItemValue(bheapitem_t *const item, const UINT32 newvalue) { boolean updatevaluesuccess = false; if (item == NULL) @@ -575,3 +598,50 @@ boolean K_UpdateHeapItemValue(bheapitem_t *const item, const UINT32 newvalue) return updatevaluesuccess; } + +/*-------------------------------------------------- + UINT32 K_BHeapContains(bheap_t *const heap, void *const data, size_t index) + + See header file for description. +--------------------------------------------------*/ +UINT32 K_BHeapContains(bheap_t *const heap, void *const data, size_t index) +{ + UINT32 heapindexwithdata = SIZE_MAX; + + if (heap == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL heap in K_BHeapContains.\n"); + } + else if (!K_BHeapValid(heap)) + { + CONS_Debug(DBG_GAMELOGIC, "Uninitialised heap in K_BHeapContains.\n"); + } + else if (data == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL data in K_BHeapContains.\n"); + } + else + { + if ((heap->count != 0U) && (index < heap->count)) + { + if (heap->array[index].data == data) + { + heapindexwithdata = index; + } + } + else if (index == SIZE_MAX) + { + size_t i; + for (i = 0; i < heap->count; i++) + { + if (heap->array[i].data == data) + { + heapindexwithdata = i; + break; + } + } + } + } + + return heapindexwithdata; +} diff --git a/src/k_bheap.h b/src/k_bheap.h index 494a4bd20..d8a4abb50 100644 --- a/src/k_bheap.h +++ b/src/k_bheap.h @@ -3,12 +3,15 @@ #include "doomdef.h" +typedef void(*updateindexfunc)(void *const, const UINT32); + typedef struct bheapitem_s { - size_t heapindex; // The index in the heap this item is - bheap_t *owner; // The heap that owns this item - void *data; // data for this heap item - UINT32 value; // The value of this item, the lowest value item is first in the array + size_t heapindex; // The index in the heap this item is + updateindexfunc indexchanged; // A callback function that is called when this item changes index to alert data + bheap_t *owner; // The heap that owns this item + void *data; // data for this heap item + UINT32 value; // The value of this item, the lowest value item is first in the array } bheapitem_t; typedef struct bheap_s @@ -51,20 +54,21 @@ boolean K_BHeapValid(bheap_t *const heap); /*-------------------------------------------------- - boolean K_BHeapPush(bheap_t *const heap, void *const item, const UINT32 value) + boolean K_BHeapPush(bheap_t *const heap, void *const item, const UINT32 value, updateindexfunc changeindexcallback) Adds a new item to a binary heap. Input Arguments:- - heap - The heap to add to. - item - The item to add to the heap. - value - The value of this item for the heap, lowest is first in the heap + heap - The heap to add to. + item - The item to add to the heap. + value - The value of this item for the heap, lowest is first in the heap + changeindexcallback - A callback function that is called when the item's index changes, can be NULL Return:- True if the push to the heap was successful, false if it wasn't due to invalid parameters --------------------------------------------------*/ -boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value); +boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value, updateindexfunc changeindexcallback); /*-------------------------------------------------- @@ -84,7 +88,7 @@ boolean K_BHeapPop(bheap_t *const heap, bheapitem_t *const returnitemstorage); /*-------------------------------------------------- - boolean K_UpdateHeapItemValue(bheapitem_t *const item, const UINT32 newvalue) + boolean K_UpdateBHeapItemValue(bheapitem_t *const item, const UINT32 newvalue) Updates the heap item's value, and reorders it in the array appropriately. Only works if the item is in a heap validly. If it's a heapitem that is not currently in a heap (ie it's been popped off) just change the value @@ -98,6 +102,24 @@ boolean K_BHeapPop(bheap_t *const heap, bheapitem_t *const returnitemstorage); true if the update was successful, false if it wasn't --------------------------------------------------*/ -boolean K_UpdateHeapItemValue(bheapitem_t *const item, const UINT32 newvalue); +boolean K_UpdateBHeapItemValue(bheapitem_t *const item, const UINT32 newvalue); + + +/*-------------------------------------------------- + boolean K_BHeapContains(bheap_t *const heap, void *const data, size_t index) + + Checks to see if data is contained in the heap. If index is not SIZE_MAX, then only the index sent in is + checked. Otherwise every index is checked linearly. + + Input Arguments:- + heap - The heap to check the contents of + data - The data that is being checked for + index - The index of the heap to check, if SIZE_MAX, check every index + + Return:- + The heap index that contains data, SIZE_MAX if it is not in the heap +--------------------------------------------------*/ + +UINT32 K_BHeapContains(bheap_t *const heap, void *const data, size_t index); #endif