Beginning to review progress on prototype codebase bootstrapping.

This commit is contained in:
2025-07-04 14:06:28 -04:00
parent ff91e41da9
commit 2e8381b097
14 changed files with 242 additions and 226 deletions

1
.gitignore vendored
View File

@ -26,3 +26,4 @@ ols.json
.vscode/settings.json
*.spall
sectr.user
sectr.proj

View File

@ -37,8 +37,8 @@ array_underlying_slice :: proc(slice: []($ Type)) -> Array(Type)
return array
}
array_to_slice :: #force_inline proc( using self : Array($ Type) ) -> []Type { return slice_ptr( data, int(num)) }
array_to_slice_capacity :: #force_inline proc( using self : Array($ Type) ) -> []Type { return slice_ptr( data, int(capacity)) }
array_to_slice :: #force_inline proc "contextless" ( using self : Array($ Type) ) -> []Type { return slice_ptr( data, int(num)) }
array_to_slice_capacity :: #force_inline proc "contextless" ( using self : Array($ Type) ) -> []Type { return slice_ptr( data, int(capacity)) }
array_grow_formula :: proc( value : u64 ) -> u64 {
result := (2 * value) + 8

View File

@ -1,48 +1,2 @@
package grime
when (false) {
KT1L_Slot :: struct($Type: typeid) {
key: u64,
value: Type,
}
KT1L_Meta :: struct {
slot_size: uintptr,
kt_value_offset: uintptr,
type_width: uintptr,
type_name: string,
}
kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: Allocator = context.allocator, values: []byte, num_values: int, m: KT1L_Meta) {
assert(kt != nil)
if num_values == 0 { return }
table_size_bytes := num_values * int(m.slot_size)
err : AllocatorError
kt^, err = alloc_bytes(table_size_bytes, allocator = backing)
slice_assert(kt ^)
kt_raw : Raw_Slice = transmute(Raw_Slice) kt^
for cursor in 0 ..< cast(uintptr) num_values {
slot_offset := cursor * m.slot_size
slot_cursor := uintptr(kt_raw.data) + slot_offset
slot_key := cast(^u64) slot_cursor
slot_value := transmute([]byte) Raw_Slice { cast([^]byte) (slot_cursor + m.kt_value_offset), int(m.type_width)}
a2_offset := cursor * m.type_width * 2
a2_cursor := uintptr(& values[a2_offset])
a2_key := (transmute(^[]byte) a2_cursor) ^
a2_value := transmute([]byte) Raw_Slice { rawptr(a2_cursor + m.type_width), int(m.type_width) }
copy(slot_value, a2_value)
slot_key^ = 0; hash64_djb8(slot_key, a2_key)
}
kt_raw.len = num_values
}
kt1l_populate_slice_a2 :: proc($Type: typeid, kt: ^[]KT1L_Slot(Type), backing: AllocatorInfo, values: [][2]Type) {
assert(kt != nil)
values_bytes := transmute([]byte) Raw_Slice{data = raw_data(values), len = len(values) * size_of([2]Type)}
kt1l_populate_slice_a2_Slice_Byte(transmute(^[]byte) kt, backing, values_bytes, len(values), {
slot_size = size_of(KT1L_Slot(Type)),
kt_value_offset = offset_of(KT1L_Slot(Type), KT1L_Slot(Type).value),
type_width = size_of(Type),
type_name = #type_string(Type),
})
}
}

View File

