make the list api require less insane casts all over the place

by sealing the spirit of insanity in its header file, that is
This commit is contained in:
Andrei Alexeyev 2017-12-24 08:16:25 +02:00
parent ab0cccd5f6
commit e355e57fb5
No known key found for this signature in database
GPG key ID: 363707CD4C7FE8A4
22 changed files with 134 additions and 99 deletions

View file

@ -45,21 +45,22 @@ void aniplayer_free_copy(AniPlayer *ani) {
void aniplayer_free(AniPlayer *plr) {
plr->queuesize = 0; // prevent aniplayer_reset from messing with the queue, since we're going to wipe all of it anyway
list_free_all((List**)&plr->queue);
list_free_all(&plr->queue);
aniplayer_reset(plr);
}
void aniplayer_reset(AniPlayer *plr) { // resets to a neutral state with empty queue.
plr->stdrow = 0;
if(plr->queuesize > 0) { // abort the animation in the fastest fluent way.
list_free_all((List**)&plr->queue->next);
list_free_all(&plr->queue->next);
plr->queuesize = 1;
plr->queue->delay = 0;
}
}
AniSequence *aniplayer_queue(AniPlayer *plr, int row, int loops, int delay) {
AniSequence *s = (AniSequence*)list_append((List**)&plr->queue, calloc(1, sizeof(AniSequence)));
AniSequence *s = calloc(1, sizeof(AniSequence));
list_append(&plr->queue, s);
plr->queuesize++;
s->row = row;
@ -94,7 +95,7 @@ void aniplayer_update(AniPlayer *plr) {
} else if(s->delay > 0) {
s->delay--;
} else {
free(list_pop((List**)&plr->queue));
free(list_pop(&plr->queue));
plr->queuesize--;
plr->clock = 0;
}

View file

@ -16,11 +16,11 @@
#include "resource/animation.h"
#include "stageobjects.h"
#include "list.h"
typedef struct AniSequence AniSequence;
struct AniSequence{
struct AniSequence *next;
struct AniSequence *prev;
LIST_INTERFACE(AniSequence);
int row;
int duration; // number of frames this sequence will be drawn

View file

@ -22,7 +22,7 @@ static Hashtable *bgm_descriptions;
static Hashtable *sfx_volumes;
static struct enqueued_sound {
List chain;
LIST_INTERFACE(struct enqueued_sound);
char *name;
int time;
int cooldown;
@ -31,11 +31,12 @@ static struct enqueued_sound {
static void play_sound_internal(const char *name, bool is_ui, int cooldown, bool replace, int delay) {
if(delay > 0) {
struct enqueued_sound *s = (struct enqueued_sound*)list_push((List**)&sound_queue, malloc(sizeof(struct enqueued_sound)));
struct enqueued_sound *s = malloc(sizeof(struct enqueued_sound));
s->time = global.frames + delay;
s->name = strdup(name);
s->cooldown = cooldown;
s->replace = replace;
list_push(&sound_queue, s);
return;
}
@ -62,11 +63,10 @@ static void* discard_enqueued_sound(List **queue, List *vsnd, void *arg) {
return NULL;
}
static void* play_enqueued_sound(List **queue, List *vsnd, void *arg) {
struct enqueued_sound *snd = (struct enqueued_sound*)vsnd;
static void* play_enqueued_sound(struct enqueued_sound **queue, struct enqueued_sound *snd, void *arg) {
play_sound_internal(snd->name, false, snd->cooldown, snd->replace, 0);
free(snd->name);
free(list_unlink(queue, vsnd));
free(list_unlink(queue, snd));
return NULL;
}
@ -115,7 +115,7 @@ void reset_sounds(void) {
}
}
list_foreach((List**)&sound_queue, discard_enqueued_sound, NULL);
list_foreach(&sound_queue, discard_enqueued_sound, NULL);
}
void update_sounds(void) {
@ -130,10 +130,10 @@ void update_sounds(void) {
}
for(struct enqueued_sound *s = sound_queue, *next; s; s = next) {
next = (struct enqueued_sound*)s->chain.next;
next = (struct enqueued_sound*)s->next;
if(s->time <= global.frames) {
play_enqueued_sound((List**)&sound_queue, (List*)s, NULL);
play_enqueued_sound(&sound_queue, s, NULL);
}
}
}

View file

@ -15,7 +15,7 @@
#define PRAGMA(p)
#else
#define PRAGMA(p) _Pragma(#p)
#define USE_GNU_EXTENSIONS
// #define USE_GNU_EXTENSIONS
#endif
#ifdef __MINGW_PRINTF_FORMAT

View file

@ -36,8 +36,7 @@ CONFIGDEFS_EXPORT ConfigEntry configdefs[] = {
};
typedef struct ConfigEntryList {
struct ConfigEntryList *next;
struct ConfigEntryList *prev;
LIST_INTERFACE(struct ConfigEntryList);
ConfigEntry entry;
} ConfigEntryList;
@ -241,11 +240,12 @@ static ConfigEntry* config_get_unknown_entry(const char *name) {
}
}
l = (ConfigEntryList*)list_push((List**)&unknowndefs, malloc(sizeof(ConfigEntryList)));
l = malloc(sizeof(ConfigEntryList));
e = &l->entry;
memset(e, 0, sizeof(ConfigEntry));
stralloc(&e->name, name);
e->type = CONFIG_TYPE_STRING;
list_push(&unknowndefs, l);
return e;
}
@ -265,7 +265,7 @@ static void* config_delete_unknown_entry(List **list, List *lentry, void *arg) {
}
static void config_delete_unknown_entries(void) {
list_foreach((List**)&unknowndefs, config_delete_unknown_entry, NULL);
list_foreach(&unknowndefs, config_delete_unknown_entry, NULL);
}
void config_save(void) {

View file

@ -36,7 +36,7 @@ Enemy *create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyVisualRule visu
}
// XXX: some code relies on the insertion logic
Enemy *e = (Enemy*)list_insert((List**)enemies, (List*)objpool_acquire(stage_object_pools.enemies));
Enemy *e = (Enemy*)list_insert(enemies, objpool_acquire(stage_object_pools.enemies));
e->moving = false;
e->dir = 0;
@ -90,7 +90,7 @@ void delete_enemy(Enemy **enemies, Enemy* enemy) {
}
void delete_enemies(Enemy **enemies) {
list_foreach((List**)enemies, _delete_enemy, NULL);
list_foreach(enemies, _delete_enemy, NULL);
}
static void draw_enemy(Enemy *e) {

View file

@ -147,7 +147,7 @@ static bool events_invoke_handlers(SDL_Event *event, ListContainer *h_list, Even
}
}
list_free_all((List**)&merged_list);
list_free_all(&merged_list);
return result;
}
@ -178,8 +178,8 @@ void events_register_handler(EventHandler *handler) {
assert(handler_alloc->priority > EPRIO_DEFAULT);
list_insert_at_priority(
(List**)&global_handlers,
(List*)list_wrap_container(handler_alloc),
&global_handlers,
list_wrap_container(handler_alloc),
handler_alloc->priority,
handler_container_prio_func
);

View file

@ -20,8 +20,7 @@
// #define HT_USE_MUTEX
typedef struct HashtableElement {
void *next;
void *prev;
LIST_INTERFACE(struct HashtableElement);
void *data;
void *key;
hash_t hash;
@ -165,7 +164,7 @@ static void* hashtable_delete_callback(List **vlist, List *velem, void *vht) {
static void hashtable_unset_all_internal(Hashtable *ht) {
for(size_t i = 0; i < ht->table_size; ++i) {
list_foreach((List**)(ht->table + i), hashtable_delete_callback, ht);
list_foreach((ht->table + i), hashtable_delete_callback, ht);
}
ht->num_elements = 0;
@ -236,7 +235,7 @@ static bool hashtable_set_internal(Hashtable *ht, HashtableElement **table, size
ht->free_func(e->key);
}
free(list_unlink((List**)&elems, (List*)e));
free(list_unlink(&elems, e));
ht->num_elements--;
if(elems) {
@ -255,10 +254,11 @@ static bool hashtable_set_internal(Hashtable *ht, HashtableElement **table, size
collisions_updated = !collisions_updated;
}
elem = (HashtableElement*)list_push((List**)&elems, malloc(sizeof(HashtableElement)));
elem = malloc(sizeof(HashtableElement));
ht->copy_func(&elem->key, key);
elem->hash = ht->hash_func(elem->key);
elem->data = data;
list_push(&elems, elem);
ht->num_elements++;
}
@ -362,7 +362,7 @@ void hashtable_unset(Hashtable *ht, void *key) {
void hashtable_unset_deferred(Hashtable *ht, void *key, ListContainer **list) {
assert(ht != NULL);
ListContainer *c = (ListContainer*)list_push(list, list_wrap_container(NULL));
ListContainer *c = list_push(list, list_wrap_container(NULL));
ht->copy_func(&c->data, key);
}

View file

@ -35,10 +35,6 @@ static int item_prio(List *litem) {
return item->type;
}
static void* alloc_item(void) {
return objpool_acquire(stage_object_pools.items);
}
Item* create_item(complex pos, complex v, ItemType type) {
if((creal(pos) < 0 || creal(pos) > VIEWPORT_W)) {
// we need this because we clamp the item position to the viewport boundary during motion
@ -46,7 +42,9 @@ Item* create_item(complex pos, complex v, ItemType type) {
return NULL;
}
Item *i = (Item*)list_insert_at_priority((List**)&global.items, alloc_item(), type, item_prio);
Item *i = (Item*)objpool_acquire(stage_object_pools.items);
list_insert_at_priority(&global.items, i, type, item_prio);
i->pos = pos;
i->pos0 = pos;
i->v = v;
@ -58,7 +56,7 @@ Item* create_item(complex pos, complex v, ItemType type) {
}
void delete_item(Item *item) {
objpool_release(stage_object_pools.items, (ObjectInterface*)list_unlink((List**)&global.items, (List*)item));
objpool_release(stage_object_pools.items, (ObjectInterface*)list_unlink(&global.items, item));
}
Item* create_bpoint(complex pos) {

View file

@ -14,7 +14,7 @@
#include "stageobjects.h"
Laser *create_laser(complex pos, float time, float deathtime, Color color, LaserPosRule prule, LaserLogicRule lrule, complex a0, complex a1, complex a2, complex a3) {
Laser *l = (Laser*)list_push((List**)&global.lasers, (List*)objpool_acquire(stage_object_pools.lasers));
Laser *l = (Laser*)list_push(&global.lasers, objpool_acquire(stage_object_pools.lasers));
l->birthtime = global.frames;
l->timespan = time;
@ -185,7 +185,7 @@ void delete_laser(Laser **lasers, Laser *laser) {
}
void delete_lasers(void) {
list_foreach((List**)&global.lasers, _delete_laser, NULL);
list_foreach(&global.lasers, _delete_laser, NULL);
}
void process_lasers(void) {

View file

@ -9,24 +9,32 @@
#pragma once
#include "taisei.h"
typedef struct ListInterface ListInterface;
typedef struct List List;
typedef struct ListContainer ListContainer;
#define LIST_INTERFACE_BASE(typename) struct { \
typename *next; \
typename *prev; \
}
#define LIST_INTERFACE(typename) union { \
List list_interface; \
ListInterface list_interface; \
LIST_INTERFACE_BASE(typename); \
}
typedef struct List {
LIST_INTERFACE_BASE(struct List);
} List;
struct ListInterface {
LIST_INTERFACE_BASE(ListInterface);
};
typedef struct ListContainer {
LIST_INTERFACE(struct ListContainer);
struct List {
LIST_INTERFACE(List);
};
struct ListContainer {
LIST_INTERFACE(ListContainer);
void *data;
} ListContainer;
};
typedef void* (*ListForeachCallback)(List **head, List *elem, void *arg);
typedef int (*ListPriorityFunc)(List *elem);
@ -47,19 +55,45 @@ ListContainer* list_wrap_container(void *data);
#ifndef LIST_NO_MACROS
#define LIST_CAST(expr,ptrlevel) (_Generic((expr), \
ListContainer ptrlevel: (List ptrlevel)(expr), \
void ptrlevel: (List ptrlevel)(expr), \
List ptrlevel: (expr) \
))
#ifdef USE_GNU_EXTENSIONS
// thorough safeguard
#define LIST_CAST(expr,ptrlevel) (__extension__({ \
static_assert(__builtin_types_compatible_p(ListInterface, __typeof__((ptrlevel (expr)).list_interface)), \
"struct must implement ListInterface (use the LIST_INTERFACE macro)"); \
static_assert(__builtin_offsetof(__typeof__(ptrlevel (expr)), list_interface) == 0, \
"list_interface must be the first member in struct"); \
(List ptrlevel)(expr); \
}))
#define LIST_CAST_RETURN(expr) (__typeof__(expr))
#else
// basic safeguard
#define LIST_CAST(expr,ptrlevel) ((void)sizeof((ptrlevel (expr)).list_interface), (List ptrlevel)(expr))
// don't even think about adding a void* cast here
#define LIST_CAST_RETURN(expr)
#endif
#define list_insert(dest,elem) list_insert(LIST_CAST(dest, **), LIST_CAST(elem, *))
#define list_push(dest,elem) list_push(LIST_CAST(dest, **), LIST_CAST(elem, *))
#define list_append(dest,elem) list_append(LIST_CAST(dest, **), LIST_CAST(elem, *))
#define list_insert_at_priority(dest,elem,prio,prio_func) list_insert_at_priority(LIST_CAST(dest, **), LIST_CAST(elem, *), prio, prio_func)
#define list_pop(dest) list_pop(LIST_CAST(dest, **))
#define list_unlink(dest,elem) list_unlink(LIST_CAST(dest, **), LIST_CAST(elem, *))
#define list_foreach(dest,callback,arg) list_foreach(LIST_CAST(dest, **), callback, arg)
#define list_free_all(dest) list_free_all(LIST_CAST(dest, **))
#define list_insert(dest,elem) \
(LIST_CAST_RETURN(elem) list_insert(LIST_CAST(dest, **), LIST_CAST(elem, *)))
#define list_push(dest,elem) \
(LIST_CAST_RETURN(elem) list_push(LIST_CAST(dest, **), LIST_CAST(elem, *)))
#define list_append(dest,elem) \
(LIST_CAST_RETURN(elem) list_append(LIST_CAST(dest, **), LIST_CAST(elem, *)))
#define list_insert_at_priority(dest,elem,prio,prio_func) \
(LIST_CAST_RETURN(elem) list_insert_at_priority(LIST_CAST(dest, **), LIST_CAST(elem, *), prio, prio_func))
#define list_pop(dest) \
(LIST_CAST_RETURN(*(dest)) list_pop(LIST_CAST(dest, **)))
#define list_unlink(dest,elem) \
(LIST_CAST_RETURN(elem) list_unlink(LIST_CAST(dest, **), LIST_CAST(elem, *)))
#define list_foreach(dest,callback,arg) \
list_foreach(LIST_CAST(dest, **), callback, arg)
#define list_free_all(dest) \
list_free_all(LIST_CAST(dest, **))
#endif // LIST_NO_MACROS

View file

@ -26,8 +26,8 @@
#endif
typedef struct Logger {
struct Logger *next;
struct Logger *prev;
LIST_INTERFACE(struct Logger);
SDL_RWops *out;
unsigned int levels;
} Logger;
@ -205,7 +205,7 @@ void log_init(LogLevel lvls, LogLevel backtrace_lvls) {
}
void log_shutdown(void) {
list_foreach((List**)&loggers, delete_logger, NULL);
list_foreach(&loggers, delete_logger, NULL);
SDL_DestroyMutex(log_mutex);
log_mutex = NULL;
}
@ -224,9 +224,10 @@ void log_add_output(LogLevel levels, SDL_RWops *output) {
return;
}
Logger *l = (Logger*)list_append((List**)&loggers, malloc(sizeof(Logger)));
Logger *l = malloc(sizeof(Logger));
l->levels = levels;
l->out = output;
list_append(&loggers, l);
}
static LogLevel chr2lvl(char c) {

View file

@ -30,7 +30,7 @@ static inline ObjectInterface* obj_ptr(ObjectPool *pool, char *objects, size_t i
static void objpool_register_objects(ObjectPool *pool, char *objects) {
for(size_t i = 0; i < pool->max_objects; ++i) {
list_push((List**)&pool->free_objects, (List*)obj_ptr(pool, objects, i));
list_push(&pool->free_objects, obj_ptr(pool, objects, i));
}
}
@ -90,7 +90,7 @@ static char* objpool_fmt_size(ObjectPool *pool) {
}
ObjectInterface *objpool_acquire(ObjectPool *pool) {
ObjectInterface *obj = (ObjectInterface*)list_pop((List**)&pool->free_objects);
ObjectInterface *obj = list_pop(&pool->free_objects);
if(obj) {
acquired:
@ -116,7 +116,7 @@ acquired:
free(tmp);
objpool_add_extent(pool);
obj = (ObjectInterface*)list_pop((List**)&pool->free_objects);
obj = list_pop(&pool->free_objects);
assert(obj != NULL);
goto acquired;
}
@ -135,7 +135,7 @@ void objpool_release(ObjectPool *pool, ObjectInterface *object) {
object->_object_private.used = false;
})
list_push((List**)&pool->free_objects, (List*)object);
list_push(&pool->free_objects, object);
pool->usage--;
// log_debug("[%s] Usage: %zu", pool->tag, pool->usage);

View file

@ -83,8 +83,8 @@ static uint32_t progress_checksum(uint8_t *buf, size_t num) {
}
typedef struct UnknownCmd {
struct UnknownCmd *next;
struct UnknownCmd *prev;
LIST_INTERFACE(struct UnknownCmd);
uint8_t cmd;
uint16_t size;
uint8_t *data;
@ -250,11 +250,12 @@ static void progress_read(SDL_RWops *file) {
default:
log_warn("Unknown command %x (%u bytes). Will preserve as-is and not interpret", cmd, cmdsize);
UnknownCmd *c = (UnknownCmd*)list_append((List**)&progress.unknown, malloc(sizeof(UnknownCmd)));
UnknownCmd *c = malloc(sizeof(UnknownCmd));
c->cmd = cmd;
c->size = cmdsize;
c->data = malloc(cmdsize);
SDL_RWread(vfile, c->data, c->size, 1);
list_append(&progress.unknown, c);
break;
}
@ -419,8 +420,7 @@ static void progress_write_cmd_hiscore(SDL_RWops *vfile, void **arg) {
//
struct cmd_stage_playinfo_data_elem {
struct cmd_stage_playinfo_data_elem *next;
struct cmd_stage_playinfo_data_elem *prev;
LIST_INTERFACE(struct cmd_stage_playinfo_data_elem);
uint16_t stage;
uint8_t diff;
uint32_t num_played;
@ -450,18 +450,14 @@ static void progress_prepare_cmd_stage_playinfo(size_t *bufsize, void **arg) {
StageProgress *p = stage_get_progress_from_info(stg, d, false);
if(p && (p->num_played || p->num_cleared)) {
struct cmd_stage_playinfo_data_elem *e = (
(struct cmd_stage_playinfo_data_elem*)
list_push(
(List**)&data->elems,
malloc(sizeof(struct cmd_stage_playinfo_data_elem))
)
);
struct cmd_stage_playinfo_data_elem *e = malloc(sizeof(struct cmd_stage_playinfo_data_elem));
e->stage = stg->id; data->size += sizeof(uint16_t);
e->diff = d; data->size += sizeof(uint8_t);
e->num_played = p->num_played; data->size += sizeof(uint32_t);
e->num_cleared = p->num_cleared; data->size += sizeof(uint32_t);
list_push(&data->elems, e);
}
}
}
@ -491,7 +487,7 @@ static void progress_write_cmd_stage_playinfo(SDL_RWops *vfile, void **arg) {
}
cleanup:
list_free_all((List**)&data->elems);
list_free_all(&data->elems);
free(data);
}
@ -711,5 +707,5 @@ static void* delete_unknown_cmd(List **dest, List *elem, void *arg) {
}
void progress_unload(void) {
list_foreach((void**)&progress.unknown, delete_unknown_cmd, NULL);
list_foreach(&progress.unknown, delete_unknown_cmd, NULL);
}

View file

@ -173,7 +173,7 @@ void delete_projectile(Projectile **projs, Projectile *proj) {
}
void delete_projectiles(Projectile **projs) {
list_foreach((List**)projs, _delete_projectile, NULL);
list_foreach(projs, _delete_projectile, NULL);
}
int collision_projectile(Projectile *p) {

View file

@ -97,7 +97,7 @@ static void free_cache_entry(CacheEntry *e) {
CACHELOG("Wiping cache entry %p [%s]", (void*)e, e->owner.ht_key);
free(e->owner.ht_key);
list_unlink((List**)&cache_entries, (List*)e);
list_unlink(&cache_entries, e);
objpool_release(cache_pool, (ObjectInterface*)e);
}
@ -119,7 +119,7 @@ static CacheEntry* get_cache_entry(Font *font, const char *text) {
}
e = (CacheEntry*)objpool_acquire(cache_pool);
list_push((List**)&cache_entries, (List*)e);
list_push(&cache_entries, e);
hashtable_set_string(font->cache, text, e);
e->owner.ht = font->cache;
e->owner.ht_key = strdup(text);

View file

@ -38,9 +38,10 @@ static void postprocess_load_callback(const char *key, const char *value, void *
PostprocessShader *current = *slist;
if(!strcmp(key, "@shader")) {
current = (PostprocessShader*)list_append((List**)slist, malloc(sizeof(PostprocessShader)));
current = malloc(sizeof(PostprocessShader));
current->uniforms = NULL;
current->shader = get_resource(RES_SHADER, value, ldata->resflags)->shader;
list_append(slist, current);
log_debug("Shader added: %s (prog: %u)", value, current->shader->prog);
return;
}
@ -104,13 +105,14 @@ static void postprocess_load_callback(const char *key, const char *value, void *
}
}
PostprocessShaderUniform *uni = (PostprocessShaderUniform*)list_append((List**)&current->uniforms, malloc(sizeof(PostprocessShaderUniform)));
PostprocessShaderUniform *uni = malloc(sizeof(PostprocessShaderUniform));
uni->loc = uniloc(current->shader, name);
uni->type = utype;
uni->size = usize;
uni->amount = asize;
uni->values.v = vbuf.v;
uni->func = get_uniform_func(utype, usize);
list_append(&current->uniforms, uni);
log_debug("Uniform added: (name: %s; loc: %i; prog: %u; type: %i; size: %i; num: %i)", name, uni->loc, current->shader->prog, uni->type, uni->size, uni->amount);
@ -138,13 +140,13 @@ static void* delete_uniform(List **dest, List *data, void *arg) {
static void* delete_shader(List **dest, List *data, void *arg) {
PostprocessShader *ps = (PostprocessShader*)data;
list_foreach((List**)&ps->uniforms, delete_uniform, NULL);
list_foreach(&ps->uniforms, delete_uniform, NULL);
free(list_unlink(dest, data));
return NULL;
}
void postprocess_unload(PostprocessShader **list) {
list_foreach((List**)list, delete_shader, NULL);
list_foreach(list, delete_shader, NULL);
}
void postprocess(PostprocessShader *ppshaders, FBO **primfbo, FBO **auxfbo, PostprocessPrepareFuncPtr prepare, PostprocessDrawFuncPtr draw) {

View file

@ -18,8 +18,8 @@ typedef struct PostprocessShader PostprocessShader;
typedef struct PostprocessShaderUniform PostprocessShaderUniform;
struct PostprocessShader {
PostprocessShader *next;
PostprocessShader *prev;
LIST_INTERFACE(PostprocessShader);
PostprocessShaderUniform *uniforms;
Shader *shader;
};
@ -40,11 +40,12 @@ typedef union PostprocessShaderUniformValue {
typedef void (APIENTRY *PostprocessShaderUniformFuncPtr)(GLint, GLsizei, const GLvoid*);
struct PostprocessShaderUniform {
PostprocessShaderUniform *next;
PostprocessShaderUniform *prev;
LIST_INTERFACE(PostprocessShaderUniform);
PostprocessShaderUniformType type;
PostprocessShaderUniformValuePtr values;
PostprocessShaderUniformFuncPtr func;
int loc;
int size;
int amount;

View file

@ -17,7 +17,9 @@ static StageText *textlist = NULL;
#define NUM_PLACEHOLDER "........................"
StageText* stagetext_add(const char *text, complex pos, Alignment align, Font **font, Color clr, int delay, int lifetime, int fadeintime, int fadeouttime) {
StageText *t = (StageText*)list_append((List**)&textlist, malloc(sizeof(StageText)));
StageText *t = malloc(sizeof(StageText));
list_append(&textlist, t);
t->text = strdup(text);
t->font = font;
t->pos = pos;

View file

@ -19,8 +19,7 @@ typedef void (*StageTextPreDrawFunc)(StageText* txt, int t, float alpha);
typedef struct StageTextTable StageTextTable;
struct StageText {
StageText *next;
StageText *prev;
LIST_INTERFACE(StageText);
char *text;
Font **font;

View file

@ -18,7 +18,7 @@ typedef struct vfs_tls_s {
} vfs_tls_t;
typedef struct vfs_shutdownhook_t {
List refs;
LIST_INTERFACE(struct vfs_shutdownhook_t);
VFSShutdownHandler func;
void *arg;
} vfs_shutdownhook_t;
@ -76,7 +76,7 @@ static void* call_shutdown_hook(List **vlist, List *vhook, void *arg) {
}
void vfs_shutdown(void) {
list_foreach((List**)&shutdown_hooks, call_shutdown_hook, NULL);
list_foreach(&shutdown_hooks, call_shutdown_hook, NULL);
vfs_decref(vfs_root);
vfs_tls_free(vfs_tls_fallback);
@ -87,9 +87,10 @@ void vfs_shutdown(void) {
}
void vfs_hook_on_shutdown(VFSShutdownHandler func, void *arg) {
vfs_shutdownhook_t *hook = (vfs_shutdownhook_t*)list_append((List**)&shutdown_hooks, malloc(sizeof(vfs_shutdownhook_t)));
vfs_shutdownhook_t *hook = malloc(sizeof(vfs_shutdownhook_t));
hook->func = func;
hook->arg = arg;
list_append(&shutdown_hooks, hook);
}
VFSNode* vfs_alloc(void) {

View file

@ -24,7 +24,7 @@ static void* vfs_union_delete_callback(List **list, List *elem, void *arg) {
}
static void vfs_union_free(VFSNode *node) {
list_foreach(&node->_members_, vfs_union_delete_callback, NULL);
list_foreach((ListContainer**)&node->_members_, vfs_union_delete_callback, NULL);
}
static VFSNode* vfs_union_locate(VFSNode *node, const char *path) {
@ -160,7 +160,7 @@ static bool vfs_union_mount_internal(VFSNode *unode, const char *mountpoint, VFS
return false;
}
list_push(&unode->_members_, list_wrap_container(mountee));
list_push((ListContainer**)&unode->_members_, list_wrap_container(mountee));
unode->_primary_member_ = mountee;
return true;