eliminate possibility for recursive watch window builds; correctly sort child expansion keys before iteration, if needed, for non-identity-based id schemes (debug info tables, frontend entities, etc.); further fixes & integration

This commit is contained in:
Ryan Fleury
2024-09-26 15:26:28 -07:00
parent 07f978ac41
commit d314a12698
6 changed files with 138 additions and 43 deletions
@@ -294,8 +294,8 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(default)
for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next)
{
// rjf: unpack expansion info; skip out-of-bounds splits
U64 child_num = child->key.child_num;
U64 child_idx = child_num-1;
U64 child_id = child->key.child_id;
U64 child_idx = child_id-1;
E_Expr *child_expr = ev_expr_from_block_index(arena, last_vb, child_idx);
if(child_idx >= last_vb->semantic_idx_range.max)
{
@@ -369,8 +369,8 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(default)
for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next)
{
// rjf: unpack expansion info; skip out-of-bounds splits
U64 child_num = child->key.child_num;
U64 child_idx = child_num-1;
U64 child_id = child->key.child_id;
U64 child_idx = child_id-1;
E_Expr *child_expr = ev_expr_from_block_index(arena, last_vb, child_idx);
if(child_idx >= last_vb->semantic_idx_range.max)
{
+110 -23
View File
@@ -40,12 +40,12 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity)
//~ rjf: Key Functions
internal EV_Key
ev_key_make(U64 parent_hash, U64 child_num)
ev_key_make(U64 parent_hash, U64 child_id)
{
EV_Key key;
{
key.parent_hash = parent_hash;
key.child_num = child_num;
key.child_id = child_id;
}
return key;
}
@@ -87,7 +87,7 @@ ev_hash_from_key(EV_Key key)
{
U64 data[] =
{
key.child_num,
key.child_id,
};
U64 hash = ev_hash_from_seed_string(key.parent_hash, str8((U8 *)data, sizeof(data)));
return hash;
@@ -253,7 +253,7 @@ ev_key_set_expansion(EV_View *view, EV_Key parent_key, EV_Key key, B32 expanded)
EV_ExpandNode *prev = 0;
for(EV_ExpandNode *n = parent_node->first; n != 0; n = n->next)
{
if(n->key.child_num < key.child_num)
if(n->key.child_id < key.child_id)
{
prev = n;
}
@@ -621,23 +621,91 @@ ev2_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 st
}
// rjf: iterate children expansions, recurse
// TODO(rjf): need to iterate these in index order, rather than "child_num" (which needs to be renamed to "child_id") order
// TODO(rjf): need to iterate these in index order, rather than "child_id" (which needs to be renamed to "child_id") order
if(expand_info.row_count != 0 && expand_view_rule_info->expr_expand_range_info)
{
for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next)
// rjf: count children
U64 child_count = 0;
for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, child_count += 1){}
// rjf: gather children keys & numbers
B32 needs_sort = 0;
EV_Key *child_keys = push_array(scratch.arena, EV_Key, child_count);
U64 *child_nums = push_array(scratch.arena, U64, child_count);
{
U64 split_num = expand_view_rule_info->expr_expand_num_from_id(child->key.child_num, expand_info.user_data);
U64 idx = 0;
for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, idx += 1)
{
child_keys[idx] = child->key;
child_nums[idx] = expand_view_rule_info->expr_expand_num_from_id(child->key.child_id, expand_info.user_data);
if(child_nums[idx] != child_keys[idx].child_id)
{
needs_sort = 1;
}
}
}
// rjf: sort children by number, if needed
if(needs_sort)
{
for(U64 idx1 = 0; idx1 < child_count; idx1 += 1)
{
U64 min_idx2 = 0;
U64 min_num = child_nums[idx1];
for(U64 idx2 = idx1+1; idx2 < child_count; idx2 += 1)
{
if(child_nums[idx2] < min_num)
{
min_idx2 = idx2;
min_num = child_nums[idx2];
}
}
if(min_idx2 != 0)
{
Swap(EV_Key, child_keys[idx1], child_keys[min_idx2]);
Swap(U64, child_nums[idx1], child_nums[min_idx2]);
}
}
}
// rjf: iterate children expansions & generate recursion tasks
for(U64 idx = 0; idx < child_count; idx += 1)
{
U64 split_num = child_nums[idx];
U64 split_relative_idx = split_num - 1;
if(split_relative_idx >= expand_info.row_count)
{
continue;
}
EV_ExpandRangeInfo child_expand = expand_view_rule_info->expr_expand_range_info(arena, view, filter, t->expr, expand_params, r1u64(split_relative_idx, split_relative_idx+1), expand_info.user_data);
if(child_expand.row_exprs_count > 0)
{
EV_Key child_key = child_keys[idx];
E_Expr *child_expr = child_expand.row_exprs[0];
EV_ViewRuleList *child_view_rules = ev_view_rule_list_from_inheritance(arena, t->view_rules);
String8 child_view_rule_string = ev_view_rule_from_key(view, child_key);
if(child_view_rule_string.size != 0)
{
ev_view_rule_list_push_string(arena, child_view_rules, child_view_rule_string);
}
else
{
Temp scratch = scratch_begin(&arena, 1);
E_IRTreeAndType child_irtree = e_irtree_and_type_from_expr(scratch.arena, child_expr);
String8 child_auto_view_rule_string = ev_auto_view_rule_from_type_key(child_irtree.type_key);
if(child_auto_view_rule_string.size != 0)
{
ev_view_rule_list_push_string(arena, child_view_rules, child_auto_view_rule_string);
}
scratch_end(scratch);
}
E_Expr *child_expr__resolved = ev_expr_from_expr_view_rules(arena, child_expr, child_view_rules);
// TODO(rjf): need to mix in child's view rules
Task *task = push_array(scratch.arena, Task, 1);
SLLQueuePush(first_task, last_task, task);
task->parent_block = expansion_block;
task->expr = child_expand.row_exprs[0];
task->child_id = child->key.child_num;
task->expr = child_expr__resolved;
task->child_id = child_key.child_id;
task->view_rules = child_view_rules;
task->split_relative_idx = split_relative_idx;
}
@@ -843,7 +911,7 @@ ev2_num_from_key(EV2_BlockRangeList *block_ranges, EV_Key key)
U64 hash = ev_hash_from_key(n->v.block->key);
if(hash == key.parent_hash)
{
U64 relative_num = n->v.block->expand_view_rule_info->expr_expand_num_from_id(key.child_num, n->v.block->expand_view_rule_info_user_data);
U64 relative_num = n->v.block->expand_view_rule_info->expr_expand_num_from_id(key.child_id, n->v.block->expand_view_rule_info_user_data);
if(contains_1u64(n->v.range, relative_num-1))
{
result = base_num + (relative_num - 1 - n->v.range.min);
@@ -927,19 +995,38 @@ ev2_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8
{
U64 child_num = block_relative_range.min + num_skipped + idx + 1;
U64 child_id = n->v.block->expand_view_rule_info->expr_expand_id_from_num(child_num, n->v.block->expand_view_rule_info_user_data);
EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id);
E_Expr *row_expr = expand_range_info.row_exprs[idx];
EV_ViewRuleList *row_view_rules = ev_view_rule_list_from_inheritance(arena, n->v.block->view_rules);
String8 row_view_rule_string = ev_view_rule_from_key(view, row_key);
if(row_view_rule_string.size != 0)
{
ev_view_rule_list_push_string(arena, row_view_rules, row_view_rule_string);
}
else
{
Temp scratch = scratch_begin(&arena, 1);
E_IRTreeAndType row_irtree = e_irtree_and_type_from_expr(scratch.arena, row_expr);
String8 row_auto_view_rule_string = ev_auto_view_rule_from_type_key(row_irtree.type_key);
if(row_auto_view_rule_string.size != 0)
{
ev_view_rule_list_push_string(arena, row_view_rules, row_auto_view_rule_string);
}
scratch_end(scratch);
}
E_Expr *row_expr__resolved = ev_expr_from_expr_view_rules(arena, row_expr, row_view_rules);
EV2_Row *row = push_array(arena, EV2_Row, 1);
SLLQueuePush(rows.first, rows.last, row);
rows.count += 1;
row->block = n->v.block;
row->key = ev_key_make(ev_hash_from_key(row->block->key), child_id);
row->key = row_key;
row->visual_size = 1;
row->visual_size_skipped = 0; // TODO(rjf)
row->visual_size_chopped = 0; // TODO(rjf)
row->string = n->v.block->string;
row->expr = expand_range_info.row_exprs[idx];
row->expr = row_expr__resolved;
row->member = expand_range_info.row_members[idx];
row->view_rules = ev_view_rule_list_from_inheritance(arena, n->v.block->view_rules);
// TODO(rjf): mix in view rules based on row's key, row's type
row->view_rules = row_view_rules;
}
}
}
@@ -1182,8 +1269,8 @@ ev_block_list_from_view_expr_keys(Arena *arena, EV_View *view, String8 filter, E
block->string = expr;
block->expr = expr_resolved;
block->view_rules = view_rule_list;
block->visual_idx_range = r1u64(key.child_num-1, key.child_num+0);
block->semantic_idx_range = r1u64(key.child_num-1, key.child_num+0);
block->visual_idx_range = r1u64(key.child_id-1, key.child_id+0);
block->semantic_idx_range = r1u64(key.child_id-1, key.child_id+0);
ev_block_end(&blocks, block);
}
@@ -1229,12 +1316,12 @@ ev_row_num_from_block_list_key(EV_BlockList *blocks, EV_Key key)
{
if(block->fzy_backing_items.v != 0)
{
U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&block->fzy_backing_items, key.child_num);
U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&block->fzy_backing_items, key.child_id);
this_block_contains_this_key = (item_num != 0 && contains_1u64(block->semantic_idx_range, item_num-1));
}
else
{
this_block_contains_this_key = (block->semantic_idx_range.min+1 <= key.child_num && key.child_num < block->semantic_idx_range.max+1);
this_block_contains_this_key = (block->semantic_idx_range.min+1 <= key.child_id && key.child_id < block->semantic_idx_range.max+1);
}
}
if(this_block_contains_this_key)
@@ -1242,12 +1329,12 @@ ev_row_num_from_block_list_key(EV_BlockList *blocks, EV_Key key)
found = 1;
if(block->fzy_backing_items.v != 0)
{
U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&block->fzy_backing_items, key.child_num);
U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&block->fzy_backing_items, key.child_id);
row_num += item_num-1-block->semantic_idx_range.min;
}
else
{
row_num += key.child_num-1-block->semantic_idx_range.min;
row_num += key.child_id-1-block->semantic_idx_range.min;
}
break;
}
@@ -1281,12 +1368,12 @@ ev_key_from_block_list_row_num(EV_BlockList *blocks, S64 row_num)
U64 item_idx = (U64)((row_num - vb_row_num_range.min) + vb->semantic_idx_range.min);
if(item_idx < vb->fzy_backing_items.count)
{
key.child_num = vb->fzy_backing_items.v[item_idx].idx;
key.child_id = vb->fzy_backing_items.v[item_idx].idx;
}
}
else
{
key.child_num = vb->semantic_idx_range.min + (row_num - vb_row_num_range.min) + 1;
key.child_id = vb->semantic_idx_range.min + (row_num - vb_row_num_range.min) + 1;
}
break;
}
@@ -1355,7 +1442,7 @@ ev_expr_from_block_index(Arena *arena, EV_Block *block, U64 index)
FZY_Item *item = &block->fzy_backing_items.v[index];
EV_Key parent_key = block->parent_key;
EV_Key key = block->key;
key.child_num = block->fzy_backing_items.v[index].idx;
key.child_id = block->fzy_backing_items.v[index].idx;
// rjf: determine module to which this item belongs
E_Module *module = e_parse_ctx->primary_module;
@@ -11,7 +11,7 @@ typedef struct EV_Key EV_Key;
struct EV_Key
{
U64 parent_hash;
U64 child_num;
U64 child_id;
};
////////////////////////////////
@@ -461,7 +461,7 @@ global read_only EV2_Block ev2_nil_block = {&ev2_nil_block, &ev2_nil_block, &ev2
////////////////////////////////
//~ rjf: Key Functions
internal EV_Key ev_key_make(U64 parent_hash, U64 child_num);
internal EV_Key ev_key_make(U64 parent_hash, U64 child_id);
internal EV_Key ev_key_zero(void);
internal EV_Key ev_key_root(void);
internal B32 ev_key_match(EV_Key a, EV_Key b);
+13 -5
View File
@@ -5975,7 +5975,7 @@ rd_window_frame(RD_Window *ws)
B32 row_is_expanded = ev_expansion_from_key(ev_view, row->key);
if(row_is_expandable)
UI_PrefWidth(ui_em(1.5f, 1))
if(ui_pressed(ui_expanderf(row_is_expanded, "###%I64x_%I64x_is_expanded", row->key.parent_hash, row->key.child_num)))
if(ui_pressed(ui_expanderf(row_is_expanded, "###%I64x_%I64x_is_expanded", row->key.parent_hash, row->key.child_id)))
{
ev_key_set_expansion(ev_view, row->block->key, row->key, !row_is_expanded);
}
@@ -8506,12 +8506,20 @@ rd_ev_view_rule_expr_expand_range_info__debug_info_tables(Arena *arena, EV_View
internal U64
rd_ev_view_rule_expr_id_from_num__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section)
{
return num;
RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data;
U64 id = 0;
if(0 < num && num <= accel->items.count)
{
id = accel->items.v[num-1].idx+1;
}
return id;
}
internal U64
rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section)
rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 id, void *user_data, RDI_SectionKind section)
{
RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data;
U64 num = fzy_item_num_from_array_element_idx__linear_search(&accel->items, id-1);
return num;
}
@@ -8571,7 +8579,7 @@ rd_ev_view_rule_block_prod_collection_debug_tables(Arena *arena, RDI_SectionKind
U64 idx = 0;
for(EV_ExpandNode *child = root_node->first; child != 0; child = child->next)
{
U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&items, child->key.child_num);
U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&items, child->key.child_id);
if(item_num != 0)
{
sub_expand_keys[idx] = child->key;
@@ -8712,7 +8720,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul
}
//- rjf: member evaluations -> display member info
if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key) && member != 0)
if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key) && member != &e_member_nil)
{
U64 member_byte_size = e_type_byte_size_from_key(eval.type_key);
String8 offset_string = str8_from_u64(arena, member->off, radix, 0, 0);
+1 -1
View File
@@ -1291,7 +1291,7 @@ internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_ctrl_en
internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__debug_info_tables(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RDI_SectionKind section);
internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__debug_info_tables(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RDI_SectionKind section);
internal U64 rd_ev_view_rule_expr_id_from_num__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section);
internal U64 rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section);
internal U64 rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 id, void *user_data, RDI_SectionKind section);
internal void rd_ev_view_rule_block_prod_collection_debug_tables(Arena *arena, RDI_SectionKind target, EV_View *view, String8 filter, EV_Key parent_key, EV_Key key, EV_ExpandNode *expand_node, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, MD_Node *view_params, S32 depth, struct EV_BlockList *out);
internal EV_View *rd_ev_view_from_key(U64 key);
+8 -8
View File
@@ -1749,8 +1749,8 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
// rjf: map selection keys to child numbers
U64 selection_numbers[2] =
{
selection_block->expand_view_rule_info->expr_expand_num_from_id(selection_keys_in_block[0].child_num, selection_block->expand_view_rule_info_user_data),
selection_block->expand_view_rule_info->expr_expand_num_from_id(selection_keys_in_block[1].child_num, selection_block->expand_view_rule_info_user_data),
selection_block->expand_view_rule_info->expr_expand_num_from_id(selection_keys_in_block[0].child_id, selection_block->expand_view_rule_info_user_data),
selection_block->expand_view_rule_info->expr_expand_num_from_id(selection_keys_in_block[1].child_id, selection_block->expand_view_rule_info_user_data),
};
// rjf: determine collection info for the block
@@ -1949,7 +1949,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
B32 next_row_expanded = row_expanded;
RD_ViewRuleInfo *ui_view_rule_info = rd_view_rule_info_from_string(row->block->expand_view_rule_info->string);
MD_Node *ui_view_rule_params_root = row->block->expand_view_rule_params;
if(ui_view_rule_info->ui == 0)
if(ui_view_rule_info->ui == 0 || !(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanUseInWatchTable))
{
ui_view_rule_info = &rd_nil_view_rule_info;
ui_view_rule_params_root = &md_nil_node;
@@ -2231,9 +2231,9 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
//////////////////////
//- rjf: draw start of cache lines in expansions
//
U64 row_offset = row_eval.value.u64;
if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) &&
row_eval.value.u64%64 == 0 && row_depth > 0 &&
!row_expanded)
row_offset%64 == 0 && row_depth > 0 && !row_expanded)
{
ui_set_next_fixed_x(0);
ui_set_next_fixed_y(0);
@@ -2585,9 +2585,9 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
//- rjf: [DEV] hovering -> watch key tooltips
if(DEV_eval_watch_key_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code)
{
ui_labelf("Block Key: {0x%I64x, %I64u}", row->block->key.parent_hash, row->block->key.child_num);
ui_labelf("Row Key: {0x%I64x, %I64u}", row->key.parent_hash, row->key.child_num);
ui_labelf("Cursor Key: {0x%I64x, %I64u}", ewv->cursor.key.parent_hash, ewv->cursor.key.child_num);
ui_labelf("Block Key: {0x%I64x, %I64u}", row->block->key.parent_hash, row->block->key.child_id);
ui_labelf("Row Key: {0x%I64x, %I64u}", row->key.parent_hash, row->key.child_id);
ui_labelf("Cursor Key: {0x%I64x, %I64u}", ewv->cursor.key.parent_hash, ewv->cursor.key.child_id);
ui_spacer(ui_em(1.f, 1.f));
ui_labelf("Cursor Table Coordinates: {%I64u, %I64u}", selection_tbl.min.x, selection_tbl.min.y);
}