// Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) //////////////////////////////// //~ rjf: Built-In View Rules // // @view_rule_info // // NOTE(rjf): View rules are subtle in that they may impact any subset of the // eval visualization pipeline. The "array" view rule, for example, functions // by tweaking the type of an eval from `X *` to `X (*)[N]` (where N is // computed from whatever expression is specified by the view rule). The "list" // view rule, on the other hand, does not require any changes to the actual // eval nor its type - instead, it follows an alternative path in constructing // "viz blocks", and then constructing "viz rows" from those blocks. Compare // these to the simpler 'dec', 'bin', or 'oct' rules, which simply tweak the // radix used when stringizing numbers, which is something that only occurs in // single-line eval stringization building. // // As such, each view rule specification has a mask, which determines which // stages it may be used for. For a given view rule specification, if the bit // corresponding to a particular eval stage is set, then that view rule spec- // -ification also includes a hook which can be called from that stage. // // Below is a list of the stages in the eval visualization pipeline, as well as // abbreviations which are used in the tables. // // expr resolution, "xp" -> provides a chance for a view rule to make // modifications to expression trees that it is // applied to // // viz block prod, "vb" -> given a resolved eval, produce a list of non- // windowed "viz blocks", which correspond to one or // many contiguous rows in a watch-window-style UI. // one level of expanded struct members, with no sub- // expansions, would be one viz block. if one of those // members - in the middle - were expanded too, then // it would require three viz blocks - one for the // members before the sub-expansion, one for the // sub expansion members, and one for the members // after, and so on. this is done recursively. // // viz row prod, "vr" -> given a list of viz blocks, a windowed list of viz // rows may be produced. each of these rows has info // for building actual UI in e.g. a watch window - // whether or not the row can be expanded, whether or // not the row's value can be edited, what the edit- // able string is for a row, what the display string // is for a row, what the expression string is for a // row, what the type is for a row, and so on. // // line stringize, "ls" -> this is the stage used to produce display strings // in the "viz row prod" stage, as well as basically // any time UI needs to display the result of an eval // in a single line. this also occurs recursively, // descending into members & elements as needed, // constrained by # of available pixels and font size // and so on. // // row ui build, "ru" -> finally, after the previous stages are completed, // ui can finally be built according to all of the // per-row information produced. this is the stage // where view rules can insert their own arbitrary ui // on a per-row basis. // // view ui build, "vu" -> view rules which want to supply more sophisticated // visualizers have the ability to provide full // arbitrary UI hooks, which can either be produced // in a minified form via watch views, or via a // standalone tab. // // A few other bits are included for various ways in which a view rule may be // applied throughout the eval visualization pipeline. A list follows: // // inherited, "ih" -> is this view rule included, or not included, in // child expansions? // // expandable, "ex" -> does this view rule force the ability to expand // an expression, even if traditional analysis of type // info would not allow expansion? // // Not all of these stages are specified at this layer, however, since the // "df_core" layer is for the non-graphical core debugger features. So the // information pertaining to the eval visualization pipeline stages which // do require graphical subsystems (e.g. UI, fonts, rendering) are specified // in the "df_gfx" layer. // // For any view rules in this layer which also have graphical features, they // are specified in both tables under the same name. @table(coverage_check name name_lower string ih ex xr xe vb display_name docs schema description) EV_ViewRuleTable: { {x Default default "default" - - - x x "Default" - "" "" } {x Array array "array" - - x - - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } {x Slice slice "slice" - - x - - "Slice" x "" "Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer." } {x ByteSwap bswap "bswap" x - x - - "Byte Swap" x "" "Specifies that all integral evaluations should be byte-swapped, such that their endianness is reversed." } {x Cast cast "cast" - - x - - "Cast" x "x:{type}" "Specifies that the expression to which the view rule is applied should be casted to the provided type." } {x Only only "only" x - x - - "Only" x "" "Specifies that only the provided member names should be shown in user-defined-type expansions." } {x Omit omit "omit" x - x - - "Omit" x "" "Specifies that the provided member names should not be shown in user-defined-type expansions." } {x Bin bin "bin" x - - - - "Display In Binary" x "" "Specifies that all numeric values should be shown in base 2 (binary)." } {x Oct oct "oct" x - - - - "Display In Octal" x "" "Specifies that all numeric values should be shown in base 8 (octal)." } {x Dec dec "dec" x - - - - "Display In Decimal" x "" "Specifies that all numeric values should be shown in base 10 (decimal)." } {x Hex hex "hex" x - - - - "Display In Hexadecimal" x "" "Specifies that all numeric values should be shown in base 16 (hexadecimal)." } } @enum EV_ViewRuleKind: { @expand(EV_ViewRuleTable a) `$(a.name)`, COUNT, } @gen { @expand(EV_ViewRuleTable a) `$(a.xr == "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(" .. a.name_lower .. ");")`; @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; } @data(EV_ViewRuleInfo) @c_file ev_builtin_view_rule_info_table: { @expand(EV_ViewRuleTable a) ```{str8_lit_comp("$(a.string)"), (EV_ViewRuleInfoFlag_Inherited*$(a.ih == "x"))|(EV_ViewRuleInfoFlag_Expandable*$(a.ex == "x")), $(a.xr == "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.xr != "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil)"), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }```; }