got multi-laned hot-reload

This commit is contained in:
2025-10-13 02:13:58 -04:00
parent 8ced7cc71e
commit 5f57cea027
18 changed files with 499 additions and 176 deletions

33
code2/grime/assert.odin Normal file
View File

@@ -0,0 +1,33 @@
package grime
import "core:os"
// Below should be defined per-package
ensure :: #force_inline proc( condition : b32, msg : string, location := #caller_location )
{
if condition {
return
}
log_print( msg, LoggerLevel.Warning, location )
debug_trap()
}
// TODO(Ed) : Setup exit codes!
fatal :: #force_inline proc( msg : string, exit_code : int = -1, location := #caller_location )
{
log_print( msg, LoggerLevel.Fatal, location )
debug_trap()
process_exit( exit_code )
}
// TODO(Ed) : Setup exit codes!
verify :: #force_inline proc( condition : b32, msg : string, exit_code : int = -1, location := #caller_location )
{
if condition {
return
}
log_print( msg, LoggerLevel.Fatal, location )
debug_trap()
process_exit( exit_code )
}

View File

@@ -8,7 +8,7 @@ file_copy_sync :: proc( path_src, path_dst: string, allocator := context.allocat
{
path_info, result := file_status( path_src, allocator )
if result != OS_ERROR_NONE {
log_fmt("Could not get file info: %v", result, LoggerLevel.Error )
log_print_fmt("Could not get file info: %v", result, LoggerLevel.Error )
return false
}
file_size = path_info.size
@@ -16,14 +16,14 @@ file_copy_sync :: proc( path_src, path_dst: string, allocator := context.allocat
src_content, result := file_read_entire( path_src, allocator )
if ! result {
log_fmt( "Failed to read file to copy: %v", path_src, LoggerLevel.Error )
log_print_fmt( "Failed to read file to copy: %v", path_src, LoggerLevel.Error )
debug_trap()
return false
}
result = file_write_entire( path_dst, src_content, false )
if ! result {
log_fmt( "Failed to copy file: %v", path_dst, LoggerLevel.Error )
log_print_fmt( "Failed to copy file: %v", path_dst, LoggerLevel.Error )
debug_trap()
return false
}

View File

@@ -17,4 +17,3 @@ sll_queue_push_nz :: proc "contextless" (first: ^$ParentType, last, n: ^^$Type,
}
}
sll_queue_push_n :: #force_inline proc "contextless" (first: $ParentType, last, n: ^^$Type) { sll_queue_push_nz(first, last, n, nil) }

View File

@@ -42,26 +42,10 @@ logger_init :: proc( logger : ^ Logger, id : string, file_path : string, file :
LOGGER_VARENA_BASE_ADDRESS : uintptr = 2 * Tera
@static vmem_init_counter : uintptr = 0
// alloc_error : AllocatorError
// logger.varena, alloc_error = varena_init(
// LOGGER_VARENA_BASE_ADDRESS + vmem_init_counter * 250 * Megabyte,
// 1 * Megabyte,
// 128 * Kilobyte,
// growth_policy = nil,
// allow_any_resize = true,
// dbg_name = "logger varena",
// enable_mem_tracking = false )
// verify( alloc_error == .None, "Failed to allocate logger's virtual arena")
vmem_init_counter += 1
// TODO(Ed): Figure out another solution here...
// logger.entries, alloc_error = array_init(Array(LoggerEntry), 8192, runtime.heap_allocator())
// verify( alloc_error == .None, "Failed to allocate logger's entries array")
context.logger = { logger_interface, logger, LoggerLevel.Debug, Default_File_Logger_Opts }
log("Initialized Logger")
log_print("Initialized Logger")
when false {
log("This sentence is over 80 characters long on purpose to test the ability of this logger to properfly wrap long as logs with a new line and then at the end of that pad it with the appropraite signature.")
log_print("This sentence is over 80 characters long on purpose to test the ability of this logger to properfly wrap long as logs with a new line and then at the end of that pad it with the appropraite signature.")
}
}
@@ -137,24 +121,13 @@ logger_interface :: proc(
str_pfmt_file_ln( logger.file, to_string(builder) )
}
// This buffer is used below excluisvely to prevent any allocator recusion when verbose logging from allocators.
// This means a single line is limited to 32k buffer (increase naturally if this SOMEHOW becomes a bottleneck...)
Logger_Allocator_Buffer : [32 * Kilo]u8
// Below are made on demand per-package.
// They should strict only use a scratch allocator...
log :: proc( msg : string, level := LoggerLevel.Info, loc := #caller_location ) {
// TODO(Ed): Finish this
// temp_arena : Arena; arena_init(& temp_arena, Logger_Allocator_Buffer[:])
// context.allocator = arena_allocator(& temp_arena)
// context.temp_allocator = arena_allocator(& temp_arena)
// core_log.log( level, msg, location = loc )
log_print :: proc( msg : string, level := LoggerLevel.Info, loc := #caller_location ) {
core_log.log( level, msg, location = loc )
}
log_fmt :: proc( fmt : string, args : ..any, level := LoggerLevel.Info, loc := #caller_location ) {
// TODO(Ed): Finish this
// temp_arena : Arena; arena_init(& temp_arena, Logger_Allocator_Buffer[:])
// context.allocator = arena_allocator(& temp_arena)
// context.temp_allocator = arena_allocator(& temp_arena)
// core_log.logf( level, fmt, ..args, location = loc )
log_print_fmt :: proc( fmt : string, args : ..any, level := LoggerLevel.Info, loc := #caller_location ) {
core_log.logf( level, fmt, ..args, location = loc )
}

View File

@@ -32,7 +32,7 @@ import fmt_io "core:fmt"
str_pfmt_builder :: fmt_io.sbprintf
str_pfmt_buffer :: fmt_io.bprintf
str_pfmt_file_ln :: fmt_io.fprintln
str_tmp_from_any :: fmt_io.tprint
str_tmp_from_any :: #force_inline proc(args: ..any, sep := " ") -> string { context.temp_allocator = resolve_odin_allocator(context.temp_allocator); return fmt_io.tprint(..args, sep = sep) }
import "core:log"
Default_File_Logger_Opts :: log.Default_File_Logger_Opts
@@ -53,31 +53,33 @@ import "core:mem"
import "core:mem/virtual"
VirtualProtectFlags :: virtual.Protect_Flags
import core_os "core:os"
FS_Open_Readonly :: core_os.O_RDONLY
FS_Open_Writeonly :: core_os.O_WRONLY
FS_Open_Create :: core_os.O_CREATE
FS_Open_Trunc :: core_os.O_TRUNC
import "core:os"
FS_Open_Readonly :: os.O_RDONLY
FS_Open_Writeonly :: os.O_WRONLY
FS_Open_Create :: os.O_CREATE
FS_Open_Trunc :: os.O_TRUNC
OS_ERROR_NONE :: core_os.ERROR_NONE
OS_Handle :: core_os.Handle
OS_ERROR_HANDLE_EOF :: core_os.ERROR_HANDLE_EOF
OS_INVALID_HANDLE :: core_os.INVALID_HANDLE
OS_ERROR_NONE :: os.ERROR_NONE
OS_Handle :: os.Handle
OS_ERROR_HANDLE_EOF :: os.ERROR_HANDLE_EOF
OS_INVALID_HANDLE :: os.INVALID_HANDLE
FileFlag_Create :: core_os.O_CREATE
FileFlag_ReadWrite :: core_os.O_RDWR
FileTime :: core_os.File_Time
file_close :: core_os.close
file_open :: core_os.open
file_read :: core_os.read
file_remove :: core_os.remove
file_seek :: core_os.seek
file_status :: core_os.stat
file_truncate :: core_os.truncate
file_write :: core_os.write
process_exit :: os.exit
file_read_entire :: core_os.read_entire_file
file_write_entire :: core_os.write_entire_file
FileFlag_Create :: os.O_CREATE
FileFlag_ReadWrite :: os.O_RDWR
FileTime :: os.File_Time
file_close :: os.close
file_open :: os.open
file_read :: os.read
file_remove :: os.remove
file_seek :: os.seek
file_status :: os.stat
file_truncate :: os.truncate
file_write :: os.write
file_read_entire :: os.read_entire_file
file_write_entire :: os.write_entire_file
import "core:strings"
StrBuilder :: strings.Builder

37
code2/grime/profiler.odin Normal file
View File

@@ -0,0 +1,37 @@
package grime
/*
This is just a snippet file, do not use directly.
*/
import "base:runtime"
import "core:prof/spall"
SpallProfiler :: struct {
ctx : spall.Context,
buffer : spall.Buffer,
}
// @(private)
// Module_Context : ^SpallProfiler
// set_profiler_module_context :: #force_inline proc "contextless" ( ctx : ^SpallProfiler ) {
// Module_Context = ctx
// }
DISABLE_PROFILING :: true
@(deferred_none = profile_end, disabled = DISABLE_PROFILING)
profile :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
// spall._buffer_begin( & Module_Context.ctx, & Module_Context.buffer, name, "", loc )
}
@(disabled = DISABLE_PROFILING)
profile_begin :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
// spall._buffer_begin( & Module_Context.ctx, & Module_Context.buffer, name, "", loc )
}
@(disabled = DISABLE_PROFILING)
profile_end :: #force_inline proc "contextless" () {
// spall._buffer_end( & Module_Context.ctx, & Module_Context.buffer)
}

View File

@@ -19,7 +19,7 @@ thread__highres_wait :: proc( desired_ms : f64, loc := #caller_location ) -> b32
timer := win32.CreateWaitableTimerExW( nil, nil, win32.CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, win32.TIMER_ALL_ACCESS )
if timer == nil {
msg := str_pfmt("Failed to create win32 timer - ErrorCode: %v", win32.GetLastError() )
log( msg, LoggerLevel.Warning, loc)
log_print( msg, LoggerLevel.Warning, loc)
return false
}
@@ -27,7 +27,7 @@ thread__highres_wait :: proc( desired_ms : f64, loc := #caller_location ) -> b32
result := win32.SetWaitableTimerEx( timer, & due_time, 0, nil, nil, nil, 0 )
if ! result {
msg := str_pfmt("Failed to set win32 timer - ErrorCode: %v", win32.GetLastError() )
log( msg, LoggerLevel.Warning, loc)
log_print( msg, LoggerLevel.Warning, loc)
return false
}
@@ -42,22 +42,22 @@ thread__highres_wait :: proc( desired_ms : f64, loc := #caller_location ) -> b32
{
case WAIT_ABANDONED:
msg := str_pfmt("Failed to wait for win32 timer - Error: WAIT_ABANDONED" )
log( msg, LoggerLevel.Error, loc)
log_print( msg, LoggerLevel.Error, loc)
return false
case WAIT_IO_COMPLETION:
msg := str_pfmt("Waited for win32 timer: Ended by APC queued to the thread" )
log( msg, LoggerLevel.Error, loc)
log_print( msg, LoggerLevel.Error, loc)
return false
case WAIT_OBJECT_0:
msg := str_pfmt("Waited for win32 timer- Reason : WAIT_OBJECT_0" )
log( msg, loc = loc)
log_print( msg, loc = loc)
return false
case WAIT_FAILED:
msg := str_pfmt("Waited for win32 timer failed - ErrorCode: $v", win32.GetLastError() )
log( msg, LoggerLevel.Error, loc)
log_print( msg, LoggerLevel.Error, loc)
return false
}