ui id strategy and core_hash.c
This commit is contained in:
@@ -4,7 +4,7 @@ struct random_seed_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// xorshift64
|
// xorshift64
|
||||||
u64 get_random_u64(random_seed_t *seed) {
|
fn u64 get_random_u64(random_seed_t *seed) {
|
||||||
u64 x = seed->a;
|
u64 x = seed->a;
|
||||||
x ^= x << 13;
|
x ^= x << 13;
|
||||||
x ^= x >> 7;
|
x ^= x >> 7;
|
||||||
@@ -12,7 +12,7 @@ u64 get_random_u64(random_seed_t *seed) {
|
|||||||
return seed->a = x;
|
return seed->a = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 get_random_in_range_u64(random_seed_t *seed, u64 start, u64 one_past_end) {
|
fn u64 get_random_in_range_u64(random_seed_t *seed, u64 start, u64 one_past_end) {
|
||||||
u64 r = get_random_u64(seed);
|
u64 r = get_random_u64(seed);
|
||||||
u64 diff = one_past_end - start;
|
u64 diff = one_past_end - start;
|
||||||
u64 rr = r % diff;
|
u64 rr = r % diff;
|
||||||
@@ -20,7 +20,7 @@ u64 get_random_in_range_u64(random_seed_t *seed, u64 start, u64 one_past_end) {
|
|||||||
return rrr;
|
return rrr;
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 get_random_in_range_i64(random_seed_t *seed, i64 start, i64 one_past_end) {
|
fn i64 get_random_in_range_i64(random_seed_t *seed, i64 start, i64 one_past_end) {
|
||||||
u64 r = get_random_u64(seed);
|
u64 r = get_random_u64(seed);
|
||||||
i64 diff = one_past_end - start;
|
i64 diff = one_past_end - start;
|
||||||
u64 rr = r % diff;
|
u64 rr = r % diff;
|
||||||
@@ -28,8 +28,25 @@ i64 get_random_in_range_i64(random_seed_t *seed, i64 start, i64 one_past_end) {
|
|||||||
return rrr;
|
return rrr;
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 get_random_f64(random_seed_t *seed) {
|
fn f64 get_random_f64(random_seed_t *seed) {
|
||||||
f64 random = (f64)get_random_in_range_u64(seed, 0, UINT32_MAX);
|
f64 random = (f64)get_random_in_range_u64(seed, 0, UINT32_MAX);
|
||||||
f64 result = random / (f64)(UINT32_MAX - 1u);
|
f64 result = random / (f64)(UINT32_MAX - 1u);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn u64 hash_data(s8_t string) {
|
||||||
|
u8 *data = (u8 *)string.str;
|
||||||
|
u64 hash = (u64)14695981039346656037ULL;
|
||||||
|
for (i64 i = 0; i < string.len; i++) {
|
||||||
|
hash = hash ^ (u64)(data[i]);
|
||||||
|
hash = hash * (u64)1099511628211ULL;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn u64 hash_mix(u64 x, u64 y) {
|
||||||
|
x ^= y;
|
||||||
|
x *= 0xff51afd7ed558ccd;
|
||||||
|
x ^= x >> 32;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
@@ -33,16 +33,6 @@ struct ht_dict_t {
|
|||||||
ht_bucket_t *buckets;
|
ht_bucket_t *buckets;
|
||||||
};
|
};
|
||||||
|
|
||||||
u64 ht_hash_data(s8_t string) {
|
|
||||||
u8 *data = (u8 *)string.str;
|
|
||||||
uint64_t hash = (u64)14695981039346656037ULL;
|
|
||||||
for (i64 i = 0; i < string.len; i++) {
|
|
||||||
hash = hash ^ (u64)(data[i]);
|
|
||||||
hash = hash * (u64)1099511628211ULL;
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
ht_dict_t *ht_create(ma_arena_t *arena, i32 size) {
|
ht_dict_t *ht_create(ma_arena_t *arena, i32 size) {
|
||||||
ht_dict_t *result = ma_push_type(arena, ht_dict_t);
|
ht_dict_t *result = ma_push_type(arena, ht_dict_t);
|
||||||
result->buckets = ma_push_array(arena, ht_bucket_t, size);
|
result->buckets = ma_push_array(arena, ht_bucket_t, size);
|
||||||
@@ -61,7 +51,7 @@ ht_node_t *ht_insert_kv(ht_dict_t *ht, u64 hash, ht_key_value_t kv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ht_node_t *ht_insert_u64_u64(ht_dict_t *ht, u64 key, u64 value) {
|
ht_node_t *ht_insert_u64_u64(ht_dict_t *ht, u64 key, u64 value) {
|
||||||
u64 hash = ht_hash_data(s8((char *)&key, sizeof(key)));
|
u64 hash = hash_data(s8_struct(key));
|
||||||
return ht_insert_kv(ht, hash, (ht_key_value_t){.key_u64 = key, .value_u64 = value});
|
return ht_insert_kv(ht, hash, (ht_key_value_t){.key_u64 = key, .value_u64 = value});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,12 +60,12 @@ ht_node_t *ht_insert_ptr(ht_dict_t *ht, void *key, void *value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ht_node_t *ht_insert_string(ht_dict_t *ht, s8_t key, s8_t value) {
|
ht_node_t *ht_insert_string(ht_dict_t *ht, s8_t key, s8_t value) {
|
||||||
u64 hash = ht_hash_data(key);
|
u64 hash = hash_data(key);
|
||||||
return ht_insert_kv(ht, hash, (ht_key_value_t){.key_string = key, .value_string = value});
|
return ht_insert_kv(ht, hash, (ht_key_value_t){.key_string = key, .value_string = value});
|
||||||
}
|
}
|
||||||
|
|
||||||
ht_node_t *ht_search_u64(ht_dict_t *ht, u64 key) {
|
ht_node_t *ht_search_u64(ht_dict_t *ht, u64 key) {
|
||||||
u64 hash = ht_hash_data(s8((char *)&key, sizeof(key)));
|
u64 hash = hash_data(s8_struct(key));
|
||||||
i64 idx = hash % ht->bucket_count;
|
i64 idx = hash % ht->bucket_count;
|
||||||
ht_bucket_t *bucket = ht->buckets + idx;
|
ht_bucket_t *bucket = ht->buckets + idx;
|
||||||
for (ht_node_t *it = bucket->first; it; it = it->next) {
|
for (ht_node_t *it = bucket->first; it; it = it->next) {
|
||||||
@@ -91,7 +81,7 @@ ht_node_t *ht_search_ptr(ht_dict_t *ht, void *key_ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ht_node_t *ht_search_string(ht_dict_t *ht, s8_t key) {
|
ht_node_t *ht_search_string(ht_dict_t *ht, s8_t key) {
|
||||||
u64 hash = ht_hash_data(key);
|
u64 hash = hash_data(key);
|
||||||
i64 idx = hash % ht->bucket_count;
|
i64 idx = hash % ht->bucket_count;
|
||||||
ht_bucket_t *bucket = ht->buckets + idx;
|
ht_bucket_t *bucket = ht->buckets + idx;
|
||||||
for (ht_node_t *it = bucket->first; it; it = it->next) {
|
for (ht_node_t *it = bucket->first; it; it = it->next) {
|
||||||
|
|||||||
@@ -44,5 +44,5 @@
|
|||||||
#include "core_log.c"
|
#include "core_log.c"
|
||||||
#include "core_lexer.c"
|
#include "core_lexer.c"
|
||||||
#include "core_type_info.c"
|
#include "core_type_info.c"
|
||||||
#include "core_random.c"
|
#include "core_hash.c"
|
||||||
#include "core_hash_table.c"
|
#include "core_hash_table.c"
|
||||||
@@ -155,6 +155,7 @@ void *sbin_read_data(stream_t *stream, i64 size);
|
|||||||
//
|
//
|
||||||
// other
|
// other
|
||||||
#define s8_fmtspec(string) (int)(string).len, (string).str
|
#define s8_fmtspec(string) (int)(string).len, (string).str
|
||||||
|
#define s8_struct(DATA) (s8_t){.str = (char *)&(DATA), .len = sizeof(DATA)}
|
||||||
#define S8_CODE(...) s8_lit(#__VA_ARGS__)
|
#define S8_CODE(...) s8_lit(#__VA_ARGS__)
|
||||||
#define S8_FILE s8_lit(__FILE__)
|
#define S8_FILE s8_lit(__FILE__)
|
||||||
#define S8_FILE_AND_LINE s8_lit(FILE_AND_LINE)
|
#define S8_FILE_AND_LINE s8_lit(FILE_AND_LINE)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
** [ ] Using file and line
|
** [ ] Using file and line
|
||||||
** [ ] Keyboard friendliness
|
** [ ] Keyboard friendliness
|
||||||
** [ ] ui_em size
|
** [ ] ui_em size
|
||||||
**
|
** [ ] strict
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct ui_id_t ui_id_t;
|
typedef struct ui_id_t ui_id_t;
|
||||||
@@ -86,8 +86,10 @@ struct ui_signal_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ui_id_strategy_hierarchy,
|
ui_id_strategy_null = 0,
|
||||||
ui_id_strategy_code_loc,
|
ui_id_strategy_use_hierarchy = set_bit(0),
|
||||||
|
ui_id_strategy_use_code_loc = set_bit(1),
|
||||||
|
ui_id_strategy_use_string = set_bit(2),
|
||||||
} ui_id_strategy_t;
|
} ui_id_strategy_t;
|
||||||
|
|
||||||
typedef struct ui_t ui_t;
|
typedef struct ui_t ui_t;
|
||||||
@@ -126,14 +128,7 @@ fn b32 ui_is_active_box(ui_box_t *box) { return !ui_is_null_box(box) && box->id.
|
|||||||
#define ev_left_up(ev) ((ev)->kind == app_event_kind_mouse_up && ev_left(ev))
|
#define ev_left_up(ev) ((ev)->kind == app_event_kind_mouse_up && ev_left(ev))
|
||||||
#define ev_left_down(ev) ((ev)->kind == app_event_kind_mouse_down && ev_left(ev))
|
#define ev_left_down(ev) ((ev)->kind == app_event_kind_mouse_down && ev_left(ev))
|
||||||
|
|
||||||
fn u64 ui_hash_mix(u64 x, u64 y) {
|
fn s8_t ui_get_display_string(s8_t string) {
|
||||||
x ^= y;
|
|
||||||
x *= 0xff51afd7ed558ccd;
|
|
||||||
x ^= x >> 32;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
s8_t ui_get_display_string(s8_t string) {
|
|
||||||
s8_t result = string;
|
s8_t result = string;
|
||||||
if (s8_seek(result, s8_lit("##"), s8_seek_none, &result.len)) {
|
if (s8_seek(result, s8_lit("##"), s8_seek_none, &result.len)) {
|
||||||
int a = 10;
|
int a = 10;
|
||||||
@@ -141,7 +136,7 @@ s8_t ui_get_display_string(s8_t string) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
s8_t ui_get_hash_string(s8_t string) {
|
fn s8_t ui_get_hash_string(s8_t string) {
|
||||||
i64 len = 0;
|
i64 len = 0;
|
||||||
if (s8_seek(string, s8_lit("##"), s8_seek_none, &len)) {
|
if (s8_seek(string, s8_lit("##"), s8_seek_none, &len)) {
|
||||||
string = s8_skip(string, len + 2);
|
string = s8_skip(string, len + 2);
|
||||||
@@ -149,12 +144,6 @@ s8_t ui_get_hash_string(s8_t string) {
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_id_t ui_id_from_string(s8_t string) {
|
|
||||||
u64 value = ht_hash_data(ui_get_hash_string(string));
|
|
||||||
ui_id_t id = {value};
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ui_id_t ui_find_valid_id(ui_box_t *box) {
|
fn ui_id_t ui_find_valid_id(ui_box_t *box) {
|
||||||
for (ui_box_t *it = box; it; it = it->parent) {
|
for (ui_box_t *it = box; it; it = it->parent) {
|
||||||
if (!ui_is_null_box(it)) return it->id;
|
if (!ui_is_null_box(it)) return it->id;
|
||||||
@@ -162,7 +151,7 @@ fn ui_id_t ui_find_valid_id(ui_box_t *box) {
|
|||||||
return ui_id_null;
|
return ui_id_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_id_t ui_id_from_parent(void) {
|
fn ui_id_t ui_find_top_id(void) {
|
||||||
ui_id_t parent_id = ui_find_valid_id(ui->top);
|
ui_id_t parent_id = ui_find_valid_id(ui->top);
|
||||||
if (ui_is_null_id(parent_id)) parent_id.value = 1423;
|
if (ui_is_null_id(parent_id)) parent_id.value = 1423;
|
||||||
return parent_id;
|
return parent_id;
|
||||||
@@ -216,20 +205,31 @@ fn ui_box_t *ui_build_box_from_id(ui_code_loc_t loc, ui_id_t id) {
|
|||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_box_t *ui_build_box_from_string(ui_code_loc_t loc, s8_t string) {
|
fn ui_id_t ui_gen_id(ui_id_strategy_t strat, ui_code_loc_t loc, s8_t string) {
|
||||||
ui_id_t id = {32};
|
assert(strat != 0);
|
||||||
ui_id_t string_id = ui_id_from_string(string);
|
u64 result = 42523423493;
|
||||||
if (ui->id_strategy == ui_id_strategy_code_loc) {
|
if (strat & ui_id_strategy_use_string) {
|
||||||
u64 file_hash = ht_hash_data(s8_from_char(loc.file));
|
u64 string_hash = hash_data(string);
|
||||||
u64 line_hash = ht_hash_data(s8((char *)&loc.line, sizeof(loc.line)));
|
result = hash_mix(string_hash, result);
|
||||||
u64 cont_hash = ht_hash_data(s8((char *)&loc.counter, sizeof(loc.counter)));
|
}
|
||||||
id.value = ui_hash_mix(file_hash, line_hash);
|
if (strat & ui_id_strategy_use_hierarchy) {
|
||||||
id.value = ui_hash_mix(id.value, cont_hash);
|
ui_id_t top_id = ui_find_top_id();
|
||||||
} else if (ui->id_strategy == ui_id_strategy_hierarchy) {
|
result = hash_mix(top_id.value, result);
|
||||||
ui_id_t id_from_stack = ui_id_from_parent();
|
}
|
||||||
id.value = ui_hash_mix(string_id.value, id_from_stack.value);
|
if (strat & ui_id_strategy_use_code_loc) {
|
||||||
} else_is_invalid;
|
u64 file_hash = hash_data(s8_from_char(loc.file));
|
||||||
|
u64 line_hash = hash_data(s8_struct(loc.line));
|
||||||
|
u64 cont_hash = hash_data(s8_struct(loc.counter));
|
||||||
|
result = hash_mix(result, file_hash);
|
||||||
|
result = hash_mix(result, line_hash);
|
||||||
|
result = hash_mix(result, cont_hash);
|
||||||
|
}
|
||||||
|
ui_id_t id = {result};
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ui_box_t *ui_build_box_from_string(ui_code_loc_t loc, s8_t string) {
|
||||||
|
ui_id_t id = ui_gen_id(ui->id_strategy, loc, ui_get_hash_string(string));
|
||||||
ui_box_t *box = ui_build_box_from_id(loc, id);
|
ui_box_t *box = ui_build_box_from_id(loc, id);
|
||||||
box->string = ui_get_display_string(string);
|
box->string = ui_get_display_string(string);
|
||||||
return box;
|
return box;
|
||||||
@@ -269,6 +269,7 @@ fn void ui_init(ma_arena_t *arena) {
|
|||||||
ui = ma_push_type(arena, ui_t);
|
ui = ma_push_type(arena, ui_t);
|
||||||
ui->box_arena = arena;
|
ui->box_arena = arena;
|
||||||
ui->root = ma_push_type(arena, ui_box_t);
|
ui->root = ma_push_type(arena, ui_box_t);
|
||||||
|
ui->id_strategy = ui_id_strategy_use_string | ui_id_strategy_use_code_loc;
|
||||||
|
|
||||||
ui->box_array = ma_push_type(arena, ui_box_t);
|
ui->box_array = ma_push_type(arena, ui_box_t);
|
||||||
SLLS_PUSH(ui->free_first, ui->box_array);
|
SLLS_PUSH(ui->free_first, ui->box_array);
|
||||||
@@ -499,12 +500,14 @@ fn void ui_draw(void) {
|
|||||||
// compute: (percent_of_parent)
|
// compute: (percent_of_parent)
|
||||||
for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) {
|
for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) {
|
||||||
ui_box_t *box = it.box;
|
ui_box_t *box = it.box;
|
||||||
ui_box_t *parent = box->parent;
|
ui_box_t *parent = box->parent; // @todo: I'm not sure why Ryan uses a loop to find a parent with fixed size_kind
|
||||||
for (i32 i = 0; i < ui_axis2_count; i += 1) {
|
for (i32 i = 0; i < ui_axis2_count; i += 1) {
|
||||||
ui_size_t sem = box->semantic_size[i];
|
ui_size_t sem = box->semantic_size[i];
|
||||||
if (sem.kind == ui_size_kind_percent_of_parent) {
|
if (sem.kind == ui_size_kind_percent_of_parent) {
|
||||||
assert(sem.value >= 0 && sem.value <= 1.0);
|
assert(sem.value >= 0 && sem.value <= 1.0);
|
||||||
assert(parent->semantic_size[i].kind == ui_size_kind_pixels || parent->semantic_size[i].kind == ui_size_kind_text_content);
|
assert(parent->semantic_size[i].kind == ui_size_kind_pixels ||
|
||||||
|
parent->semantic_size[i].kind == ui_size_kind_text_content ||
|
||||||
|
parent->semantic_size[i].kind == ui_size_kind_percent_of_parent);
|
||||||
box->computed_size[i] = sem.value * parent->computed_size[i];
|
box->computed_size[i] = sem.value * parent->computed_size[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user