Browse Source

Update linked list implementation

Use node pointers instead of duplicating the find function logic.
master
TheoryOfNekomata 1 year ago
parent
commit
0fca9b77e3
5 changed files with 18 additions and 22 deletions
  1. +9
    -16
      src/packages/game/data/IZ_list.c
  2. +1
    -1
      src/packages/game/data/IZ_list.h
  3. +3
    -1
      src/packages/game/data/README.md
  4. +4
    -3
      src/packages/game/data/data.test.c
  5. +1
    -1
      src/packages/game/memory/IZ_pool.c

+ 9
- 16
src/packages/game/data/IZ_list.c View File

@@ -1,9 +1,5 @@
#include "IZ_list.h" #include "IZ_list.h"


bool IZ_ListFindFilterAlwaysTrue(IZ_ListNode** _node, u64 _index, IZ_List* _list) {
return true;
}

/** /**
* Initializes a list. * Initializes a list.
* @param list - The list to initialize. * @param list - The list to initialize.
@@ -20,10 +16,9 @@ void IZ_ListInitialize(IZ_List* list) {
*/ */
void IZ_ListTeardown(IZ_List* list) { void IZ_ListTeardown(IZ_List* list) {
while (list->root) { while (list->root) {
IZ_ListDeleteFirstNode(list, IZ_ListFindFilterAlwaysTrue);
IZ_ListDeleteNode(list, &list->root);
} }
list->iterator = NULL;
list->length = 0;
IZ_free(list);
} }


/** /**
@@ -54,30 +49,28 @@ IZ_ListNode** IZ_ListAppendNode(IZ_List* list, void* node_value) {
/** /**
* Deletes the first node in the list that matches the filter. * Deletes the first node in the list that matches the filter.
* @param list - The list to delete from. * @param list - The list to delete from.
* @param filter - The filter to use to find the node to delete.
* @param node - The node to delete.
*/ */
void IZ_ListDeleteFirstNode(IZ_List* list, IZ_ListFindPredicate filter) {
if (!(list && list->root)) {
void IZ_ListDeleteNode(IZ_List* list, IZ_ListNode** node) {
if (!(list && list->root && node)) {
// should we raise warnings here? // should we raise warnings here?
return; return;
} }


// FIXME Teardown having problems here // FIXME Teardown having problems here
list->iterator = &list->root; list->iterator = &list->root;
IZ_ListNode* previous_node = NULL;
u64 index = 0;
IZ_ListNode** previous_node = NULL;
do { do {
if (!filter(list->iterator, index, list)) {
previous_node = *list->iterator;
if (list->iterator != node) {
previous_node = list->iterator;
list->iterator = &((*list->iterator)->next); list->iterator = &((*list->iterator)->next);
index += 1;
// we haven't found the node we're looking for, go to the next one // we haven't found the node we're looking for, go to the next one
continue; continue;
} }


if (previous_node) { if (previous_node) {
// this is not the first node in the list // this is not the first node in the list
previous_node->next = (*list->iterator)->next;
(*previous_node)->next = (*list->iterator)->next;
} else { } else {
// this is the first node, set it as new root // this is the first node, set it as new root
list->root = (*list->iterator)->next; list->root = (*list->iterator)->next;


+ 1
- 1
src/packages/game/data/IZ_list.h View File

@@ -57,7 +57,7 @@ IZ_ListNode** IZ_ListAppendNode(IZ_List*, void*);
/** /**
* Deletes the first node in the list that matches the filter. * Deletes the first node in the list that matches the filter.
*/ */
void IZ_ListDeleteFirstNode(IZ_List*, IZ_ListFindPredicate);
void IZ_ListDeleteNode(IZ_List*, IZ_ListNode**);


/** /**
* Finds the first node in the list that matches the filter. * Finds the first node in the list that matches the filter.


+ 3
- 1
src/packages/game/data/README.md View File

@@ -38,8 +38,10 @@ int main() {
printf("Found node with value 2!\n"); printf("Found node with value 2!\n");
} }
ListNode* delete_node;
delete_node = IZ_ListFindFirstNode(&list, &FindNodeWithValueOne);
// deletions are done only on one node at a time // deletions are done only on one node at a time
IZ_ListDeleteFirstNode(&list, &FindNodeWithValueOne);
IZ_ListDeleteNode(&list, delete_node);
// teardown takes care of de-allocating nodes and making sure data cannot be accessed sensibly anymore. // teardown takes care of de-allocating nodes and making sure data cannot be accessed sensibly anymore.
IZ_ListTeardown(&list); IZ_ListTeardown(&list);


+ 4
- 3
src/packages/game/data/data.test.c View File

@@ -53,7 +53,7 @@ spec("data") {
} }


it("removes all nodes from the list") { it("removes all nodes from the list") {
mock_set_expected_calls(IZ_free, 3);
mock_set_expected_calls(IZ_free, 4);
IZ_ListTeardown(&list); IZ_ListTeardown(&list);
unsigned int expected_calls = mock_get_expected_calls(IZ_free); unsigned int expected_calls = mock_get_expected_calls(IZ_free);
unsigned int actual_calls = mock_get_actual_calls(IZ_free); unsigned int actual_calls = mock_get_actual_calls(IZ_free);
@@ -151,7 +151,7 @@ spec("data") {
} }
} }


describe("DeleteFirstNode") {
describe("DeleteNode") {
static IZ_List list; static IZ_List list;


before_each() { before_each() {
@@ -170,7 +170,8 @@ spec("data") {
} }


it("removes first node satisfying the filter condition") { it("removes first node satisfying the filter condition") {
IZ_ListDeleteFirstNode(&list, NodeExists);
IZ_ListNode** existing_node = IZ_ListFindFirstNode(&list, NodeExists);
IZ_ListDeleteNode(&list, existing_node);


check( check(
mock_is_called(IZ_free), mock_is_called(IZ_free),


+ 1
- 1
src/packages/game/memory/IZ_pool.c View File

@@ -43,7 +43,7 @@ bool IZ_PoolGetSameItem(IZ_ListNode** node, u64 _index, IZ_List* list) {
} }


void IZ_PoolDeallocate(IZ_PoolItem* item) { void IZ_PoolDeallocate(IZ_PoolItem* item) {
IZ_ListDeleteFirstNode(&item->pool->items, IZ_PoolGetSameItem);
IZ_ListDeleteNode(&item->pool->items, IZ_PoolGetSameItem);
} }


void IZ_PoolTeardown(IZ_Pool* pool) { void IZ_PoolTeardown(IZ_Pool* pool) {


Loading…
Cancel
Save