You've already forked flecs_tests
refactor: eliminate globals, add pen tool + edit mode, frustum culling
Remove all file-scope mutable state so the codebase compiles cleanly as a single translation unit. State moved into structs owned by userdata_t: - group_index_ctx_t replaces g_group_by_id/g_group_by_id_cap - shape_pool_ctx_t replaces g_shape_pool_dirty/g_shape_data_dirty and g_shape_groups/g_shape_groups_count - panel_log_ctx_t wired through all subsystems explicitly - pipeline_ctx_t owns render pipeline handles - overlay_upload_state_t (per-buffer flags) replaces single bool New features piggybacking on the refactor: - Pen tool: click-to-place anchors, Catmull-Rom preview, finalize into Bezier shapes with control points - Edit mode: anchor/handle hit testing, dragging, pre-drag undo snapshots, dedicated GPU buffers for edit overlays - Frustum culling: spatial-grid-based viewport cull in draw_shapes with linear-scan fallback for oversized viewports - Log dedup: FNV-1a 64-bit hash to skip duplicate messages - Buffer shrink: halve draw buffers after 60 frames of low usage - Shape geometry hashing for instanced-draw vertex-buffer grouping - Group member_indices arrays with O(n) rebuild - Log ring expanded 64→256 entries, added log_filter Debug build: added --profiling-funcs and -sASSERTIONS flags.
This commit is contained in:
25
src/util.h
25
src/util.h
@@ -33,7 +33,11 @@ static void vec_grow(vector_t *v, int min_capacity) {
|
||||
int new_cap = v->capacity ? v->capacity * 2 : 8;
|
||||
if (new_cap < min_capacity) new_cap = min_capacity;
|
||||
uint8_t *new_data = (uint8_t*) ALLOC(new_cap * v->stride);
|
||||
assert(new_data != NULL);
|
||||
if (!new_data) {
|
||||
EM_ASM({ console.error("vec_grow: ALLOC failed for %d elements of %d bytes", $0, $1); },
|
||||
new_cap, v->stride);
|
||||
return;
|
||||
}
|
||||
if (v->data) {
|
||||
memcpy(new_data, v->data, v->count * v->stride);
|
||||
FREE(v->data);
|
||||
@@ -72,6 +76,25 @@ static void vec_remove_ordered(vector_t *v, int index) {
|
||||
v->count--;
|
||||
}
|
||||
|
||||
// Remove `count` elements at given indices in a single compaction pass.
|
||||
// Indices must be sorted in ascending order and must be valid.
|
||||
static void vec_remove_ordered_bulk(vector_t *v, const int *indices, int count) {
|
||||
if (count <= 0) return;
|
||||
int write = indices[0];
|
||||
for (int k = 0; k < count; k++) {
|
||||
int gap_start = indices[k];
|
||||
int gap_end = (k + 1 < count) ? indices[k + 1] : v->count;
|
||||
int keep = gap_end - gap_start - 1;
|
||||
if (keep > 0) {
|
||||
memmove(v->data + write * v->stride,
|
||||
v->data + (gap_start + 1) * v->stride,
|
||||
(size_t)keep * (size_t)v->stride);
|
||||
write += keep;
|
||||
}
|
||||
}
|
||||
v->count -= count;
|
||||
}
|
||||
|
||||
static void *vec_insert(vector_t *v, int index) {
|
||||
if (index < 0 || index > v->count) return NULL;
|
||||
if (v->count >= v->capacity) vec_grow(v, v->count + 1);
|
||||
|
||||
Reference in New Issue
Block a user