diff --git a/src/ht.h b/src/ht.h index 1e39ebe..81519dd 100644 --- a/src/ht.h +++ b/src/ht.h @@ -96,6 +96,20 @@ void *ht_get(ed_ht *ht, string key) { return NULL; } +void ht_remove(ed_ht *ht, string key) { + ht_hash_t hash = ht_hash(key, ht->capacity); + + for (size_t i=hash; icapacity; ++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) { // TODO: destroy the hash table free(ht->key_slots); diff --git a/src/main.c b/src/main.c index 30a91e5..c601b66 100644 --- a/src/main.c +++ b/src/main.c @@ -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(); } void ed_frame() { - string label = _String("Number 1"); - ui_element(&state.ui_cx, label); + 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_element(&state.ui_cx, _String("Number 1")); ui_element(&state.ui_cx, _String("ui element 2")); ui_element(&state.ui_cx, _String("ui element 3")); 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; - for (size_t i = 0; i < state.ui_cx.cached_elements.capacity; ++i) { - if (state.ui_cx.cached_elements.key_slots[i].key.data != NULL) { - string text = state.ui_cx.cached_elements.key_slots[i].key; + for (size_t i = 0; i < state.ui_cx.frame_elements.size; ++i) { + string text = state.ui_cx.frame_elements.data[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); - if (value) { - queue_text(text, (float[]){ (float)value->size.computed_pos[0], (float)value->size.computed_pos[1] }); - } - } + queue_text(text, (float[]){ (float)elm->size.computed_pos[0], (float)elm->size.computed_pos[1] }); } + ui_update_cache(&state.ui_cx, 0); + ui_prune(&state.ui_cx); + if (state.gpu_glyphs.size > 0) { sg_update_buffer(state.bind.vertex_buffers[1], &(sg_range) { .ptr = state.gpu_glyphs.data, @@ -363,10 +357,12 @@ void ed_frame() { sg_end_pass(); sg_commit(); } + void ed_cleanup() { sfetch_shutdown(); sg_shutdown(); } + void ed_event(const sapp_event *event) { switch (event->type) { case SAPP_EVENTTYPE_MOUSE_DOWN: diff --git a/src/ui.h b/src/ui.h index 37d1131..630bcb9 100644 --- a/src/ui.h +++ b/src/ui.h @@ -24,6 +24,7 @@ #define _prev_ref(index) (_elm(_prev(index))) #define _parent_ref(index) (_elm(_parent(index))) +#include #include #include #include @@ -360,6 +361,13 @@ void ui_update_cache(ui_context *cx, size_t element_index) { do { __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) { .label = child->label, .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] }, .computed_size = { child->size.computed_size[0], child->size.computed_size[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); @@ -384,5 +392,23 @@ void ui_update_cache(ui_context *cx, size_t element_index) { 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