dynarray: get rid of memset and add optional initializer arg to dynarray_append

This commit is contained in:
Andrei Alexeyev 2023-09-23 13:49:26 +02:00
parent b02d831e41
commit c15934f666
No known key found for this signature in database
GPG key ID: 72D26128040B9690
20 changed files with 92 additions and 89 deletions

View file

@ -204,9 +204,10 @@ static void credits_add(char *data, int time) {
assert(time > CREDITS_ENTRY_FADEOUT);
e = dynarray_append(&credits.entries);
e->time = time - CREDITS_ENTRY_FADEOUT;
e->lines = 1;
e = dynarray_append(&credits.entries, {
.time = time - CREDITS_ENTRY_FADEOUT,
.lines = 1,
});
for(c = data; *c; ++c)
if(*c == '\n') e->lines++;

View file

@ -50,15 +50,14 @@ dynarray_size_t _dynarray_prepare_append_with_min_capacity(dynarray_size_t sizeo
assume(num_elements <= capacity);
assume(min_capacity >= 2);
if(capacity < min_capacity) {
if(UNLIKELY(capacity < min_capacity)) {
_dynarray_resize(sizeof_element, darr, min_capacity);
} else if(num_elements == capacity) {
} else if(UNLIKELY(num_elements == capacity)) {
capacity += capacity >> 1;
_dynarray_resize(sizeof_element, darr, capacity);
}
++darr->num_elements;
memset((char*)darr->data + num_elements * sizeof_element, 0, sizeof_element);
DYNARRAY_DEBUG(darr, "elements: %u/%u", darr->num_elements, darr->capacity);
return num_elements; // insertion index

View file

@ -70,21 +70,23 @@ void _dynarray_ensure_capacity(dynarray_size_t sizeof_element, DynamicArray *dar
dynarray_size_t _dynarray_prepare_append_with_min_capacity(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_size_t min_capacity) attr_nonnull_all;
/*
* NOTE: unfortunately this evaluates `darr` more than once, but when compiling
* with NDEBUG the assume() macro should trip a clang warning if there are
* potential side-effects, and we always treat that warning as an error.
*/
#define _dynarray_append_with_min_capacity(darr, min_capacity) \
dynarray_get_ptr(darr, _dynarray_dispatch_func(prepare_append_with_min_capacity, darr, min_capacity))
#define dynarray_append_with_min_capacity(darr, min_capacity) ({ \
auto _darr2 = NOT_NULL(darr); \
dynarray_get_ptr(_darr2, _dynarray_dispatch_func(prepare_append_with_min_capacity, _darr2, min_capacity)); \
#define _dynarray_append_with_min_capacity_1(darr, min_capacity, ...) ({ \
auto _pelem = _dynarray_append_with_min_capacity_0(darr, min_capacity); \
*_pelem = ((typeof(*_pelem)) __VA_ARGS__); \
_pelem; \
})
#define dynarray_append(darr) \
dynarray_append_with_min_capacity(darr, 2)
#define _dynarray_append_with_min_capacity_0(darr, min_capacity) ({ \
auto _darr2 = NOT_NULL(darr); \
auto _pelem = dynarray_get_ptr(_darr2, _dynarray_dispatch_func(prepare_append_with_min_capacity, _darr2, min_capacity)); \
_pelem; \
})
#define dynarray_append_with_min_capacity(darr, min_capacity, ...) \
MACROHAX_OVERLOAD_HASARGS(_dynarray_append_with_min_capacity_, __VA_ARGS__)(darr, min_capacity, ##__VA_ARGS__)
#define dynarray_append(darr, ...) \
dynarray_append_with_min_capacity(darr, 2, ##__VA_ARGS__)
void _dynarray_compact(dynarray_size_t sizeof_element, DynamicArray *darr) attr_nonnull_all;
#define dynarray_compact(darr) \

View file

@ -81,7 +81,7 @@ void ent_register(EntityInterface *ent, EntityType type) {
ent->spawn_id = ++entities.total_spawns;
ent->index = entities.registered.num_elements;
assume(ent->spawn_id > 0);
*dynarray_append(&entities.registered) = ent;
dynarray_append(&entities.registered, ent);
}
void ent_unregister(EntityInterface *ent) {

View file

@ -80,7 +80,7 @@ void events_register_handler(EventHandler *handler) {
assert(handler->priority >= EPRIO_FIRST);
assert(handler->priority <= EPRIO_LAST);
*dynarray_append(&global_handlers) = *handler;
dynarray_append(&global_handlers, *handler);
// don't bother sorting, since most of the time we will need to re-sort it
// together with local handlers when polling
@ -249,7 +249,7 @@ void events_emit(TaiseiEvent type, int32_t code, void *data1, void *data2) {
}
void events_defer(SDL_Event *evt) {
*dynarray_append(&deferred_events) = *evt;
dynarray_append(&deferred_events, *evt);
}
void events_pause_keyrepeat(void) {

View file

@ -164,9 +164,10 @@ static bool gamepad_update_device_list(void) {
continue;
}
auto dev = dynarray_append(&gamepad.devices);
dev->sdl_id = i;
dev->controller = SDL_GameControllerOpen(i);
auto dev = dynarray_append(&gamepad.devices, {
.sdl_id = i,
.controller = SDL_GameControllerOpen(i),
});
if(dev->controller == NULL) {
log_sdl_error(LOG_WARN, "SDL_GameControllerOpen");

View file

@ -266,12 +266,11 @@ static int quantize_laser(Laser *l) {
(xb > viewbounds.x && xb < viewbounds.w && yb > viewbounds.y && yb < viewbounds.h);
if(visible) {
LaserSegment *seg = dynarray_append(&lintern.segments);
*seg = (LaserSegment) {
LaserSegment *seg = dynarray_append(&lintern.segments, {
.pos = { a, b },
.width = { w0, w },
.time = { -t0, -t },
};
});
if(w < w0) {
// NOTE: the uneven capsule distance function may not work correctly in cases where

View file

@ -773,10 +773,11 @@ static char *copy_pattern(const char *p) {
}
void log_add_filter(LogLevelDiff diff, const char *pmod, const char *pfunc) {
LogFilterEntry *f = dynarray_append(&logging.filters);
f->patterns.module = copy_pattern(pmod);
f->patterns.func = copy_pattern(pfunc);
f->diff = diff;
dynarray_append(&logging.filters, {
.patterns.module = copy_pattern(pmod),
.patterns.func = copy_pattern(pfunc),
.diff = diff,
});
}
bool log_add_filter_string(const char *fstr) {

View file

@ -16,18 +16,16 @@
#include "util/graphics.h"
MenuEntry *add_menu_entry(MenuData *menu, const char *name, MenuAction action, void *arg) {
MenuEntry *e = dynarray_append(&menu->entries);
stralloc(&e->name, name);
e->action = action;
e->arg = arg;
e->transition = menu->transition;
return e;
return dynarray_append(&menu->entries, {
.action = action,
.arg = arg,
.transition = menu->transition,
.name = name ? strdup(name) : NULL,
});
}
void add_menu_separator(MenuData *menu) {
dynarray_append(&menu->entries);
dynarray_append(&menu->entries, {});
}
void free_menu(MenuData *menu) {

View file

@ -647,10 +647,11 @@ static void progress_prepare_cmd_stage_playinfo(size_t *bufsize, void **arg) {
StageProgress *p = stageinfo_get_progress(stg, d, false);
if(p && (p->global.num_played || p->global.num_cleared)) {
auto e = dynarray_append(&data->elems);
e->head.stage = stg->id;
e->head.diff = d;
e->prog = p;
dynarray_append(&data->elems, {
.head.stage = stg->id,
.head.diff = d,
.prog = p,
});
}
}
}

View file

@ -22,15 +22,17 @@ static void add_glsl_version_parsed(GLSLVersion v) {
}
});
ShaderLangInfo *lang = dynarray_append(&glcommon_shader_lang_table);
lang->lang = SHLANG_GLSL;
lang->glsl.version = v;
dynarray_append(&glcommon_shader_lang_table, {
.lang = SHLANG_GLSL,
.glsl.version = v,
});
if(v.profile == GLSL_PROFILE_NONE && v.version >= 330) {
v.profile = GLSL_PROFILE_CORE;
lang = dynarray_append(&glcommon_shader_lang_table);
lang->lang = SHLANG_GLSL;
lang->glsl.version = v;
dynarray_append(&glcommon_shader_lang_table, {
.lang = SHLANG_GLSL,
.glsl.version = v,
});
}
}

View file

@ -107,9 +107,7 @@ static GLTextureFormatInfo *add_texture_format(const GLTextureFormatInfo *fmt) {
#ifndef STATIC_GLES3
if(!glext.internalformat_query2) {
#endif
GLTextureFormatInfo *entry = dynarray_append(&g_formats);
*entry = *fmt;
return entry;
return dynarray_append(&g_formats, *fmt);
#ifndef STATIC_GLES3
}
@ -134,8 +132,7 @@ static GLTextureFormatInfo *add_texture_format(const GLTextureFormatInfo *fmt) {
GLint64 blendable = query_gl_format(ifmt, GL_FRAMEBUFFER_BLEND);
GLint64 encoding = query_gl_format(ifmt, GL_COLOR_ENCODING);
GLTextureFormatInfo *entry = dynarray_append(&g_formats);
*entry = *fmt;
GLTextureFormatInfo *entry = dynarray_append(&g_formats, *fmt);
entry->flags &= ~(
GLTEX_COLOR_RENDERABLE |

View file

@ -284,7 +284,7 @@ static bool _replay_read_events(ReplayReadContext *ctx) {
dynarray_ensure_capacity(&stg->events, stg->num_events);
for(int j = 0; j < stg->num_events; ++j) {
ReplayEvent *evt = dynarray_append(&stg->events);
ReplayEvent *evt = dynarray_append(&stg->events, {});
CHECKPROP(evt->frame = SDL_ReadLE32(ctx->stream), u);
CHECKPROP(evt->type = SDL_ReadU8(ctx->stream), u);

View file

@ -14,8 +14,7 @@
#include "plrmodes.h"
ReplayStage *replay_stage_new(Replay *rpy, StageInfo *stage, uint64_t start_time, uint64_t seed, Difficulty diff, Player *plr) {
ReplayStage *s = dynarray_append(&rpy->stages);
*s = (ReplayStage) { };
ReplayStage *s = dynarray_append(&rpy->stages, {});
get_system_time(&s->init_time);
dynarray_ensure_capacity(&s->events, REPLAY_ALLOC_INITIAL);
@ -73,10 +72,11 @@ void replay_stage_update_final_stats(ReplayStage *stg, const Stats *stats) {
void replay_stage_event(ReplayStage *stg, uint32_t frame, uint8_t type, uint16_t value) {
dynarray_size_t old_capacity = stg->events.capacity;
ReplayEvent *e = dynarray_append(&stg->events);
e->frame = frame;
e->type = type;
e->value = value;
dynarray_append(&stg->events, {
.frame = frame,
.type = type,
.value = value,
});
if(stg->events.capacity > old_capacity && stg->events.capacity > UINT16_MAX) {
log_error("Too many events in replay; saving WILL FAIL!");

View file

@ -516,15 +516,17 @@ static Glyph *load_glyph(Font *font, FT_UInt gindex, SpriteSheetAnchor *spritesh
return NULL;
}
Glyph *glyph = dynarray_append(&font->glyphs);
glyph->metrics.bearing_x = f26dot6_to_float(font->face->glyph->metrics.horiBearingX);
glyph->metrics.bearing_y = f26dot6_to_float(font->face->glyph->metrics.horiBearingY);
glyph->metrics.width = f26dot6_to_float(font->face->glyph->metrics.width);
glyph->metrics.height = f26dot6_to_float(font->face->glyph->metrics.height);
glyph->metrics.advance = f26dot6_to_float(font->face->glyph->metrics.horiAdvance);
glyph->metrics.lsb_delta = f26dot6_to_float(font->face->glyph->lsb_delta);
glyph->metrics.rsb_delta = f26dot6_to_float(font->face->glyph->rsb_delta);
Glyph *glyph = dynarray_append(&font->glyphs, {
.metrics = {
.bearing_x = f26dot6_to_float(font->face->glyph->metrics.horiBearingX),
.bearing_y = f26dot6_to_float(font->face->glyph->metrics.horiBearingY),
.width = f26dot6_to_float(font->face->glyph->metrics.width),
.height = f26dot6_to_float(font->face->glyph->metrics.height),
.advance = f26dot6_to_float(font->face->glyph->metrics.horiAdvance),
.lsb_delta = f26dot6_to_float(font->face->glyph->lsb_delta),
.rsb_delta = f26dot6_to_float(font->face->glyph->rsb_delta),
}
});
FT_Glyph g_src = NULL, g_fill = NULL, g_border = NULL, g_inner = NULL;
FT_BitmapGlyph g_bm_fill = NULL, g_bm_border = NULL, g_bm_inner = NULL;

View file

@ -476,7 +476,7 @@ void res_load_dependency(ResourceLoadState *st, ResourceType type, const char *n
InternalResource *dep = preload_resource_internal(type, name, st->flags & ~RESF_RELOAD);
InternalResource *ires = ist->ires;
ires_lock(ires);
*dynarray_append(&ires->dependencies) = dep;
dynarray_append(&ires->dependencies, dep);
ires_make_dependent_one(ires_get_persistent(ires), dep);
ires_unlock(ires);
}
@ -574,7 +574,7 @@ static void register_watched_path(InternalResource *ires, const char *vfspath, F
});
if(!free_slot) {
free_slot = dynarray_append(&ires->watched_paths);
free_slot = dynarray_append(&ires->watched_paths, {});
}
free_slot->vfs_path = strdup(vfspath);
@ -632,7 +632,7 @@ static void get_ires_list_for_watch(FileWatch *watch, IResPtrArray *output) {
for(;iter.has_data; ht_ires_counted_set_iter_next(&iter)) {
assert(iter.value > 0);
*dynarray_append(output) = iter.key;
dynarray_append(output, iter.key);
}
ht_ires_counted_set_iter_end(&iter);
@ -663,8 +663,7 @@ static void ires_migrate_watched_paths(InternalResource *dst, InternalResource *
dst->watched_paths.num_elements = 0;
dynarray_foreach_elem(&src->watched_paths, WatchedPath *src_wp, {
WatchedPath *dst_wp = dynarray_append(&dst->watched_paths);
*dst_wp = *src_wp;
WatchedPath *dst_wp = dynarray_append(&dst->watched_paths, *src_wp);
FileWatch *w = dst_wp->watch;
associate_ires_watch(dst, w);
@ -785,7 +784,7 @@ static void res_group_add_ires(ResourceGroup *rg, InternalResource *ires, bool i
ires_incref(ires);
}
*dynarray_append(&rg->refs) = ires;
dynarray_append(&rg->refs, ires);
}
static void res_group_preload_one(

View file

@ -27,14 +27,15 @@ static void add_stage(
AttackInfo *spell,
Difficulty diff
) {
StageInfo *stg = dynarray_append(&stageinfo.stages);
stg->id = id;
stg->procs = procs;
stg->type = type;
stralloc(&stg->title, title);
stralloc(&stg->subtitle, subtitle);
stg->spell = spell;
stg->difficulty = diff;
dynarray_append(&stageinfo.stages, {
.id = id,
.procs = procs,
.type = type,
.spell = spell,
.difficulty = diff,
.title = title ? strdup(title) : NULL,
.subtitle = subtitle ? strdup(subtitle) : NULL,
});
}
static void add_spellpractice_stage(

View file

@ -244,7 +244,7 @@ char** vfs_dir_list_sorted(const char *path, size_t *out_size, int (*compare)(co
continue;
}
*dynarray_append(&results) = strdup(e);
dynarray_append(&results, strdup(e));
}
vfs_dir_close(dir);

View file

@ -163,7 +163,7 @@ static bool vfs_union_mount(VFSNode *node, const char *mountpoint, VFSNode *moun
return false;
}
*dynarray_append(&unode->members) = mountee;
dynarray_append(&unode->members, mountee);
assert(vfs_union_get_primary(unode) == mountee);
return true;

View file

@ -197,7 +197,7 @@ static void video_add_mode(VideoModeArray *mode_array, IntExtent mode_screen, In
}
}
dynarray_append(mode_array)->as_int_extent = mode_screen;
dynarray_append(mode_array, { .as_int_extent = mode_screen });
log_debug("Add %s mode: %ix%i", mode_type, mode_screen.w, mode_screen.h);
}