]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/list.c
Optimize MapBlock meshes
[dragonblocks_alpha.git] / src / list.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "list.h"
4
5 bool list_compare_default(void *v1, void *v2)
6 {
7         return v1 == v2;
8 }
9
10 bool list_compare_string(void *v1, void *v2)
11 {
12         return strcmp(v1, v2) == 0;
13 }
14
15 List list_create(ListComparator cmp)
16 {
17         return (List) {
18                 .cmp = cmp ? cmp : list_compare_default,
19                 .first = NULL,
20         };
21 }
22
23 void list_clear(List *list)
24 {
25         list_clear_func(list, NULL, NULL);
26 }
27
28 void list_clear_func(List *list, void (*func)(void *key, void *value, void *arg), void *arg)
29 {
30         for (ListPair *pair = list->first; pair != NULL;) {
31                 ListPair *next = pair->next;
32                 if (func)
33                         func(pair->key, pair->value, arg);
34                 free(pair);
35                 pair = next;
36         }
37         list->first = NULL;
38 }
39
40 static ListPair *make_pair(void *key, void *value)
41 {
42         ListPair *pair = malloc(sizeof(ListPair));
43         pair->key = key;
44         pair->value = value;
45         pair->next = NULL;
46         return pair;
47 }
48
49 bool list_put(List *list, void *key, void *value)
50 {
51         ListPair **pairptr;
52         for (pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) {
53                 if (list->cmp((*pairptr)->key, key))
54                         return false;
55         }
56         *pairptr = make_pair(key, value);
57         return true;
58 }
59
60 void *list_get_cached(List *list, void *key, void *(*provider)(void *key))
61 {
62         ListPair **pairptr;
63         for (pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) {
64                 if (list->cmp((*pairptr)->key, key))
65                         return (*pairptr)->value;
66         }
67         return (*pairptr = make_pair(key, provider(key)))->value;
68 }
69
70 void list_set(List *list, void *key, void *value)
71 {
72         ListPair **pairptr;
73         for (pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) {
74                 if (list->cmp((*pairptr)->key, key))
75                         break;
76         }
77         *pairptr = make_pair(key, value);
78 }
79
80 void *list_delete(List *list, void *key)
81 {
82         for (ListPair **pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) {
83                 if (list->cmp((*pairptr)->key, key)) {
84                         ListPair *pair = *pairptr;
85                         void *value = (*pairptr)->value;
86                         *pairptr = pair->next;
87                         free(pair);
88                         return value;
89                 }
90         }
91         return NULL;
92 }
93
94 void *list_get(List *list, void *key)
95 {
96         for (ListPair *pair = list->first; pair != NULL; pair = pair->next)
97                 if (list->cmp(pair->key, key))
98                         return pair->value;
99         return NULL;
100 }