Gama C Library
Gama C API Documentation
Loading...
Searching...
No Matches
body_list.h
Go to the documentation of this file.
1/**
2 * @file body_list.h
3 * @brief Provides a dynamic, NULL-terminated pointer list implementation.
4 *
5 * This file contains a generic pointer list (`gmPtrList`) and a specialized
6 * version for physics bodies (`gmBodies`). The lists automatically resize and
7 * are always NULL-terminated, making them easy to iterate.
8 *
9 * @note The functions in this file that return a new list (e.g., push, pop)
10 * allocate new memory. It is the caller's responsibility to free the
11 * original list pointer to prevent memory leaks.
12 */
13#pragma once
14
15#include "body.h"
16#include <stdlib.h>
17
18// ---------------------------------------------------------------------------
19// --------------------------- Generic Pointer List --------------------------
20// ---------------------------------------------------------------------------
21
22/**
23 * @brief A dynamic, NULL-terminated array of generic pointers.
24 */
25typedef void **gmPtrList;
26
27/**
28 * @brief Calculates the number of elements in a pointer list.
29 * @param list The NULL-terminated pointer list.
30 * @return The number of elements, excluding the NULL terminator.
31 */
33 if (list == NULL)
34 return 0;
35 size_t i = 0;
36 while (list[i] != NULL)
37 i++;
38 return i;
39}
40
41/**
42 * @brief Checks if a pointer list is empty.
43 * @param list The list to check.
44 * @return 1 if the list is NULL or has zero length, 0 otherwise.
45 */
47 return list == NULL || list[0] == NULL;
48}
49
50/**
51 * @brief Counts the occurrences of a specific pointer in the list.
52 * @param list The list to search.
53 * @param obj The pointer to count.
54 * @return The number of times `obj` appears in the list.
55 */
56size_t gm_ptr_list_count(gmPtrList list, void *obj) {
57 if (list == NULL)
58 return 0;
59 size_t count = 0;
60 for (size_t i = 0; list[i] != NULL; i++) {
61 if (list[i] == obj)
62 count++;
63 }
64 return count;
65}
66
67/**
68 * @brief Adds a pointer to the end of the list.
69 * @param list The list to append to.
70 * @param obj The pointer to add.
71 * @return A new pointer to the resized list. The original list should be freed.
72 */
74 size_t length = gm_ptr_list_length(list);
75 gmPtrList new_list = realloc(list, (length + 2) * sizeof(void *));
76 new_list[length] = obj;
77 new_list[length + 1] = NULL;
78 return new_list;
79}
80
81/**
82 * @brief Removes the last element from the list.
83 * @param list The list to modify.
84 * @return A new pointer to the resized list. The original list should be freed.
85 */
87 size_t len = gm_ptr_list_length(list);
88 if (len == 0)
89 return list;
90 gmPtrList new_list = realloc(list, len * sizeof(void *));
91 new_list[len - 1] = NULL;
92 return new_list;
93}
94
95/**
96 * @brief Removes all occurrences of a specific pointer from the list.
97 * @param list The list to modify.
98 * @param obj The pointer to remove.
99 * @return A new pointer to the resized list. The original list should be freed.
100 */
102 size_t len = gm_ptr_list_length(list);
103 size_t count = gm_ptr_list_count(list, obj);
104 if (count == 0)
105 return list;
106
107 gmPtrList new_list = malloc((len - count + 1) * sizeof(void *));
108 size_t index = 0;
109 for (size_t i = 0; i < len; i++) {
110 if (list[i] != obj) {
111 new_list[index++] = list[i];
112 }
113 }
114 new_list[index] = NULL;
115 free(list);
116 return new_list;
117}
118
119/**
120 * @brief Removes an element at a specific index.
121 * @param list The list to modify.
122 * @param idx The index of the element to remove.
123 * @return A new pointer to the resized list. The original list should be freed.
124 */
126 size_t len = gm_ptr_list_length(list);
127 if (idx >= len)
128 return list;
129
130 gmPtrList new_list = malloc(len * sizeof(void *));
131 size_t new_idx = 0;
132 for (size_t i = 0; i < len; i++) {
133 if (i != idx) {
134 new_list[new_idx++] = list[i];
135 }
136 }
137 new_list[new_idx] = NULL;
138 free(list);
139 return new_list;
140}
141
142/**
143 * @brief Inserts a pointer at a specific index.
144 * @param list The list to modify.
145 * @param idx The index at which to insert the value.
146 * @param value The pointer to insert.
147 * @return A new pointer to the resized list. The original list should be freed.
148 */
149gmPtrList gm_ptr_list_insert_at(gmPtrList list, size_t idx, void *value) {
150 size_t len = gm_ptr_list_length(list);
151 if (idx > len)
152 idx = len;
153
154 gmPtrList new_list = malloc((len + 2) * sizeof(void *));
155 for (size_t i = 0; i < idx; i++) {
156 new_list[i] = list[i];
157 }
158 new_list[idx] = value;
159 for (size_t i = idx; i < len; i++) {
160 new_list[i + 1] = list[i];
161 }
162 new_list[len + 1] = NULL;
163 free(list);
164 return new_list;
165}
166
167/**
168 * @brief Finds the index of a specific pointer.
169 * @param list The list to search.
170 * @param value The pointer to find.
171 * @return The index of the first occurrence of the value, or -1 if not found.
172 */
173int gm_ptr_list_find(gmPtrList list, void *value) {
174 if (list == NULL)
175 return -1;
176 for (size_t i = 0; list[i] != NULL; i++) {
177 if (list[i] == value)
178 return i;
179 }
180 return -1;
181}
182
183/**
184 * @brief Retrieves the element at a specific index.
185 * @param list The list.
186 * @param index The index of the element to retrieve.
187 * @return The pointer at the specified index, or NULL if the index is out of
188 * bounds.
189 */
190void *gm_ptr_list_get(gmPtrList list, size_t index) {
191 if (list == NULL || index >= gm_ptr_list_length(list)) {
192 return NULL;
193 }
194 return list[index];
195}
196
197/**
198 * @brief Retrieves the last element of the list.
199 * @param list The list.
200 * @return The last pointer in the list, or NULL if the list is empty.
201 */
203 if (gm_ptr_list_is_empty(list))
204 return NULL;
205 return list[gm_ptr_list_length(list) - 1];
206}
207
208/**
209 * @brief Frees the memory used by the list.
210 * @param list The list to clear.
211 */
213 if (list != NULL) {
214 free(list);
215 }
216}
217
218/**
219 * @brief A macro for iterating over a gmPtrList.
220 * @param item The variable to hold the current item (e.g., `gmBody* item`).
221 * @param list The gmPtrList to iterate over.
222 */
223#define gm_ptr_list_for_each(item, list) \
224 for (size_t i = 0; (list != NULL) && (item = list[i]) != NULL; i++)
225
226// ---------------------------------------------------------------------------
227// ---------------------------- Body List Wrapper ----------------------------
228// ---------------------------------------------------------------------------
229
230/**
231 * @brief A specialized pointer list for `gmBody` pointers.
232 */
233typedef gmBody **gmBodies;
234
235static inline size_t gm_bodies_length(gmBodies list) {
236 return gm_ptr_list_length((gmPtrList)list);
237}
238static inline int gm_bodies_is_empty(gmBodies list) {
239 return gm_ptr_list_is_empty((gmPtrList)list);
240}
241static inline size_t gm_bodies_count(gmBodies list, gmBody *obj) {
242 return gm_ptr_list_count((gmPtrList)list, obj);
243}
244static inline gmBodies gm_bodies_push(gmBodies list, gmBody *obj) {
245 return (gmBodies)gm_ptr_list_push((gmPtrList)list, obj);
246}
247static inline gmBodies gm_bodies_pop(gmBodies list) {
248 return (gmBodies)gm_ptr_list_pop((gmPtrList)list);
249}
250static inline gmBodies gm_bodies_remove(gmBodies list, gmBody *obj) {
251 return (gmBodies)gm_ptr_list_remove((gmPtrList)list, obj);
252}
253static inline gmBodies gm_bodies_pop_at(gmBodies list, size_t idx) {
254 return (gmBodies)gm_ptr_list_pop_at((gmPtrList)list, idx);
255}
256static inline gmBodies gm_bodies_insert_at(gmBodies list, size_t idx,
257 gmBody *value) {
258 return (gmBodies)gm_ptr_list_insert_at((gmPtrList)list, idx, value);
259}
260static inline int gm_bodies_find(gmBodies list, gmBody *value) {
261 return gm_ptr_list_find((gmPtrList)list, value);
262}
263static inline gmBody *gm_bodies_get(gmBodies list, size_t index) {
264 return (gmBody *)gm_ptr_list_get((gmPtrList)list, index);
265}
266static inline gmBody *gm_bodies_last(gmBodies list) {
267 return (gmBody *)gm_ptr_list_last((gmPtrList)list);
268}
269static inline void gm_bodies_clear(gmBodies list) {
271}
272
273/**
274 * @brief A macro for iterating over a gmBodies list.
275 * @param item A `gmBody*` variable to hold the current item.
276 * @param list The gmBodies list to iterate over.
277 */
278#define gm_bodies_for_each(item, list) \
279 for (size_t i = 0; (list != NULL) && (item = list[i]) != NULL; i++)
gmPtrList gm_ptr_list_pop_at(gmPtrList list, size_t idx)
Removes an element at a specific index.
Definition body_list.h:125
gmPtrList gm_ptr_list_insert_at(gmPtrList list, size_t idx, void *value)
Inserts a pointer at a specific index.
Definition body_list.h:149
void * gm_ptr_list_last(gmPtrList list)
Retrieves the last element of the list.
Definition body_list.h:202
gmPtrList gm_ptr_list_push(gmPtrList list, void *obj)
Adds a pointer to the end of the list.
Definition body_list.h:73
void ** gmPtrList
A dynamic, NULL-terminated array of generic pointers.
Definition body_list.h:25
size_t gm_ptr_list_length(gmPtrList list)
Calculates the number of elements in a pointer list.
Definition body_list.h:32
gmPtrList gm_ptr_list_pop(gmPtrList list)
Removes the last element from the list.
Definition body_list.h:86
void gm_ptr_list_clear(gmPtrList list)
Frees the memory used by the list.
Definition body_list.h:212
gmPtrList gm_ptr_list_remove(gmPtrList list, void *obj)
Removes all occurrences of a specific pointer from the list.
Definition body_list.h:101
int gm_ptr_list_is_empty(gmPtrList list)
Checks if a pointer list is empty.
Definition body_list.h:46
gmBody ** gmBodies
A specialized pointer list for gmBody pointers.
Definition body_list.h:233
int gm_ptr_list_find(gmPtrList list, void *value)
Finds the index of a specific pointer.
Definition body_list.h:173
size_t gm_ptr_list_count(gmPtrList list, void *obj)
Counts the occurrences of a specific pointer in the list.
Definition body_list.h:56
void * gm_ptr_list_get(gmPtrList list, size_t index)
Retrieves the element at a specific index.
Definition body_list.h:190
Structure representing a physics body with properties for collision and movement.
Definition body.h:19