@ -1 +1,48 @@
package grime
when (false) {
KT1L_Slot :: struct($Type: typeid) {
key: u64,
value: Type,
}
KT1L_Meta :: struct {
slot_size: uintptr,
kt_value_offset: uintptr,
type_width: uintptr,
type_name: string,
}
kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: Allocator = context.allocator, values: []byte, num_values: int, m: KT1L_Meta) {
assert(kt != nil)
if num_values == 0 { return }
table_size_bytes := num_values * int(m.slot_size)
err : AllocatorError
kt^, err = alloc_bytes(table_size_bytes, allocator = backing)
slice_assert(kt ^)
kt_raw : Raw_Slice = transmute(Raw_Slice) kt^
for cursor in 0 ..< cast(uintptr) num_values {
slot_offset := cursor * m.slot_size
slot_cursor := uintptr(kt_raw.data) + slot_offset
slot_key := cast(^u64) slot_cursor
slot_value := transmute([]byte) Raw_Slice { cast([^]byte) (slot_cursor + m.kt_value_offset), int(m.type_width)}
a2_offset := cursor * m.type_width * 2
a2_cursor := uintptr(& values[a2_offset])
a2_key := (transmute(^[]byte) a2_cursor) ^
a2_value := transmute([]byte) Raw_Slice { rawptr(a2_cursor + m.type_width), int(m.type_width) }
copy(slot_value, a2_value)
slot_key^ = 0; hash64_djb8(slot_key, a2_key)
}
kt_raw.len = num_values
}
kt1l_populate_slice_a2 :: proc($Type: typeid, kt: ^[]KT1L_Slot(Type), backing: AllocatorInfo, values: [][2]Type) {
assert(kt != nil)
values_bytes := transmute([]byte) Raw_Slice{data = raw_data(values), len = len(values) * size_of([2]Type)}
kt1l_populate_slice_a2_Slice_Byte(transmute(^[]byte) kt, backing, values_bytes, len(values), {
slot_size = size_of(KT1L_Slot(Type)),
kt_value_offset = offset_of(KT1L_Slot(Type), KT1L_Slot(Type).value),
type_width = size_of(Type),
type_name = #type_string(Type),
})
}
}

View File

@ -64,7 +64,7 @@ str_cache_init :: proc( table_allocator, slabs_allocator : Allocator ) -> (cache
@static dbg_name := "StringCache slab"
// TODO(Ed): Is this nessary (essentially is there a perf impact of using vs not using, which is better because thats all that matters)
// TODO(Ed): Is this necessary (essentially is there a perf impact of using vs not using, which is better because thats all that matters)
// Interning should only be handled on a growing arena anyway so it doesn't really need this.
alloc_error : AllocatorError
cache.slab, alloc_error = slab_init( & policy, allocator = slabs_allocator, dbg_name = dbg_name )

View File

@ -216,9 +216,10 @@ State :: struct {
input_data : [2]InputState,
input_prev : ^InputState,
input : ^InputState,
input : ^InputState, // TODO(Ed): Rename to indicate its the device's signal state for the frame?
input_events : InputEvents,
input_events: InputEvents,
input_binds_stack: Array(InputContext),
// Note(Ed): Do not modify directly, use its interface in app/event.odin
staged_input_events : Array(InputEvent),
@ -292,4 +293,7 @@ get_screen_extent :: #force_inline proc "contextless" () -> Extents2 { retu
get_ui_context_mut :: #force_inline proc "contextless" () -> ^UI_State { return get_state().ui_context }
set_ui_context :: #force_inline proc "contextless" ( ui : ^UI_State ) { get_state().ui_context = ui }
get_input_binds :: #force_inline proc "contextless" () -> InputContext { return array_back(get_state().input_binds_stack) }
get_input_binds_stack :: #force_inline proc "contextless" () -> []InputContext { return array_to_slice(get_state().input_binds_stack) }
//endregion State

View File

@ -536,7 +536,7 @@ tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32
debug.draw_ui_box_bounds_points = false
debug.draw_ui_padding_bounds = false
debug.draw_ui_content_bounds = false
debug.draw_ui_content_bounds = true
// config.engine_refresh_hz = 165

View File

@ -454,6 +454,13 @@ render_ui_via_box_list :: proc( box_list : []UI_RenderBoxInfo, text_list : []UI_
shape_enqueued = true
}
if debug.draw_ui_content_bounds
{
render_set_color(RGBA8_Debug_UI_Content_Bounds)
draw_rect_border(entry.bounds, 1.0)
shape_enqueued = true
}
box_id += 1
}
@ -890,4 +897,4 @@ render_set_view_space :: #force_inline proc( extent : Extents2 )
gp.project( -extent.x, extent.x, extent.y, -extent.y )
}
//endregion Helpers
//endregion Helper

View File

