prune unused elements

main
Patrick Cleavelin 2024-03-18 19:58:06 -05:00
parent 46dd862512
commit 86e5eaaac9
3 changed files with 55 additions and 19 deletions

View File

@ -96,6 +96,20 @@ void *ht_get(ed_ht *ht, string key) {
return NULL; return NULL;
} }
void ht_remove(ed_ht *ht, string key) {
ht_hash_t hash = ht_hash(key, ht->capacity);
for (size_t i=hash; i<ht->capacity; ++i) {
if (ht->key_slots[i].key.data == NULL) {
return;
}
if (string_eq(ht->key_slots[i].key, key)) {
ht->key_slots[i] = (ed_ht_slot) { 0 };
}
}
}
void ht_destroy(ed_ht *ht) { void ht_destroy(ed_ht *ht) {
// TODO: destroy the hash table // TODO: destroy the hash table
free(ht->key_slots); free(ht->key_slots);

View File

@ -307,36 +307,30 @@ void ed_init() {
}, },
}); });
// queue_text(_String("But what even is text! []!@#$%^&*()_=+"), (float[]){ 0, 0 });
// queue_text(_String("v0.1.0"), (float[]){ 32, 128 });
// queue_text(_String("an_editor - what even"), (float[]){ 32, 256 });
state.ui_cx = ui_init_context(); state.ui_cx = ui_init_context();
} }
void ed_frame() { void ed_frame() {
string label = _String("Number 1"); state.ui_cx.frame_elements.data[0].size.computed_size[0] = sapp_width();
ui_element(&state.ui_cx, label); state.ui_cx.frame_elements.data[0].size.computed_size[1] = sapp_height();
ui_element(&state.ui_cx, _String("Number 1"));
ui_element(&state.ui_cx, _String("ui element 2")); ui_element(&state.ui_cx, _String("ui element 2"));
ui_element(&state.ui_cx, _String("ui element 3")); ui_element(&state.ui_cx, _String("ui element 3"));
ui_compute_layout(&state.ui_cx, 0); ui_compute_layout(&state.ui_cx, 0);
state.ui_cx.frame_elements.data[0].size.computed_size[0] = sapp_width();
state.ui_cx.frame_elements.data[0].size.computed_size[1] = sapp_height();
ui_update_cache(&state.ui_cx, 0);
state.gpu_glyphs.size = 0; state.gpu_glyphs.size = 0;
for (size_t i = 0; i < state.ui_cx.cached_elements.capacity; ++i) { for (size_t i = 0; i < state.ui_cx.frame_elements.size; ++i) {
if (state.ui_cx.cached_elements.key_slots[i].key.data != NULL) { string text = state.ui_cx.frame_elements.data[i].key;
string text = state.ui_cx.cached_elements.key_slots[i].key; ui_element_frame_data *elm = &state.ui_cx.frame_elements.data[i];
ui_element_cache_data *value = ht_get(&state.ui_cx.cached_elements, text); queue_text(text, (float[]){ (float)elm->size.computed_pos[0], (float)elm->size.computed_pos[1] });
if (value) {
queue_text(text, (float[]){ (float)value->size.computed_pos[0], (float)value->size.computed_pos[1] });
}
}
} }
ui_update_cache(&state.ui_cx, 0);
ui_prune(&state.ui_cx);
if (state.gpu_glyphs.size > 0) { if (state.gpu_glyphs.size > 0) {
sg_update_buffer(state.bind.vertex_buffers[1], &(sg_range) { sg_update_buffer(state.bind.vertex_buffers[1], &(sg_range) {
.ptr = state.gpu_glyphs.data, .ptr = state.gpu_glyphs.data,
@ -363,10 +357,12 @@ void ed_frame() {
sg_end_pass(); sg_end_pass();
sg_commit(); sg_commit();
} }
void ed_cleanup() { void ed_cleanup() {
sfetch_shutdown(); sfetch_shutdown();
sg_shutdown(); sg_shutdown();
} }
void ed_event(const sapp_event *event) { void ed_event(const sapp_event *event) {
switch (event->type) { switch (event->type) {
case SAPP_EVENTTYPE_MOUSE_DOWN: case SAPP_EVENTTYPE_MOUSE_DOWN:

View File

@ -24,6 +24,7 @@
#define _prev_ref(index) (_elm(_prev(index))) #define _prev_ref(index) (_elm(_prev(index)))
#define _parent_ref(index) (_elm(_parent(index))) #define _parent_ref(index) (_elm(_parent(index)))
#include <stdio.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@ -360,6 +361,13 @@ void ui_update_cache(ui_context *cx, size_t element_index) {
do { do {
__auto_type child = _elm(child_index); __auto_type child = _elm(child_index);
size_t last_instantiated_index = cx->frame_index;
ui_element_cache_data *cache;
if ((cache = ht_get(&cx->cached_elements, child->key))) {
last_instantiated_index = cache->last_instantiated_index;
}
ht_set(&cx->cached_elements, child->key, &(ui_element_cache_data) { ht_set(&cx->cached_elements, child->key, &(ui_element_cache_data) {
.label = child->label, .label = child->label,
.size = { .size = {
@ -367,8 +375,8 @@ void ui_update_cache(ui_context *cx, size_t element_index) {
.semantic_size = { child->size.semantic_size[0], child->size.semantic_size[1] }, .semantic_size = { child->size.semantic_size[0], child->size.semantic_size[1] },
.computed_size = { child->size.computed_size[0], child->size.computed_size[1] }, .computed_size = { child->size.computed_size[0], child->size.computed_size[1] },
.computed_pos = { child->size.computed_pos[0], child->size.computed_pos[1] }, .computed_pos = { child->size.computed_pos[0], child->size.computed_pos[1] },
} },
// FIXME: don't mangle last_instantiated_index .last_instantiated_index = last_instantiated_index,
}); });
ui_update_cache(cx, child_index); ui_update_cache(cx, child_index);
@ -384,5 +392,23 @@ void ui_update_cache(ui_context *cx, size_t element_index) {
cx->current_parent = 0; cx->current_parent = 0;
} }
void ui_prune(ui_context *cx) {
for (size_t i = 0; i < cx->cached_elements.capacity; ++i) {
if (cx->cached_elements.key_slots[i].key.data != NULL) {
string key = cx->cached_elements.key_slots[i].key;
// if this element hasn't been created in the past 5 frames, remove it
ui_element_cache_data *cached = ht_get(&cx->cached_elements, key);
if (cached && cached->last_instantiated_index < cx->frame_index-5) {
// fprintf(stderr, "removing %.*s from cache, cache index: %zu, frame index: %zu\n", (int)key.len, key.data, cached->last_instantiated_index, cx->frame_index);
ht_remove(&cx->cached_elements, key);
}
}
}
cx->frame_index += 1;
}
#endif #endif
#endif #endif