sdlbomber/src/list.c

87 lines
1.7 KiB
C

#include "list.h"
#include "bomber.h"
#include "utils.h"
typedef union genericlistitem genericlistitem;
union genericlistitem {
genericlistitem* next;
listhead list;
bomb b;
flame f;
brickdecay bc;
player p;
bonustile bt;
generic g;
};
/* doesn't use prev link */
static genericlistitem* things = 0;
static genericlistitem* free_things;
static int count_used = 0;
void alloc_things(void) {
int i;
if (!things) {
things = calloc(sizeof(genericlistitem), MAXTHINGS);
} else {
memset(things, 0, sizeof(genericlistitem) * MAXTHINGS);
}
if (!things) nomem("Trying to allocate thing memory");
for (i = 0; i < MAXTHINGS - 1; ++i) { things[i].next = &things[i + 1]; }
things[i].next = 0;
free_things = things;
count_used = 0;
}
void* _allocentry(size_t size) {
genericlistitem* entry = free_things;
if (size > sizeof(genericlistitem)) return 0;
if (free_things) {
count_used++;
free_things = free_things->next;
memset(entry, 0, sizeof(genericlistitem));
}
return entry;
}
void freeentry(void* ptr) {
genericlistitem* entry = ptr;
entry->next = free_things;
free_things = entry;
count_used--;
}
void list_add_tail(listhead* head, listhead* entry) {
entry->next = head;
entry->prev = head->prev;
head->prev->next = entry;
head->prev = entry;
}
void list_del(listhead* entry) {
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
entry->next = entry->prev = entry;
}
void list_init_head(listhead* head) {
head->next = head;
head->prev = head;
}
void things_list_clear(listhead* head) {
genericlistitem* entry;
while (head->next != head) {
entry = container_of(head->next, __typeof__(*entry), list);
list_del(head->next);
freeentry(entry);
}
}