@ -124,6 +124,8 @@ import "core:os"
import "core:path/filepath"
file_name_from_path :: filepath.short_stem
import "core:slice"
import "core:strconv"
parse_f32 :: strconv.parse_f32
parse_u64 :: strconv.parse_u64
@ -194,6 +196,7 @@ import "codebase:grime"
array_append_value :: grime.array_append_value
array_append_array :: grime.array_append_array
array_append_at :: grime.array_append_at
array_back :: grime.array_back
array_clear :: grime.array_clear
array_free :: grime.array_free
array_grow_formula :: grime.array_grow_formula
@ -366,6 +369,10 @@ append_at :: proc {
grime.array_append_at_slice,
}
back :: proc {
grime.array_back,
}
bivec3 :: proc {
bivec3_via_f32s,
vec3_to_bivec3,
@ -426,7 +433,7 @@ floor :: proc {
math.floor_f64le,
math.floor_f64be,
linalg.floor
linalg.floor,
}
from_bytes :: proc {
@ -717,4 +724,8 @@ wedge :: proc {
wedge_bivec3,
}
zero :: proc {
slice.zero,
}
//endregion Proc overload mappings

View File

@ -48,6 +48,7 @@ UI_InteractState :: struct {
disabled_time : f32,
}
// TODO(Ed): Make the key 128-bit?
UI_Key :: distinct u64
UI_Scalar :: f32

View File

@ -1,5 +1,163 @@
package sectr
ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_LayoutDirection_X, width_ref : ^f32 = nil )
{
container_width : f32
if width_ref != nil {
container_width = width_ref ^
}
else {
container_width = container.computed.content.max.x - container.computed.content.min.x
}
container_height := container.computed.content.max.y - container.computed.content.min.y
// do layout calculations for the children
total_stretch_ratio : f32 = 0.0
size_req_children : f32 = 0
for child := container.first; child != nil; child = child.next
{
using child.layout
scaled_width_by_height : b32 = b32(.Scale_Width_By_Height_Ratio in flags)
if .Scale_Width_By_Height_Ratio in flags
{
size_req_children += size.min.x * container_height
continue
}
if .Fixed_Width in flags
{
size_req_children += size.min.x
continue
}
size_req_children += size.min.x
total_stretch_ratio += anchor.ratio.x
}
avail_flex_space := container_width - size_req_children
allocate_space :: proc( child : ^UI_Box, total_stretch_ratio, avail_flex_space, container_height : f32 ) -> (space_allocated : f32)
{
using child.layout
if .Scale_Width_By_Height_Ratio in flags {
size.min.y = container_height
space_allocated = size.min.x * container_height
}
else if ! (.Fixed_Width in flags) {
potential_size := anchor.ratio.x * (1 / total_stretch_ratio) * avail_flex_space
space_allocated = max(potential_size, size.min.x)
size.min.x = space_allocated
}
else {
space_allocated = size.min.x
}
space_allocated -= margins.left - margins.right
size.min.x -= margins.left - margins.right
flags |= {.Fixed_Width}
return
}
space_used : f32 = 0.0
switch direction{
case .Left_To_Right:
for child := container.first; child != nil; child = child.next {
using child.layout
child_width := allocate_space(child, total_stretch_ratio, avail_flex_space, container_height)
anchor = range2({0, anchor.bottom}, {0, anchor.top})
alignment = {0, alignment.y}
pos.x = space_used
space_used += child_width + child.layout.margins.left + child.layout.margins.right
}
case .Right_To_Left:
for child := container.first; child != nil; child = child.next {
using child.layout
child_width := allocate_space(child, total_stretch_ratio, avail_flex_space, container_height)
anchor = range2({1, anchor.bottom}, {0, anchor.top})
alignment = {1, alignment.y}
pos.x = space_used
space_used -= child_width + child.layout.margins.left + child.layout.margins.right
}
}
}
ui_layout_children_vertically :: proc( container : ^UI_Box, direction : UI_LayoutDirection_Y, height_ref : ^f32 = nil )
{
container_height : f32
if height_ref != nil {
container_height = height_ref ^
}
else {
container_height = container.computed.content.max.y - container.computed.content.min.y
}
container_width := container.computed.content.max.x - container.computed.content.min.x
// do layout calculations for the children
total_stretch_ratio : f32 = 0.0
size_req_children : f32 = 0
for child := container.first; child != nil; child = child.next
{
using child.layout
scaled_height_by_width : b32 = b32(.Scale_Height_By_Width_Ratio in flags)
if scaled_height_by_width {
size_req_children += size.min.y * container_width
continue
}
if .Fixed_Height in flags
{
size_req_children += size.min.y
continue
}
size_req_children += size.min.y
total_stretch_ratio += anchor.ratio.y
}
avail_flex_space := container_height - size_req_children
allocate_space :: proc( child : ^UI_Box, total_stretch_ratio, avail_flex_space, container_width : f32 ) -> (space_allocated : f32)
{
using child.layout
if .Scale_Height_By_Width_Ratio in flags {
size.min.x = container_width
space_allocated = size.min.y * container_width
}
if ! (.Fixed_Height in flags) {
potential_size := (anchor.ratio.y * (1 / total_stretch_ratio) * avail_flex_space)
space_allocated = max(potential_size, size.min.y)
size.min.y = space_allocated
}
else {
space_allocated = size.min.y
}
space_allocated -= margins.top - margins.bottom
size.min.y -= margins.top - margins.bottom
flags |= {.Fixed_Height}
return
}
space_used : f32 = 0
switch direction
{
case .Top_To_Bottom:
for child := container.first; child != nil; child = child.next {
using child.layout
child_height := allocate_space(child, total_stretch_ratio, avail_flex_space, container_width)
anchor = range2({anchor.left, 1}, {anchor.right, 0})
alignment = {alignment.x, 1}
pos.y = space_used
space_used -= child_height - child.layout.margins.top - child.layout.margins.bottom
}
case .Bottom_To_Top:
for child := container.first; child != nil; child = child.next {
using child.layout
child_height := allocate_space(child, total_stretch_ratio, avail_flex_space, container_width)
anchor = range2({anchor.left,0}, {anchor.right, 0})
alignment = {alignment.x, 0}
pos.y = space_used
space_used += child_height - child.layout.margins.top - child.layout.margins.bottom
}
}
}
ui_box_compute_layout :: proc( box : ^UI_Box,
dont_mark_fresh : b32 = false,
ancestors_layout_required : b32 = false,

View File

@ -8,161 +8,3 @@ Widget Layout Ops
TODO(Ed): Review this file, these are can now be done with ui_box_compute_layout
*/
ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_LayoutDirection_X, width_ref : ^f32 = nil )
{
container_width : f32
if width_ref != nil {
container_width = width_ref ^
}
else {
container_width = container.computed.content.max.x - container.computed.content.min.x
}
container_height := container.computed.content.max.y - container.computed.content.min.y
// do layout calculations for the children
total_stretch_ratio : f32 = 0.0
size_req_children : f32 = 0
for child := container.first; child != nil; child = child.next
{
using child.layout
scaled_width_by_height : b32 = b32(.Scale_Width_By_Height_Ratio in flags)
if .Scale_Width_By_Height_Ratio in flags
{
size_req_children += size.min.x * container_height
continue
}
if .Fixed_Width in flags
{
size_req_children += size.min.x
continue
}
size_req_children += size.min.x
total_stretch_ratio += anchor.ratio.x
}
avail_flex_space := container_width - size_req_children
allocate_space :: proc( child : ^UI_Box, total_stretch_ratio, avail_flex_space, container_height : f32 ) -> (space_allocated : f32)
{
using child.layout
if .Scale_Width_By_Height_Ratio in flags {
size.min.y = container_height
space_allocated = size.min.x * container_height
}
else if ! (.Fixed_Width in flags) {
potential_size := anchor.ratio.x * (1 / total_stretch_ratio) * avail_flex_space
space_allocated = lalg.max(potential_size, size.min.x)
size.min.x = space_allocated
}
else {
space_allocated = size.min.x
}
space_allocated -= margins.left - margins.right
size.min.x -= margins.left - margins.right
flags |= {.Fixed_Width}
return
}
space_used : f32 = 0.0
switch direction{
case .Left_To_Right:
for child := container.first; child != nil; child = child.next {
using child.layout
child_width := allocate_space(child, total_stretch_ratio, avail_flex_space, container_height)
anchor = range2({0, anchor.bottom}, {0, anchor.top})
alignment = {0, alignment.y}
pos.x = space_used
space_used += child_width + child.layout.margins.left + child.layout.margins.right
}
case .Right_To_Left:
for child := container.first; child != nil; child = child.next {
using child.layout
child_width := allocate_space(child, total_stretch_ratio, avail_flex_space, container_height)
anchor = range2({1, anchor.bottom}, {0, anchor.top})
alignment = {1, alignment.y}
pos.x = space_used
space_used -= child_width + child.layout.margins.left + child.layout.margins.right
}
}
}
ui_layout_children_vertically :: proc( container : ^UI_Box, direction : UI_LayoutDirection_Y, height_ref : ^f32 = nil )
{
container_height : f32
if height_ref != nil {
container_height = height_ref ^
}
else {
container_height = container.computed.content.max.y - container.computed.content.min.y
}
container_width := container.computed.content.max.x - container.computed.content.min.x
// do layout calculations for the children
total_stretch_ratio : f32 = 0.0
size_req_children : f32 = 0
for child := container.first; child != nil; child = child.next
{
using child.layout
scaled_height_by_width : b32 = b32(.Scale_Height_By_Width_Ratio in flags)
if scaled_height_by_width {
size_req_children += size.min.y * container_width
continue
}
if .Fixed_Height in flags
{
size_req_children += size.min.y
continue
}
size_req_children += size.min.y
total_stretch_ratio += anchor.ratio.y
}
avail_flex_space := container_height - size_req_children
allocate_space :: proc( child : ^UI_Box, total_stretch_ratio, avail_flex_space, container_width : f32 ) -> (space_allocated : f32)
{
using child.layout
if .Scale_Height_By_Width_Ratio in flags {
size.min.x = container_width
space_allocated = size.min.y * container_width
}
if ! (.Fixed_Height in flags) {
potential_size := (anchor.ratio.y * (1 / total_stretch_ratio) * avail_flex_space)
space_allocated = lalg.max(potential_size, size.min.y)
size.min.y = space_allocated
}
else {
space_allocated = size.min.y
}
space_allocated -= margins.top - margins.bottom
size.min.y -= margins.top - margins.bottom
flags |= {.Fixed_Height}
return
}
space_used : f32 = 0
switch direction
{
case .Top_To_Bottom:
for child := container.first; child != nil; child = child.next {
using child.layout
child_height := allocate_space(child, total_stretch_ratio, avail_flex_space, container_width)
anchor = range2({anchor.left, 1}, {anchor.right, 0})
alignment = {alignment.x, 1}
pos.y = space_used
space_used -= child_height - child.layout.margins.top - child.layout.margins.bottom
}
case .Bottom_To_Top:
for child := container.first; child != nil; child = child.next {
using child.layout
child_height := allocate_space(child, total_stretch_ratio, avail_flex_space, container_width)
anchor = range2({anchor.left,0}, {anchor.right, 0})
alignment = {alignment.x, 0}
pos.y = space_used
space_used += child_height - child.layout.margins.top - child.layout.margins.bottom
}
}
}

View File

@ -209,10 +209,10 @@ push-location $path_root
$build_args += $flag_use_separate_modules
$build_args += $flag_thread_count + $CoreCount_Physical
# $build_args += $flag_optimize_none
# $build_args += $flag_optimize_minimal
$build_args += $flag_optimize_speed
$build_args += $flag_optimize_minimal
# $build_args += $flag_optimize_speed
# $build_args += $falg_optimize_aggressive
# $build_args += $flag_debug
$build_args += $flag_debug
$build_args += $flag_pdb_name + $pdb
$build_args += $flag_subsystem + 'windows'
# $build_args += $flag_show_system_calls
@ -289,8 +289,8 @@ push-location $path_root
# $build_args += $flag_micro_architecture_native
$build_args += $flag_use_separate_modules
$build_args += $flag_thread_count + $CoreCount_Physical
$build_args += $flag_optimize_none
# $build_args += $flag_optimize_minimal
# $build_args += $flag_optimize_none
$build_args += $flag_optimize_minimal
# $build_args += $flag_optimize_speed
# $build_args += $falg_optimize_aggressive
$build_args += $flag_debug

View File

@ -1,9 +0,0 @@
// raddbg 0.9.18 project file
recent_file: path: "code/host/host.odin"
target:
{
executable: "build/sectr_host.exe"
working_directory: build
enabled: 1
}