From 2da0554c782b9fd5a4d31109d822d6df704c55e7 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 14 Feb 2024 02:29:08 -0500 Subject: [PATCH] Not using dynamic map temporarily for font caching There is an issue with hot-reloading dynamic maps. So I'll be using my own dynamic array and hashtable instead to debug the reason. --- code/api.odin | 9 ++++++--- code/font_provider.odin | 22 ++++++++++++---------- code/tick_render.odin | 3 ++- code/tick_update.odin | 6 +++--- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/code/api.odin b/code/api.odin index 43f192e..58812b6 100644 --- a/code/api.odin +++ b/code/api.odin @@ -19,7 +19,7 @@ ModuleAPI :: struct { lib_version : i32, startup : type_of( startup ), - shutdown : type_of( sectr_shutdown), + shutdown : type_of( sectr_shutdown ), reload : type_of( reload ), tick : type_of( tick ), clean_temp : type_of( clean_temp ), @@ -141,12 +141,10 @@ startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ // } frame_1.color = Color_BG_TextBox - // Frame is getting interpreted as points (It doesn't have to be, I'm just doing it...) box_set_size( & frame_1, { 100, 50 } * CM_Per_Point ) frame_2.color = Color_BG_TextBox_Green box_set_size( & frame_2, { 60, 100 } * CM_Per_Point ) - // frame_1.position = { 1000, 1000 } } } } @@ -197,6 +195,11 @@ reload :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ L context.allocator = transient_allocator() context.temp_allocator = temp_allocator() + // Procedure Addresses are not preserved on hot-reload. They must be restored for persistent data. + // The only way to alleviate this is to either do custom handles to allocators + // Or as done below, correct containers using allocators on reload. + // Thankfully persistent dynamic allocations are rare, and thus we know exactly which ones they are. + // font_provider_data := & get_state().font_provider_data // font_provider_data.font_cache.allocator = arena_allocator( & font_provider_data.font_arena ) diff --git a/code/font_provider.odin b/code/font_provider.odin index 98d6d22..badd041 100644 --- a/code/font_provider.odin +++ b/code/font_provider.odin @@ -12,7 +12,7 @@ Font_Arena_Size :: 32 * Megabyte Font_Largest_Px_Size :: 96 // Font_Default :: "" -Font_Default :: 0 +Font_Default :: 0 Font_Default_Point_Size :: 18.0 Font_TTF_Default_Chars_Padding :: 4 @@ -21,14 +21,12 @@ Font_Load_Use_Default_Size :: -1 Font_Load_Gen_ID :: "" Font_Atlas_Packing_Method :: enum u32 { - Raylib_Basic = 0, // Basic packing algo + Raylib_Basic = 0, // Basic packing algo Skyeline_Rect = 1, // stb_pack_rect } -// TODO(Ed) : This isn't good enough for what we need font wise.. -Font :: rl.Font - -// TODO(Ed) : Use this instead of the raylib font directly +// TODO(Ed) : These are currently i32, I wanted them to be string ids for debug ease of use. +// There is an issue with the hash map type preventing me from doing so. Its allocator reference breaks. // FontID :: distinct string FontID :: distinct i32 FontTag :: struct { @@ -50,13 +48,14 @@ FontDef :: struct { data : [] u8, default_size : i32, size_table : [Font_Largest_Px_Size] FontGlyphsRender, + // TODO(Ed) : This is a rough way to do even multiplies, we are wasting half the array, I'll make a proper accessor/generation to it eventually. } FontProviderData :: struct { font_arena : Arena, //TODO(Ed) : There is an issue with hot-reload and map allocations that I can't figure out right now.. - // font_cache : map [FontID](FontDef), + // font_cache : ^ map [FontID](FontDef), font_cache : [10] FontDef, open_id : i32 } @@ -72,7 +71,7 @@ font_provider_startup :: proc() arena_init( & font_arena, data ) // font_cache = new( map[FontID](FontDef), arena_allocator( & font_arena ) ) - // font_cache = make_map( map[FontID](FontDef), capacity = 10, allocator = arena_allocator( & font_arena ) ) + // font_cache^ = make_map( map[FontID](FontDef), capacity = 10, allocator = arena_allocator( & font_arena ) ) open_id = 0 log("font_cache created") log("font_provider initialized") @@ -128,7 +127,8 @@ font_load :: proc ( path_file : string, // TODO(Ed): this is extremely slow // Render all sizes at once - for id : i32 = 0; id < Font_Largest_Px_Size; id += 1 + // Note(Ed) : We only generate textures for even multiples of the font. + for id : i32 = 1; id < Font_Largest_Px_Size; id += 2 { px_render := & def.size_table[id] using px_render @@ -168,11 +168,13 @@ Font_Use_Default_Size :: f32(0.0) to_rl_Font :: proc ( id : FontID, size := Font_Use_Default_Size ) -> rl.Font { font_provider_data := & get_state().font_provider_data; using font_provider_data - size := clamp( i32( math.round(size * 0.5) * 2.0), 8, Font_Largest_Px_Size ) + even_size := math.round(size * 0.5) * 2.0 + size := clamp( i32( even_size), 8, Font_Largest_Px_Size ) def := & font_cache[id] size = size if size != i32(Font_Use_Default_Size) else def.default_size px_render := & def.size_table[ size - 1 ] + // This is free for now perf wise... may have to move this out to on a setting change later. rl.SetTextureFilter( px_render.texture, rl.TextureFilter.TRILINEAR ) rl_font : rl.Font diff --git a/code/tick_render.odin b/code/tick_render.odin index a738482..9ccd00a 100644 --- a/code/tick_render.odin +++ b/code/tick_render.odin @@ -71,7 +71,8 @@ render :: proc() rl.EndDrawing() } -render_mode_2d :: proc() { +render_mode_2d :: proc() +{ state := get_state(); using state cam := & project.workspace.cam win_extent := state.app_window.extent diff --git a/code/tick_update.odin b/code/tick_update.odin index 8c9e3cd..85a8e5d 100644 --- a/code/tick_update.odin +++ b/code/tick_update.odin @@ -139,7 +139,7 @@ update :: proc( delta_time : f64 ) -> b32 cam := & project.workspace.cam digital_move_speed : f32 = 200.0 - zoom_sensitivity : f32 = 0.1 // Digital + zoom_sensitivity : f32 = 0.2 // Digital // zoom_sensitivity : f32 = 2.0 // Smooth if debug.zoom_target == 0.0 { @@ -149,12 +149,12 @@ update :: proc( delta_time : f64 ) -> b32 // Adjust zoom_target based on input, not the actual zoom zoom_delta := input.mouse.vertical_wheel * zoom_sensitivity debug.zoom_target *= 1 + zoom_delta //* f32(delta_time) - debug.zoom_target = clamp(debug.zoom_target, 0.5, 10.0) + debug.zoom_target = clamp(debug.zoom_target, 0.25, 10.0) // Linearly interpolate cam.zoom towards zoom_target lerp_factor := cast(f32) 4.0 // Adjust this value to control the interpolation speed cam.zoom += (debug.zoom_target - cam.zoom) * lerp_factor * f32(delta_time) - cam.zoom = clamp(cam.zoom, 0.5, 10.0) // Ensure cam.zoom stays within bounds + cam.zoom = clamp(cam.zoom, 0.25, 10.0) // Ensure cam.zoom stays within bounds move_velocity : Vec2 = { - cast(f32) i32(debug_actions.cam_move_left) + cast(f32) i32(debug_actions.cam_move_right),