Add callback to heapitem to alert data when the heap index is changed.

Add K_BHeapContains to give an easy way to find if the heap contains data.
This commit is contained in:
Sryder 2019-06-08 22:55:02 +01:00
parent 31d76596c0
commit 3a25bb38fe
2 changed files with 111 additions and 19 deletions

View file

@ -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 // Swap the heap index on each item to be correct
item2->heapindex = item1->heapindex; item2->heapindex = item1->heapindex;
item1->heapindex = tempitemindex; 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. 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; boolean pushsuccess = false;
if (heap == NULL) if (heap == NULL)
@ -455,6 +464,7 @@ boolean K_BHeapPush(bheap_t *const heap, void *const item, UINT32 value)
} }
else else
{ {
bheapitem_t *newitem = NULL;
// If the capacity of the heap has been reached, a realloc is needed // If the capacity of the heap has been reached, a realloc is needed
// I'm just doing a basic double of capacity for simplicity // I'm just doing a basic double of capacity for simplicity
if (heap->count >= heap->capacity) 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->capacity = newarraycapacity;
} }
heap->array[heap->count].heapindex = heap->count; newitem = &heap->array[heap->count];
heap->array[heap->count].owner = heap;
heap->array[heap->count].data = item; newitem->heapindex = heap->count;
heap->array[heap->count].value = value; newitem->owner = heap;
newitem->data = item;
newitem->value = value;
newitem->indexchanged = changeindexcallback;
if (newitem->indexchanged != NULL)
{
newitem->indexchanged(newitem->data, newitem->heapindex);
}
heap->count++; heap->count++;
@ -517,6 +535,11 @@ boolean K_BHeapPop(bheap_t *const heap, bheapitem_t *const returnitemstorage)
returnitemstorage->owner = NULL; returnitemstorage->owner = NULL;
returnitemstorage->heapindex = SIZE_MAX; returnitemstorage->heapindex = SIZE_MAX;
if (returnitemstorage->indexchanged != NULL)
{
returnitemstorage->indexchanged(returnitemstorage->data, returnitemstorage->heapindex);
}
heap->count--; heap->count--;
heap->array[0] = heap->array[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. 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; boolean updatevaluesuccess = false;
if (item == NULL) if (item == NULL)
@ -575,3 +598,50 @@ boolean K_UpdateHeapItemValue(bheapitem_t *const item, const UINT32 newvalue)
return updatevaluesuccess; 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;
}

View file

@ -3,12 +3,15 @@
#include "doomdef.h" #include "doomdef.h"
typedef void(*updateindexfunc)(void *const, const UINT32);
typedef struct bheapitem_s typedef struct bheapitem_s
{ {
size_t heapindex; // The index in the heap this item is size_t heapindex; // The index in the heap this item is
bheap_t *owner; // The heap that owns this item updateindexfunc indexchanged; // A callback function that is called when this item changes index to alert data
void *data; // data for this heap item bheap_t *owner; // The heap that owns this item
UINT32 value; // The value of this item, the lowest value item is first in the array 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; } bheapitem_t;
typedef struct bheap_s 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. Adds a new item to a binary heap.
Input Arguments:- Input Arguments:-
heap - The heap to add to. heap - The heap to add to.
item - The item to add to the heap. item - The item to add to the heap.
value - The value of this item for the heap, lowest is first in 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:- Return:-
True if the push to the heap was successful, false if it wasn't due to invalid parameters 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 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 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 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 #endif