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
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;
}

View file

@ -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