Przeglądaj źródła

Fix list tests

Convert list to doubly-linked list for easy traversal.
master
TheoryOfNekomata 1 rok temu
rodzic
commit
0fda7dd8ba
3 zmienionych plików z 36 dodań i 37 usunięć
  1. +24
    -34
      src/packages/game/data/IZ_list.c
  2. +7
    -2
      src/packages/game/data/IZ_list.h
  3. +5
    -1
      src/packages/game/data/data.test.c

+ 24
- 34
src/packages/game/data/IZ_list.c Wyświetl plik

@@ -15,8 +15,8 @@ void IZ_ListInitialize(IZ_List* list) {
* @param list - The list to clean up.
*/
void IZ_ListTeardown(IZ_List* list) {
while (list->root) {
IZ_ListDeleteNode(list, &list->root);
while (list->length > 0) {
IZ_ListDeleteNode(list->root);
}
IZ_free(list);
}
@@ -30,61 +30,51 @@ IZ_ListNode** IZ_ListAppendNode(IZ_List* list, void* node_value) {
IZ_ListNode* new_node = IZ_malloc(sizeof(IZ_ListNode));
new_node->value = node_value;
new_node->next = NULL;
list->length += 1;
new_node->list = list;
new_node->list->length += 1;

if (!(list->root)) {
list->root = new_node;
return &list->root;
new_node->previous = NULL;
new_node->list->root = new_node;
return &new_node->list->root;
}

IZ_ListNode *last_node = list->root;
IZ_ListNode *last_node = new_node->list->root;
while (last_node->next) {
last_node = last_node->next;
}

new_node->previous = last_node;
last_node->next = new_node;
return &last_node->next;
}

/**
* Deletes the first node in the list that matches the filter.
* @param list - The list to delete from.
* @param node - The node to delete.
*/
void IZ_ListDeleteNode(IZ_List* list, IZ_ListNode** node) {
if (!(list && list->root && node)) {
void IZ_ListDeleteNode(IZ_ListNode* node) {
if (!node) {
// should we raise warnings here?
return;
}

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

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

IZ_free(*list->iterator);
list->iterator = NULL;
if (list->length > 0) {
// avoid underflow
list->length -= 1;
}
return;
} while (*list->iterator);
if (node->list && node->list->length > 0) {
node->list->length -= 1;
}

IZ_free(node);
}

/**


+ 7
- 2
src/packages/game/data/IZ_list.h Wyświetl plik

@@ -4,10 +4,15 @@
#include "../../common/IZ_common.h"
#include "../../stdinc/IZ_stdlib.h"

struct IZ_List;

/**
* A node in a linked list.
*/
typedef struct IZ_ListNode {
struct IZ_List* list;

struct IZ_ListNode* previous;
/**
* The value of the node.
*/
@@ -21,7 +26,7 @@ typedef struct IZ_ListNode {
/**
* A singly-linked list.
*/
typedef struct {
typedef struct IZ_List {
/**
* The first node in the list.
*/
@@ -57,7 +62,7 @@ IZ_ListNode** IZ_ListAppendNode(IZ_List*, void*);
/**
* Deletes the first node in the list that matches the filter.
*/
void IZ_ListDeleteNode(IZ_List*, IZ_ListNode**);
void IZ_ListDeleteNode(IZ_ListNode*);

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


+ 5
- 1
src/packages/game/data/data.test.c Wyświetl plik

@@ -22,6 +22,7 @@ spec("data") {

after_each() {
IZ_ListTeardown(&list);
mock_reset(IZ_free);
}

it("sets root to NULL") {
@@ -77,10 +78,13 @@ spec("data") {
IZ_ListInitialize(&list2);
static u64 existing_value = 69420u;
static IZ_ListNode existing_node = {
.list = NULL,
.previous = NULL,
.value = &existing_value,
.next = NULL,
};
list2.root = &existing_node;
existing_node.list = &list2;
list2.length = 1;
}

@@ -171,7 +175,7 @@ spec("data") {

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

check(
mock_is_called(IZ_free),


Ładowanie…
Anuluj
Zapisz