Got logging setup
There is an issue with the tracked allocators made for the host module. I'll need to see later whats going on, for now it doesn't matter.
This commit is contained in:
parent
d205aba15a
commit
6819336696
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
build/**
|
||||
*.exe
|
||||
thirdparty/**
|
||||
~thirdparty/odin/core/**
|
||||
~thirdparty/odin/core/**
|
||||
logs
|
||||
|
@ -27,8 +27,11 @@ ModuleAPI :: struct {
|
||||
}
|
||||
|
||||
@export
|
||||
startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8 )
|
||||
startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ Logger )
|
||||
{
|
||||
init( & memory.logger, "Sectr", host_logger.file_path, host_logger.file )
|
||||
context.logger = to_odin_logger( & memory.logger )
|
||||
|
||||
// Setup memory for the first time
|
||||
{
|
||||
arena_size :: size_of( mem.Arena)
|
||||
@ -53,6 +56,7 @@ startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8 )
|
||||
context.allocator = tracked_allocator( transient )
|
||||
context.temp_allocator = tracked_allocator( temp )
|
||||
}
|
||||
|
||||
state := new( State, tracked_allocator( memory.persistent ) )
|
||||
using state
|
||||
|
||||
@ -64,12 +68,13 @@ startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8 )
|
||||
screen_height = 1000
|
||||
win_title : cstring = "Sectr Prototype"
|
||||
rl.InitWindow( screen_width, screen_height, win_title )
|
||||
log( "Raylib initialized and window opened" )
|
||||
|
||||
// Determining current monitor and setting the target frametime based on it..
|
||||
monitor_id = rl.GetCurrentMonitor ()
|
||||
monitor_refresh_hz = rl.GetMonitorRefreshRate( monitor_id )
|
||||
rl.SetTargetFPS( monitor_refresh_hz )
|
||||
fmt.println( "Set target FPS to: %v", monitor_refresh_hz )
|
||||
log( fmt.tprintf( "Set target FPS to: %v", monitor_refresh_hz ) )
|
||||
|
||||
// Basic Font Setup
|
||||
{
|
||||
@ -80,6 +85,7 @@ startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8 )
|
||||
|
||||
rl.GuiSetFont( font_rec_mono_semicasual_reg ) // TODO(Ed) : Does this do anything?
|
||||
default_font = font_rec_mono_semicasual_reg
|
||||
log( "Default font loaded" )
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,10 +108,11 @@ sectr_shutdown :: proc()
|
||||
rl.UnloadFont ( state.font_rec_mono_semicasual_reg )
|
||||
rl.CloseWindow()
|
||||
}
|
||||
log("Module shutdown complete")
|
||||
}
|
||||
|
||||
@export
|
||||
reload :: proc( live_mem : virtual.Arena, snapshot_mem : []u8 )
|
||||
reload :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ Logger )
|
||||
{
|
||||
using memory;
|
||||
block := live_mem.curr_block
|
||||
@ -120,6 +127,8 @@ reload :: proc( live_mem : virtual.Arena, snapshot_mem : []u8 )
|
||||
persistent = cast( ^TrackedAllocator ) & persistent_slice[0]
|
||||
transient = cast( ^TrackedAllocator ) & transient_slice[0]
|
||||
temp = cast( ^TrackedAllocator ) & temp_slice[0]
|
||||
|
||||
log("Module reloaded")
|
||||
}
|
||||
|
||||
// TODO(Ed) : This lang really not have a fucking swap?
|
||||
@ -152,32 +161,26 @@ update :: proc() -> b32
|
||||
}
|
||||
}}
|
||||
|
||||
DO_NOT_CONTINUE : b32 = false
|
||||
|
||||
if debug_actions.play_replay { switch replay.mode
|
||||
{
|
||||
case ReplayMode.Off : {
|
||||
if ! file_exists( Path_Input_Replay ) {
|
||||
save_snapshot( & memory.snapshot[0] )
|
||||
replay_recording_begin( Path_Input_Replay )
|
||||
break
|
||||
}
|
||||
else {
|
||||
load_snapshot( & memory.snapshot[0] )
|
||||
replay_playback_begin( Path_Input_Replay )
|
||||
break
|
||||
}
|
||||
}
|
||||
case ReplayMode.Playback : {
|
||||
replay_playback_end()
|
||||
load_snapshot( & memory.snapshot[0] )
|
||||
break
|
||||
}
|
||||
case ReplayMode.Record : {
|
||||
replay_recording_end()
|
||||
load_snapshot( & memory.snapshot[0] )
|
||||
replay_playback_begin( Path_Input_Replay )
|
||||
break
|
||||
}
|
||||
}}
|
||||
|
||||
|
31
code/assert.odin
Normal file
31
code/assert.odin
Normal file
@ -0,0 +1,31 @@
|
||||
package sectr
|
||||
|
||||
import "base:runtime"
|
||||
import "core:os"
|
||||
|
||||
ensure :: proc( condition : b32, msg : string, location := #caller_location )
|
||||
{
|
||||
if ! condition {
|
||||
return
|
||||
}
|
||||
log( msg, LogLevel.Warning, location )
|
||||
runtime.debug_trap()
|
||||
}
|
||||
|
||||
// TODO(Ed) : Setup exit codes!
|
||||
fatal :: proc ( msg : string, exit_code : int = -1, location := #caller_location )
|
||||
{
|
||||
log( msg, LogLevel.Fatal, location )
|
||||
runtime.debug_trap()
|
||||
os.exit( exit_code )
|
||||
}
|
||||
|
||||
verify :: proc ( condition : b32, msg : string, exit_code : int = -1, location := #caller_location )
|
||||
{
|
||||
if ! condition {
|
||||
return
|
||||
}
|
||||
log( msg, LogLevel.Fatal, location )
|
||||
runtime.debug_trap()
|
||||
os.exit( exit_code )
|
||||
}
|
@ -21,7 +21,8 @@ Memory :: struct {
|
||||
transient : ^ TrackedAllocator,
|
||||
temp : ^ TrackedAllocator,
|
||||
|
||||
replay : ReplayState
|
||||
replay : ReplayState,
|
||||
logger : Logger,
|
||||
}
|
||||
|
||||
State :: struct {
|
||||
@ -93,6 +94,11 @@ poll_debug_actions :: proc( actions : ^ DebugActions, input : ^ InputState )
|
||||
}
|
||||
|
||||
save_snapshot :: proc( snapshot : [^]u8 ) {
|
||||
state := get_state()
|
||||
|
||||
// state.font_rec_mono_semicasual_reg
|
||||
// state.default_font
|
||||
|
||||
live_ptr := cast( ^ rawptr ) memory.live.curr_block.base
|
||||
mem.copy_non_overlapping( & snapshot[0], live_ptr, memory_chunk_size )
|
||||
}
|
||||
@ -118,25 +124,12 @@ replay_recording_begin :: proc( path : string )
|
||||
{
|
||||
if file_exists( path ) {
|
||||
result := os.remove( path )
|
||||
if ( result != os.ERROR_NONE )
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Failed to delete replay file before beginning a new one" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
verify( result != os.ERROR_NONE, "Failed to delete replay file before beginning a new one" )
|
||||
}
|
||||
|
||||
replay_file, open_error := os.open( path, os.O_RDWR | os.O_CREATE )
|
||||
if ( open_error != os.ERROR_NONE )
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Failed to create or open the replay file" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
verify( open_error != os.ERROR_NONE, "Failed to create or open the replay file" )
|
||||
|
||||
os.seek( replay_file, 0, 0 )
|
||||
|
||||
replay := & memory.replay
|
||||
@ -154,34 +147,20 @@ replay_recording_end :: proc() {
|
||||
|
||||
replay_playback_begin :: proc( path : string )
|
||||
{
|
||||
if ! file_exists( path )
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Failed to create or open the replay file" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
verify( ! file_exists( path ), "Failed to find replay file" )
|
||||
|
||||
replay_file, open_error := os.open( path, os.O_RDWR | os.O_CREATE )
|
||||
if ( open_error != os.ERROR_NONE )
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Failed to create or open the replay file" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
// TODO(Ed): WE need to wrap any actions that can throw a fatal like this. Files need a grime wrap.
|
||||
verify( open_error != os.ERROR_NONE, "Failed to create or open the replay file" )
|
||||
|
||||
os.seek( replay_file, 0, 0 )
|
||||
|
||||
replay := & memory.replay
|
||||
replay.active_file = replay_file
|
||||
replay.mode = ReplayMode.Playback
|
||||
replay.mode = ReplayMode.Playback
|
||||
}
|
||||
|
||||
replay_playback_end :: proc() {
|
||||
input := get_state().input
|
||||
input := get_state().input
|
||||
replay := & memory.replay
|
||||
replay.mode = ReplayMode.Off
|
||||
os.seek( replay.active_file, 0, 0 )
|
||||
|
@ -11,7 +11,7 @@ copy_file_sync :: proc( path_src, path_dst: string ) -> b32
|
||||
{
|
||||
path_info, result := os.stat( path_src, context.temp_allocator )
|
||||
if result != os.ERROR_NONE {
|
||||
fmt.println("Error getting file info: ", result )
|
||||
logf("Could not get file info: %v", result, LogLevel.Error )
|
||||
return false
|
||||
}
|
||||
file_size = path_info.size
|
||||
@ -19,14 +19,14 @@ copy_file_sync :: proc( path_src, path_dst: string ) -> b32
|
||||
|
||||
src_content, result := os.read_entire_file( path_src, context.temp_allocator )
|
||||
if ! result {
|
||||
fmt.println( "Failed to read file to copy" )
|
||||
logf( "Failed to read file to copy: %v", path_src, LogLevel.Error )
|
||||
runtime.debug_trap()
|
||||
return false
|
||||
}
|
||||
|
||||
result = os.write_entire_file( path_dst, src_content, false )
|
||||
if ! result {
|
||||
fmt.println( "Failed to copy file")
|
||||
logf( "Failed to copy file: %v", path_dst, LogLevel.Error )
|
||||
runtime.debug_trap()
|
||||
return false
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import "core:mem/virtual"
|
||||
Petabyte :: 1024 * Terabyte
|
||||
Exabyte :: 1024 * Petabyte
|
||||
import "core:os"
|
||||
file_resize :: os.ftruncate
|
||||
import "core:strings"
|
||||
import "core:time"
|
||||
import rl "vendor:raylib"
|
||||
@ -24,9 +25,15 @@ TrackedAllocator :: sectr.TrackedAllocator
|
||||
tracked_allocator :: sectr.tracked_allocator
|
||||
tracked_allocator_init :: sectr.tracked_allocator_init
|
||||
|
||||
LogLevel :: sectr.LogLevel
|
||||
log :: sectr.log
|
||||
fatal :: sectr.fatal
|
||||
verify :: sectr.verify
|
||||
|
||||
path_snapshot :: "VMemChunk_1.snapshot"
|
||||
when ODIN_OS == runtime.Odin_OS_Type.Windows
|
||||
{
|
||||
path_logs :: "../logs"
|
||||
path_sectr_module :: "sectr.dll"
|
||||
path_sectr_live_module :: "sectr_live.dll"
|
||||
path_sectr_debug_symbols :: "sectr.pdb"
|
||||
@ -65,29 +72,14 @@ setup_memory :: proc () -> VMemChunk
|
||||
base_address : rawptr = transmute( rawptr) u64(Terabyte * 1)
|
||||
|
||||
result := arena_init_static( & sectr_live, base_address, sectr.memory_chunk_size, sectr.memory_chunk_size )
|
||||
if result != runtime.Allocator_Error.None
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Failed to allocate live memory for the sectr module" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
verify( result != runtime.Allocator_Error.None, "Failed to allocate live memory for the sectr module" )
|
||||
}
|
||||
|
||||
// Setup memory mapped io for snapshots
|
||||
{
|
||||
file_resize :: os.ftruncate
|
||||
|
||||
snapshot_file, open_error := os.open( path_snapshot, os.O_RDWR | os.O_CREATE )
|
||||
if ( open_error != os.ERROR_NONE )
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Failed to open snapshot file for the sectr module" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
verify( open_error != os.ERROR_NONE, "Failed to open snapshot file for the sectr module" )
|
||||
|
||||
file_info, stat_code := os.stat( path_snapshot )
|
||||
{
|
||||
if file_info.size != sectr.memory_chunk_size {
|
||||
@ -95,16 +87,10 @@ setup_memory :: proc () -> VMemChunk
|
||||
}
|
||||
}
|
||||
|
||||
map_error : virtual.Map_File_Error
|
||||
sectr_snapshot, map_error = virtual.map_file_from_file_descriptor( uintptr(snapshot_file), { virtual.Map_File_Flag.Read, virtual.Map_File_Flag.Write } )
|
||||
if map_error != virtual.Map_File_Error.None
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Failed to allocate snapshot memory for the sectr module" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
map_error : virtual.Map_File_Error
|
||||
map_flags : virtual.Map_File_Flags = { virtual.Map_File_Flag.Read, virtual.Map_File_Flag.Write }
|
||||
sectr_snapshot, map_error = virtual.map_file_from_file_descriptor( uintptr(snapshot_file), map_flags )
|
||||
verify( map_error != virtual.Map_File_Error.None, "Failed to allocate snapshot memory for the sectr module" )
|
||||
|
||||
os.close(snapshot_file)
|
||||
}
|
||||
@ -112,8 +98,7 @@ setup_memory :: proc () -> VMemChunk
|
||||
// Reassign default allocators for host
|
||||
memory.og_allocator = context.allocator
|
||||
memory.og_temp_allocator = context.temp_allocator
|
||||
context.allocator = tracked_allocator( & memory.host_persistent )
|
||||
context.temp_allocator = tracked_allocator( & memory.host_transient )
|
||||
log("Memory setup")
|
||||
return memory;
|
||||
}
|
||||
|
||||
@ -121,10 +106,9 @@ load_sectr_api :: proc ( version_id : i32 ) -> sectr.ModuleAPI
|
||||
{
|
||||
loaded_module : sectr.ModuleAPI
|
||||
|
||||
write_time,
|
||||
result := os.last_write_time_by_name("sectr.dll")
|
||||
write_time, result := os.last_write_time_by_name("sectr.dll")
|
||||
if result != os.ERROR_NONE {
|
||||
fmt. println("Could not resolve the last write time for sectr.dll")
|
||||
log( "Could not resolve the last write time for sectr.dll", LogLevel.Warning )
|
||||
runtime.debug_trap()
|
||||
return {}
|
||||
}
|
||||
@ -134,8 +118,7 @@ load_sectr_api :: proc ( version_id : i32 ) -> sectr.ModuleAPI
|
||||
|
||||
lib, load_result := dynlib.load_library( live_file )
|
||||
if ! load_result {
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. println( "Failed to load the sectr module." )
|
||||
log( "Failed to load the sectr module.", LogLevel.Warning )
|
||||
runtime.debug_trap()
|
||||
return {}
|
||||
}
|
||||
@ -159,6 +142,7 @@ load_sectr_api :: proc ( version_id : i32 ) -> sectr.ModuleAPI
|
||||
return {}
|
||||
}
|
||||
|
||||
log("Loaded sectr API")
|
||||
loaded_module = {
|
||||
lib = lib,
|
||||
write_time = write_time,
|
||||
@ -179,9 +163,10 @@ unload_sectr_api :: proc ( module : ^ sectr.ModuleAPI )
|
||||
dynlib.unload_library( module.lib )
|
||||
os.remove( path_sectr_live_module )
|
||||
module^ = {}
|
||||
log("Unloaded sectr API")
|
||||
}
|
||||
|
||||
sync_sectr_api :: proc ( sectr_api : ^ sectr.ModuleAPI, memory : ^ VMemChunk )
|
||||
sync_sectr_api :: proc ( sectr_api : ^ sectr.ModuleAPI, memory : ^ VMemChunk, logger : ^ sectr.Logger )
|
||||
{
|
||||
if write_time, result := os.last_write_time_by_name( path_sectr_module );
|
||||
result == os.ERROR_NONE && sectr_api.write_time != write_time
|
||||
@ -194,13 +179,9 @@ sync_sectr_api :: proc ( sectr_api : ^ sectr.ModuleAPI, memory : ^ VMemChunk )
|
||||
time.sleep( time.Millisecond )
|
||||
|
||||
sectr_api ^ = load_sectr_api( version_id )
|
||||
if sectr_api.lib_version == 0 {
|
||||
fmt.println("Failed to hot-reload the sectr module")
|
||||
runtime.debug_trap()
|
||||
os.exit(-1)
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
sectr_api.reload( memory.sectr_live, memory.sectr_snapshot )
|
||||
verify( sectr_api.lib_version == 0, "Failed to hot-reload the sectr module" )
|
||||
|
||||
sectr_api.reload( memory.sectr_live, memory.sectr_snapshot, logger )
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,6 +190,32 @@ main :: proc()
|
||||
state : RuntimeState
|
||||
using state
|
||||
|
||||
path_logger_finalized : string
|
||||
{
|
||||
startup_time := time.now()
|
||||
year, month, day := time.date( startup_time)
|
||||
hour, min, sec := time.clock_from_time( startup_time)
|
||||
|
||||
if ! os.is_dir( path_logs ) {
|
||||
os.make_directory( path_logs )
|
||||
}
|
||||
|
||||
timestamp := fmt.tprintf("%04d-%02d-%02d_%02d-%02d-%02d", year, month, day, hour, min, sec)
|
||||
path_logger_finalized = strings.clone( fmt.tprintf( "%s/sectr_%v.log", path_logs, timestamp) )
|
||||
}
|
||||
logger : sectr.Logger
|
||||
sectr.init( & logger, "Sectr Host", fmt.tprintf( "%s/sectr.log", path_logs ) )
|
||||
context.logger = sectr.to_odin_logger( & logger )
|
||||
{
|
||||
// Log System Context
|
||||
backing_builder : [16 * Kilobyte] u8
|
||||
builder := strings.builder_from_bytes( backing_builder[:] )
|
||||
fmt.sbprintf( & builder, "Core Count: %v, ", os.processor_core_count() )
|
||||
fmt.sbprintf( & builder, "Page Size: %v", os.get_page_size() )
|
||||
|
||||
sectr.log( strings.to_string(builder) )
|
||||
}
|
||||
|
||||
// Basic Giant VMem Block
|
||||
{
|
||||
// By default odin uses a growing arena for the runtime context
|
||||
@ -218,28 +225,26 @@ main :: proc()
|
||||
memory = setup_memory()
|
||||
}
|
||||
|
||||
// TODO(Ed): Cannot use the manually created allocators for the host. Not sure why
|
||||
// context.allocator = tracked_allocator( & memory.host_persistent )
|
||||
// context.temp_allocator = tracked_allocator( & memory.host_transient )
|
||||
|
||||
// Load the Enviornment API for the first-time
|
||||
{
|
||||
sectr_api = load_sectr_api( 1 )
|
||||
if sectr_api.lib_version == 0 {
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. println( "Failed to initially load the sectr module" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
sectr_api = load_sectr_api( 1 )
|
||||
verify( sectr_api.lib_version == 0, "Failed to initially load the sectr module" )
|
||||
}
|
||||
|
||||
running = true;
|
||||
memory = memory
|
||||
sectr_api = sectr_api
|
||||
sectr_api.startup( memory.sectr_live, memory.sectr_snapshot )
|
||||
sectr_api.startup( memory.sectr_live, memory.sectr_snapshot, & logger )
|
||||
|
||||
// TODO(Ed) : This should have an end status so that we know the reason the engine stopped.
|
||||
for ; running ;
|
||||
{
|
||||
// Hot-Reload
|
||||
sync_sectr_api( & sectr_api, & memory )
|
||||
sync_sectr_api( & sectr_api, & memory, & logger )
|
||||
|
||||
running = sectr_api.update()
|
||||
sectr_api.render()
|
||||
@ -254,4 +259,8 @@ main :: proc()
|
||||
|
||||
sectr_api.shutdown()
|
||||
unload_sectr_api( & sectr_api )
|
||||
|
||||
log("Succesfuly closed")
|
||||
os.close( logger.file )
|
||||
os.rename( logger.file_path, path_logger_finalized )
|
||||
}
|
||||
|
@ -2,11 +2,13 @@
|
||||
// This was made becaause odin didn't expose the base_address param that virtual alloc allows.
|
||||
package host
|
||||
|
||||
import "base:runtime"
|
||||
import "core:mem"
|
||||
import "core:mem/virtual"
|
||||
|
||||
import win32 "core:sys/windows"
|
||||
|
||||
when ODIN_OS == runtime.Odin_OS_Type.Windows {
|
||||
@(private="file")
|
||||
virtual_Platform_Memory_Block :: struct {
|
||||
block: virtual.Memory_Block,
|
||||
@ -124,3 +126,6 @@ arena_init_static :: proc(arena: ^virtual.Arena, base_address : rawptr,
|
||||
arena.total_reserved = arena.curr_block.reserved
|
||||
return
|
||||
}
|
||||
|
||||
// END WINDOWS CHECK WRAP
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ btn_pressed :: proc( btn : DigitalBtn ) -> b32 {
|
||||
}
|
||||
|
||||
pressed :: proc {
|
||||
btn_pressed
|
||||
btn_pressed,
|
||||
}
|
||||
|
||||
MaxKeyboardKeys :: 256
|
||||
@ -286,7 +286,7 @@ poll_input :: proc( old, new : ^ InputState )
|
||||
input_process_digital_btn :: proc ( old_state, new_state : ^ DigitalBtn, is_down : b32 )
|
||||
{
|
||||
new_state.ended_down = is_down
|
||||
had_transition := old_state.ended_down != new_state.ended_down
|
||||
had_transition := old_state.ended_down != new_state.ended_down
|
||||
if had_transition {
|
||||
new_state.half_transitions += 1
|
||||
}
|
||||
@ -477,7 +477,7 @@ to_raylib_key :: proc ( key : i32 ) -> rl.KeyboardKey {
|
||||
rl.KeyboardKey.KP_SUBTRACT,
|
||||
rl.KeyboardKey.KP_MULTIPLY,
|
||||
rl.KeyboardKey.KP_DIVIDE,
|
||||
rl.KeyboardKey.KP_ENTER
|
||||
rl.KeyboardKey.KP_ENTER
|
||||
}
|
||||
return raylib_key_lookup_table[ key ]
|
||||
}
|
||||
|
125
code/logger.odin
Normal file
125
code/logger.odin
Normal file
@ -0,0 +1,125 @@
|
||||
package sectr
|
||||
|
||||
import "base:runtime"
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:strings"
|
||||
import "core:time"
|
||||
import core_log "core:log"
|
||||
|
||||
Max_Logger_Message_Width :: 80
|
||||
|
||||
LogLevel :: core_log.Level
|
||||
|
||||
Logger :: struct {
|
||||
file_path : string,
|
||||
file : os.Handle,
|
||||
id : string,
|
||||
}
|
||||
|
||||
to_odin_logger :: proc ( logger : ^ Logger ) -> core_log.Logger {
|
||||
return { logger_interface, logger, core_log.Level.Debug, core_log.Default_File_Logger_Opts }
|
||||
}
|
||||
|
||||
init :: proc ( logger : ^ Logger, id : string, file_path : string, file := os.INVALID_HANDLE )
|
||||
{
|
||||
if file == os.INVALID_HANDLE
|
||||
{
|
||||
logger_file, result_code := os.open( file_path, os.O_RDWR | os.O_CREATE )
|
||||
if result_code != os.ERROR_NONE {
|
||||
// Log failures are fatal and must never occur at runtime (there is no logging)
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
logger.file = logger_file
|
||||
}
|
||||
else {
|
||||
logger.file = file
|
||||
}
|
||||
logger.file_path = file_path
|
||||
logger.id = id
|
||||
|
||||
context.logger = { logger_interface, logger, core_log.Level.Debug, core_log.Default_File_Logger_Opts }
|
||||
log("Initialized Logger")
|
||||
when false {
|
||||
log("This sentence is over 80 characters long on purpose to test the ability of this fucking logger to properfly fucking wrap long as fuck logs with a new line and then at the end of that pad it with the appropraite signature.")
|
||||
}
|
||||
}
|
||||
|
||||
logger_interface :: proc (
|
||||
logger_data : rawptr,
|
||||
level : core_log.Level,
|
||||
text : string,
|
||||
options : core_log.Options,
|
||||
location := #caller_location )
|
||||
{
|
||||
logger := cast(^ Logger) logger_data
|
||||
|
||||
@static builder_backing : [16 * Kilobyte] byte; {
|
||||
mem.set( raw_data( builder_backing[:] ), 0, len(builder_backing) )
|
||||
}
|
||||
builder := strings.builder_from_bytes( builder_backing[:] )
|
||||
|
||||
first_line_length := len(text) > Max_Logger_Message_Width ? Max_Logger_Message_Width : len(text)
|
||||
first_line := transmute(string) text[ 0 : first_line_length ]
|
||||
fmt.sbprintf( & builder, "%-*s ", Max_Logger_Message_Width, first_line )
|
||||
|
||||
// Signature
|
||||
{
|
||||
when time.IS_SUPPORTED
|
||||
{
|
||||
if core_log.Full_Timestamp_Opts & options != nil {
|
||||
fmt.sbprint( & builder, "[")
|
||||
|
||||
t := time.now()
|
||||
y, m, d := time.date(t)
|
||||
h, min, s := time.clock(t)
|
||||
|
||||
if .Date in options {
|
||||
fmt.sbprintf( & builder, "%d-%02d-%02d ", y, m, d )
|
||||
}
|
||||
if .Time in options {
|
||||
fmt.sbprintf( & builder, "%02d:%02d:%02d", h, min, s)
|
||||
}
|
||||
|
||||
fmt.sbprint( & builder, "] ")
|
||||
}
|
||||
}
|
||||
core_log.do_level_header( options, level, & builder )
|
||||
|
||||
if logger.id != "" {
|
||||
fmt.sbprintf( & builder, "[%s] ", logger.id )
|
||||
}
|
||||
core_log.do_location_header( options, & builder, location )
|
||||
}
|
||||
|
||||
// Oversized message handling
|
||||
if len(text) > Max_Logger_Message_Width
|
||||
{
|
||||
offset := Max_Logger_Message_Width
|
||||
bytes := transmute([]u8) text
|
||||
for left := len(bytes) - Max_Logger_Message_Width; left > 0; left -= Max_Logger_Message_Width
|
||||
{
|
||||
fmt.sbprintf( & builder, "\n" )
|
||||
subset_length := len(text) - offset
|
||||
if subset_length > Max_Logger_Message_Width {
|
||||
subset_length = Max_Logger_Message_Width
|
||||
}
|
||||
subset := slice_ptr( ptr_offset( raw_data(bytes), offset), subset_length )
|
||||
fmt.sbprintf( & builder, "%s", transmute(string)subset )
|
||||
offset += Max_Logger_Message_Width
|
||||
}
|
||||
}
|
||||
|
||||
fmt.fprintln( logger.file, strings.to_string(builder) )
|
||||
}
|
||||
|
||||
log :: proc ( msg : string, level := LogLevel.Info, loc := #caller_location ) {
|
||||
core_log.log( level, msg, location = loc )
|
||||
}
|
||||
|
||||
logf :: proc ( fmt : string, args : ..any, level := LogLevel.Info, loc := #caller_location ) {
|
||||
core_log.logf( level, fmt, args, location = loc )
|
||||
}
|
@ -34,6 +34,7 @@ tracked_allocator :: proc ( self : ^ TrackedAllocator ) -> Allocator {
|
||||
return tracking_allocator( & self.tracker )
|
||||
}
|
||||
|
||||
// TODO(Ed): These allocators are bad... not sure why.
|
||||
tracked_allocator_init :: proc( size, internals_size : int, allocator := context.allocator ) -> TrackedAllocator
|
||||
{
|
||||
result : TrackedAllocator
|
||||
@ -44,20 +45,22 @@ tracked_allocator_init :: proc( size, internals_size : int, allocator := context
|
||||
raw_size := backing_size + internals_size
|
||||
|
||||
raw_mem, raw_mem_code := alloc( raw_size, mem.DEFAULT_ALIGNMENT, allocator )
|
||||
if ( raw_mem_code != mem.Allocator_Error.None )
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Failed to allocate memory for the TrackingAllocator" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
arena_init( & result.backing, slice_ptr( cast( ^ byte) raw_mem, backing_size ) )
|
||||
arena_init( & result.internals, slice_ptr( memory_after( result.backing.data), internals_size ) )
|
||||
verify( raw_mem_code != mem.Allocator_Error.None, "Failed to allocate memory for the TrackingAllocator" )
|
||||
|
||||
backing_slice := slice_ptr( cast( ^ byte) raw_mem, backing_size )
|
||||
internals_slice := slice_ptr( memory_after( backing_slice), internals_size )
|
||||
|
||||
arena_init( & result.backing, backing_slice )
|
||||
arena_init( & result.internals, internals_slice )
|
||||
|
||||
backing_allocator := arena_allocator( & result.backing )
|
||||
internals_allocator := arena_allocator( & result.internals )
|
||||
tracking_allocator_init( & result.tracker, backing_allocator, internals_allocator )
|
||||
{
|
||||
tracker_arena := cast(^Arena) result.tracker.backing.data
|
||||
arena_len := len( tracker_arena.data )
|
||||
verify( arena_len != len(result.backing.data), "BAD SIZE ON TRACKER'S ARENA" )
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@ -68,14 +71,7 @@ tracked_allocator_init_vmem :: proc( vmem : [] byte, internals_size : int ) -> ^
|
||||
backing_size := len(vmem) - internals_size
|
||||
raw_size := backing_size + internals_size
|
||||
|
||||
if backing_size < 0 || len(vmem) < raw_size
|
||||
{
|
||||
// TODO(Ed) : Setup a proper logging interface
|
||||
fmt. printf( "Provided virtual memory slice is not large enough to hold the TrackedAllocator" )
|
||||
runtime.debug_trap()
|
||||
os. exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
verify( backing_size < 0 || len(vmem) < raw_size, "Provided virtual memory slice is not large enough to hold the TrackedAllocator" )
|
||||
|
||||
result := cast( ^ TrackedAllocator) & vmem[0]
|
||||
result_slice := slice_ptr( & vmem[0], tracking_allocator_size )
|
||||
|
Loading…
Reference in New Issue
Block a user