Began to reduce direct referencing of mutable state struct
This commit is contained in:
parent
9da86c1f4b
commit
57d51fc7b1
@ -23,7 +23,11 @@ The dependencies are:
|
||||
* I added support for 'monlithic packages' or 'uniform-across-subdirectories packages'. It allows me to organize the main package with sub-directories.
|
||||
* Odin repo's base, core, and vendor(raylib) libaries
|
||||
* An ini parser
|
||||
* backtrace
|
||||
* backtrace (not used yet)
|
||||
* freetype (not used yet)
|
||||
* harfbuzz
|
||||
* sokol
|
||||
* sokol-tools
|
||||
* Powershell (if you want to use my build scripts)
|
||||
|
||||
Major 'codebase modules':
|
||||
|
@ -271,11 +271,11 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
// path_squidgy_slimes := strings.concatenate( { Path_Assets, "Squidgy Slimes.ttf" } )
|
||||
// font_squidgy_slimes = font_load( path_squidgy_slimes, 32.0, "Squidgy_Slime" )
|
||||
|
||||
// path_firacode := strings.concatenate( { Path_Assets, "FiraCode-Regular.ttf" } )
|
||||
// font_firacode = font_load( path_firacode, 16.0, "FiraCode" )
|
||||
|
||||
path_fira_cousine := strings.concatenate( { Path_Assets, "FiraCousine-Regular.ttf" } )
|
||||
font_fira_cousine = font_load( path_fira_cousine, 16.0, "Fira Cousine" )
|
||||
path_firacode := strings.concatenate( { Path_Assets, "FiraCode-Regular.ttf" } )
|
||||
font_firacode = font_load( path_firacode, 16.0, "FiraCode" )
|
||||
|
||||
// path_fira_cousine := strings.concatenate( { Path_Assets, "FiraCousine-Regular.ttf" } )
|
||||
// font_fira_cousine = font_load( path_fira_cousine, 16.0, "Fira Cousine" )
|
||||
|
||||
// path_open_sans := strings.concatenate( { Path_Assets, "OpenSans-Regular.ttf" } )
|
||||
// font_open_sans = font_load( path_open_sans, 16.0, "OpenSans" )
|
||||
@ -298,7 +298,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
// path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } )
|
||||
// font_arial_unicode_ms = font_load( path_arial_unicode_ms, 16.0, "Arial_Unicode_MS" )
|
||||
|
||||
default_font = font_fira_cousine
|
||||
default_font = font_firacode
|
||||
log( "Default font loaded" )
|
||||
}
|
||||
|
||||
@ -319,7 +319,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
}
|
||||
|
||||
// Demo project setup
|
||||
// TODO(Ed): This will eventually have to occur when the user either creates or loads a workspace. I don't know
|
||||
// TODO(Ed): This will eventually have to occur when the user either creates or loads a workspace.
|
||||
if true
|
||||
{
|
||||
profile("project setup")
|
||||
@ -499,21 +499,17 @@ tick :: proc( host_delta_time_ms : f64, host_delta_ns : Duration ) -> b32
|
||||
// Lifted out of tick so that sokol_app_frame_callback can do it as well.
|
||||
tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32
|
||||
{
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
state := get_state(); using state
|
||||
profile("Work frame")
|
||||
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
should_close : b32
|
||||
|
||||
// Setup Frame Slab
|
||||
{
|
||||
alloc_error : AllocatorError
|
||||
frame_slab, alloc_error = slab_init( & default_slab_policy, bucket_reserve_num = 0,
|
||||
allocator = frame_allocator(),
|
||||
dbg_name = Frame_Slab_DBG_Name,
|
||||
should_zero_buckets = true )
|
||||
verify( alloc_error == .None, "Failed to allocate frame slab" )
|
||||
}
|
||||
alloc_error : AllocatorError
|
||||
get_state().frame_slab, alloc_error = slab_init( & get_state().default_slab_policy, bucket_reserve_num = 0,
|
||||
allocator = frame_allocator(),
|
||||
dbg_name = Frame_Slab_DBG_Name,
|
||||
should_zero_buckets = true )
|
||||
verify( alloc_error == .None, "Failed to allocate frame slab" )
|
||||
|
||||
// The policy for the work tick is that the default allocator is the frame's slab.
|
||||
// Transient's is the temp allocator.
|
||||
@ -522,6 +518,9 @@ tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32
|
||||
|
||||
// rl.PollInputEvents()
|
||||
|
||||
config := app_config()
|
||||
debug := & get_state().debug
|
||||
|
||||
debug.draw_ui_box_bounds_points = false
|
||||
debug.draw_ui_padding_bounds = false
|
||||
debug.draw_ui_content_bounds = false
|
||||
@ -535,7 +534,7 @@ tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32
|
||||
sokol_width := sokol_app.widthf()
|
||||
sokol_height := sokol_app.heightf()
|
||||
|
||||
window := & state.app_window
|
||||
window := & get_state().app_window
|
||||
// if int(window.extent.x) != int(sokol_width) || int(window.extent.y) != int(sokol_height) {
|
||||
window.resized = true
|
||||
window.extent.x = sokol_width * 0.5
|
||||
@ -554,23 +553,24 @@ tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32
|
||||
tick_frametime :: #force_inline proc( client_tick : ^time.Tick, host_delta_time_ms : f64, host_delta_ns : Duration, can_sleep := true )
|
||||
{
|
||||
profile(#procedure)
|
||||
state := get_state(); using state
|
||||
config := app_config()
|
||||
frametime := & get_state().frametime
|
||||
context.allocator = frame_slab_allocator()
|
||||
context.temp_allocator = transient_allocator()
|
||||
|
||||
// profile("Client tick timing processing")
|
||||
|
||||
frametime_target_ms = 1.0 / f64(config.engine_refresh_hz) * S_To_MS
|
||||
sub_ms_granularity_required := frametime_target_ms <= Frametime_High_Perf_Threshold_MS
|
||||
frametime.target_ms = 1.0 / f64(config.engine_refresh_hz) * S_To_MS
|
||||
sub_ms_granularity_required := frametime.target_ms <= Frametime_High_Perf_Threshold_MS
|
||||
|
||||
frametime_delta_ns = time.tick_lap_time( client_tick )
|
||||
frametime_delta_ms = duration_ms( frametime_delta_ns )
|
||||
frametime_delta_seconds = duration_seconds( host_delta_ns )
|
||||
frametime_elapsed_ms = frametime_delta_ms + host_delta_time_ms
|
||||
frametime.delta_ns = time.tick_lap_time( client_tick )
|
||||
frametime.delta_ms = duration_ms( frametime.delta_ns )
|
||||
frametime.delta_seconds = duration_seconds( host_delta_ns )
|
||||
frametime.elapsed_ms = frametime.delta_ms + host_delta_time_ms
|
||||
|
||||
if frametime_elapsed_ms < frametime_target_ms
|
||||
if frametime.elapsed_ms < frametime.target_ms
|
||||
{
|
||||
sleep_ms := frametime_target_ms - frametime_elapsed_ms
|
||||
sleep_ms := frametime.target_ms - frametime.elapsed_ms
|
||||
pre_sleep_tick := time.tick_now()
|
||||
|
||||
if can_sleep && sleep_ms > 0 {
|
||||
@ -585,24 +585,24 @@ tick_frametime :: #force_inline proc( client_tick : ^time.Tick, host_delta_time_
|
||||
// log( str_fmt_tmp("frametime sleep was off by: %v ms", sleep_delta_ms - sleep_ms ))
|
||||
}
|
||||
|
||||
frametime_elapsed_ms += sleep_delta_ms
|
||||
for ; frametime_elapsed_ms < frametime_target_ms; {
|
||||
frametime.elapsed_ms += sleep_delta_ms
|
||||
for ; frametime.elapsed_ms < frametime.target_ms; {
|
||||
sleep_delta_ns = time.tick_lap_time( & pre_sleep_tick)
|
||||
sleep_delta_ms = duration_ms( sleep_delta_ns )
|
||||
|
||||
frametime_elapsed_ms += sleep_delta_ms
|
||||
frametime.elapsed_ms += sleep_delta_ms
|
||||
}
|
||||
}
|
||||
|
||||
config.timing_fps_moving_avg_alpha = 0.99
|
||||
frametime_avg_ms = mov_avg_exp( f64(config.timing_fps_moving_avg_alpha), frametime_elapsed_ms, frametime_avg_ms )
|
||||
fps_avg = 1 / (frametime_avg_ms * MS_To_S)
|
||||
frametime.avg_ms = mov_avg_exp( f64(config.timing_fps_moving_avg_alpha), frametime.elapsed_ms, frametime.avg_ms )
|
||||
frametime.fps_avg = 1 / (frametime.avg_ms * MS_To_S)
|
||||
|
||||
if frametime_elapsed_ms > 60.0 {
|
||||
log( str_fmt("Big tick! %v ms", frametime_elapsed_ms), LogLevel.Warning )
|
||||
if frametime.elapsed_ms > 60.0 {
|
||||
log( str_fmt("Big tick! %v ms", frametime.elapsed_ms), LogLevel.Warning )
|
||||
}
|
||||
|
||||
frame += 1
|
||||
frametime.current_frame += 1
|
||||
}
|
||||
|
||||
@export
|
||||
|
@ -17,8 +17,8 @@ sokol_app_init_callback :: proc "c" () {
|
||||
// So this will only get called during window pan or resize events (on Win32 at least)
|
||||
sokol_app_frame_callback :: proc "c" ()
|
||||
{
|
||||
context = get_state().sokol_context
|
||||
profile(#procedure)
|
||||
context = get_state().sokol_context
|
||||
|
||||
state := get_state()
|
||||
should_close : b32
|
||||
@ -99,14 +99,13 @@ sokol_app_log_callback :: proc "c" (
|
||||
// TODO(Ed): Does this need to be queued to a separate thread?
|
||||
sokol_app_event_callback :: proc "c" (sokol_event : ^sokol_app.Event)
|
||||
{
|
||||
state := get_state(); using state
|
||||
context = sokol_context
|
||||
context = get_state().sokol_context
|
||||
|
||||
event : InputEvent
|
||||
using event
|
||||
|
||||
_sokol_frame_id = sokol_event.frame_count
|
||||
frame_id = frame
|
||||
frame_id = get_frametime().current_frame
|
||||
|
||||
mouse.pos = { sokol_event.mouse_x, sokol_event.mouse_y }
|
||||
mouse.delta = { sokol_event.mouse_dx, sokol_event.mouse_dy }
|
||||
|
@ -22,7 +22,7 @@ RenderState :: struct {
|
||||
render :: proc()
|
||||
{
|
||||
profile(#procedure)
|
||||
state := get_state(); using state // TODO(Ed): Prefer passing static context to through the callstack
|
||||
state := get_state(); using state // TODO(Ed): Remove mutable access to to entire state.
|
||||
|
||||
screen_extent := app_window.extent
|
||||
screen_size := app_window.extent * 2
|
||||
@ -152,7 +152,7 @@ render_mode_screenspace :: proc( screen_extent : Extents2, screen_ui : ^UI_State
|
||||
|
||||
debug_draw_text :: proc( content : string, pos : Vec2, size : f32, color := Color_White, font : FontID = Font_Default )
|
||||
{
|
||||
state := get_state(); using state
|
||||
state := get_state(); using state // TODO(Ed): Remove this state getter. Get default font properly.
|
||||
if len( content ) == 0 do return
|
||||
|
||||
font := font
|
||||
@ -187,11 +187,12 @@ render_mode_screenspace :: proc( screen_extent : Extents2, screen_ui : ^UI_State
|
||||
}
|
||||
|
||||
if true {
|
||||
frametime := get_frametime()
|
||||
debug_text( "Screen Width : %v", screen_size.x )
|
||||
debug_text( "Screen Height: %v", screen_size.y )
|
||||
debug_text( "frametime_target_ms : %f ms", frametime_target_ms )
|
||||
debug_text( "frametime (work) : %0.3f ms", frametime_delta_ms )
|
||||
debug_text( "frametime_last_elapsed_ms : %f ms", frametime_elapsed_ms )
|
||||
debug_text( "frametime_target_ms : %f ms", frametime.target_ms )
|
||||
debug_text( "frametime (work) : %0.3f ms", frametime.delta_ms )
|
||||
debug_text( "frametime_last_elapsed_ms : %f ms", frametime.elapsed_ms )
|
||||
}
|
||||
if replay.mode == ReplayMode.Record {
|
||||
debug_text( "Recording Input")
|
||||
@ -450,6 +451,7 @@ render_text_layer :: proc( screen_extent : Vec2, ve_ctx : ^ve.Context, render :
|
||||
|
||||
render_ui_via_box_tree :: proc( ui : ^UI_State, screen_extent : Vec2, ve_ctx : ^ve.Context, ve_render : VE_RenderData, cam : ^Camera = nil )
|
||||
{
|
||||
// TODO(Ed): Make a debug getter.
|
||||
debug := get_state().debug
|
||||
default_font := get_state().default_font
|
||||
|
||||
@ -801,8 +803,6 @@ draw_text_string_pos_norm :: proc( content : string, id : FontID, size : f32, po
|
||||
width := app_window.extent.x * 2
|
||||
height := app_window.extent.y * 2
|
||||
|
||||
// TODO(Ed): Review doing double scaling on the text...
|
||||
|
||||
ve_id, resolved_size := font_provider_resolve_draw_id( id, size * config.font_size_screen_scalar )
|
||||
color_norm := normalize_rgba8(color)
|
||||
|
||||
@ -825,7 +825,7 @@ draw_text_string_pos_extent :: proc( content : string, id : FontID, size : f32,
|
||||
draw_text_string_pos_extent_zoomed :: proc( content : string, id : FontID, size : f32, pos : Vec2, cam : Camera, color := Color_White )
|
||||
{
|
||||
profile(#procedure)
|
||||
state := get_state(); using state
|
||||
state := get_state(); using state // TODO(Ed): Remove usage of direct access to entire mutable state.
|
||||
|
||||
cam_offset := Vec2 {
|
||||
cam.position.x,
|
||||
@ -871,6 +871,7 @@ draw_text_string_pos_extent_zoomed :: proc( content : string, id : FontID, size
|
||||
render_flush_gp :: #force_inline proc()
|
||||
{
|
||||
profile(#procedure)
|
||||
// TODO(Ed): Perfer a non-mutable get to the pass.
|
||||
gfx.begin_pass( gfx.Pass { action = get_state().render_data.pass_actions.empty_action, swapchain = sokol_glue.swapchain() })
|
||||
gp.flush()
|
||||
gfx.end_pass()
|
||||
|
@ -56,14 +56,11 @@ poll_debug_actions :: proc( actions : ^ DebugActions, input : ^ InputState )
|
||||
cam_mouse_pan = mouse.right.ended_down && ! pressed(mouse.right)
|
||||
}
|
||||
|
||||
frametime_delta32 :: #force_inline proc "contextless" () -> f32 {
|
||||
return cast(f32) get_state().frametime_avg_ms
|
||||
}
|
||||
|
||||
//TODO(Ed): Just use avg delta not this.
|
||||
update :: proc( delta_time : f64 ) -> b32
|
||||
{
|
||||
profile(#procedure)
|
||||
// TODO(Ed): Remove usage of mutable reference to state here.
|
||||
state := get_state(); using state
|
||||
replay := & Memory_App.replay
|
||||
workspace := & project.workspace
|
||||
@ -259,7 +256,7 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
|
||||
if zoom_delta != 0 {
|
||||
current_index := find_closest_zoom_index(cam.zoom, Digial_Zoom_Snap_Levels)
|
||||
scroll_speed := max(1, abs(zoom_delta) * config.cam_zoom_scroll_delta_scale) // Adjust this factor to control sensitivity
|
||||
scroll_speed := max( cast(f32) 1, abs(zoom_delta) * config.cam_zoom_scroll_delta_scale) // Adjust this factor to control sensitivity
|
||||
target_index := current_index
|
||||
|
||||
if zoom_delta > 0 {
|
||||
|
@ -428,9 +428,17 @@ make :: proc {
|
||||
make_multi_pointer,
|
||||
}
|
||||
|
||||
// measure_text_size :: proc {
|
||||
// measure_text_size_raylib,
|
||||
// }
|
||||
max :: proc {
|
||||
linalg.max_single,
|
||||
linalg.max_double,
|
||||
linalg.max_triple,
|
||||
}
|
||||
|
||||
min :: proc {
|
||||
linalg.min_single,
|
||||
linalg.min_double,
|
||||
linalg.min_triple,
|
||||
}
|
||||
|
||||
mov_avg_exp :: proc {
|
||||
mov_avg_exp_f32,
|
||||
|
@ -285,3 +285,19 @@ poll_input_events :: proc( input, prev_input : ^InputState, input_events : Input
|
||||
|
||||
prev_frame = last_frame
|
||||
}
|
||||
|
||||
input_event_iter :: #force_inline proc () -> RingBufferFixedIterator(InputEvent) {
|
||||
return iterator_ringbuf_fixed( & get_state().input_events.events )
|
||||
}
|
||||
|
||||
input_key_event_iter :: #force_inline proc() -> RingBufferFixedIterator(InputKeyEvent) {
|
||||
return iterator_ringbuf_fixed( & get_state().input_events.key_events )
|
||||
}
|
||||
|
||||
input_mouse_event_iter :: #force_inline proc() -> RingBufferFixedIterator(InputMouseEvent) {
|
||||
return iterator_ringbuf_fixed( & get_state().input_events.mouse_events )
|
||||
}
|
||||
|
||||
input_codes_pressed_slice :: #force_inline proc() -> []rune {
|
||||
return to_slice( get_state().input_events.codes_pressed )
|
||||
}
|
||||
|
@ -587,10 +587,9 @@ ui_text_input_box :: proc( text_input_box : ^UI_TextInputBox, label : string,
|
||||
policy : UI_TextInput_Policy = {}
|
||||
)
|
||||
{
|
||||
state := get_state()
|
||||
// state := get_state()
|
||||
iter_next :: next
|
||||
input := state.input
|
||||
input_events := & get_state().input_events
|
||||
input := get_input_state()
|
||||
ui := ui_context()
|
||||
|
||||
text_input_box.box = ui_box_make( flags, label )
|
||||
@ -621,7 +620,7 @@ ui_text_input_box :: proc( text_input_box : ^UI_TextInputBox, label : string,
|
||||
|
||||
// TODO(Ed): Abstract this to navigation bindings
|
||||
if btn_pressed(input.keyboard.left) {
|
||||
editor_cursor_pos.x = max(0, editor_cursor_pos.x - 1)
|
||||
editor_cursor_pos.x = max(editor_cursor_pos.x - 1, 0)
|
||||
}
|
||||
if btn_pressed(input.keyboard.right) {
|
||||
editor_cursor_pos.x = min(i32(input_str.num), editor_cursor_pos.x + 1)
|
||||
@ -638,14 +637,14 @@ ui_text_input_box :: proc( text_input_box : ^UI_TextInputBox, label : string,
|
||||
// screen_ui.active = 0
|
||||
// }
|
||||
|
||||
iter_obj := iterator( & input_events.key_events ); iter := & iter_obj
|
||||
iter_obj := input_key_event_iter(); iter := & iter_obj
|
||||
for event := iter_next( iter ); event != nil; event = iter_next( iter )
|
||||
{
|
||||
if event.frame_id != state.frame do break
|
||||
if event.frame_id != get_frametime().current_frame do break
|
||||
|
||||
if event.key == .backspace && event.type == .Key_Pressed {
|
||||
if input_str.num > 0 {
|
||||
editor_cursor_pos.x = max(0, editor_cursor_pos.x - 1)
|
||||
editor_cursor_pos.x = max(editor_cursor_pos.x - 1, 0)
|
||||
remove_at( input_str, u64(editor_cursor_pos.x) )
|
||||
break
|
||||
}
|
||||
@ -657,7 +656,7 @@ ui_text_input_box :: proc( text_input_box : ^UI_TextInputBox, label : string,
|
||||
}
|
||||
|
||||
decimal_detected := false
|
||||
for code in to_slice(input_events.codes_pressed)
|
||||
for code in input_codes_pressed_slice()
|
||||
{
|
||||
accept_digits := ! digits_only || '0' <= code && code <= '9'
|
||||
accept_decimal := ! disallow_decimal || ! decimal_detected && code =='.'
|
||||
@ -680,7 +679,7 @@ ui_text_input_box :: proc( text_input_box : ^UI_TextInputBox, label : string,
|
||||
continue
|
||||
}
|
||||
}
|
||||
clear( input_events.codes_pressed )
|
||||
clear( get_state().input_events.codes_pressed )
|
||||
|
||||
invalid_color := RGBA8 { 70, 40, 40, 255}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user