From 80846d035f8609d04343c0d7d7413ecd78d50008 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 12 Oct 2025 02:13:57 -0400 Subject: [PATCH] got it compiling again (still quite a bit todo) --- code2/grime/chrono.odin | 33 ++++++++++ code2/grime/dynamic_array.odin | 63 +++++++++++++++++++ ...y_table_1_layer_chained_chunked_cells.odin | 13 ++-- code2/grime/memory.odin | 7 ++- code2/grime/pkg_mappings.odin | 4 ++ code2/grime/timing_windows.odin | 22 +++---- code2/grime/unicode.odin | 3 + code2/grime/virtual_memory.odin | 2 +- 8 files changed, 123 insertions(+), 24 deletions(-) create mode 100644 code2/grime/chrono.odin create mode 100644 code2/grime/dynamic_array.odin diff --git a/code2/grime/chrono.odin b/code2/grime/chrono.odin new file mode 100644 index 0000000..6bf35f3 --- /dev/null +++ b/code2/grime/chrono.odin @@ -0,0 +1,33 @@ +package grime + +Nanosecond_To_Microsecond :: 1.0 / (1000.0) +Nanosecond_To_Millisecond :: 1.0 / (1000.0 * 1000.0) +Nanosecond_To_Second :: 1.0 / (1000.0 * 1000.0 * 1000.0) + +Microsecond_To_Nanosecond :: 1000.0 +Microsecond_To_Millisecond :: 1.0 / 1000.0 +Microsecond_To_Second :: 1.0 / (1000.0 * 1000.0) + +Millisecond_To_Nanosecond :: 1000.0 * 1000.0 +Millisecond_To_Microsecond :: 1000.0 +Millisecond_To_Second :: 1.0 / 1000.0 + +Second_To_Nanosecond :: 1000.0 * 1000.0 * 1000.0 +Second_To_Microsecnd :: 1000.0 * 1000.0 +Second_To_Millisecond :: 1000.0 + +NS_To_MS :: Nanosecond_To_Millisecond +NS_To_US :: Nanosecond_To_Microsecond +NS_To_S :: Nanosecond_To_Second + +US_To_NS :: Microsecond_To_Nanosecond +US_To_MS :: Microsecond_To_Millisecond +US_To_S :: Microsecond_To_Second + +MS_To_NS :: Millisecond_To_Nanosecond +MS_To_US :: Millisecond_To_Microsecond +MS_To_S :: Millisecond_To_Second + +S_To_NS :: Second_To_Nanosecond +S_To_US :: Second_To_Microsecnd +S_To_MS :: Second_To_Millisecond diff --git a/code2/grime/dynamic_array.odin b/code2/grime/dynamic_array.odin new file mode 100644 index 0000000..749bd94 --- /dev/null +++ b/code2/grime/dynamic_array.odin @@ -0,0 +1,63 @@ +package grime + +/* +Based on gencpp's and thus zpl's Array implementation +Made becasue of the map issue with fonts during hot-reload. +I didn't want to make the HMapZPL impl with the [dynamic] array for now to isolate the hot-reload issue (when I was diagnoising) + +Update 2024-5-26: +TODO(Ed): Raw_Dynamic_Array is defined within base:runtime/core.odin and exposes what we need for worst case hot-reloads. +So its best to go back to regular dynamic arrays at some point. + +Update 2025-5-12: +I can use either... so I'll just keep both +*/ + +ArrayHeader :: struct ( $ Type : typeid ) { + backing : Odin_Allocator, + dbg_name : string, + fixed_cap : b32, + capacity : int, + num : int, + data : [^]Type, +} + +Array :: struct ( $ Type : typeid ) { + using header : ^ArrayHeader(Type), +} + +array_underlying_slice :: proc(s: []($ Type)) -> Array(Type) { + assert(len(slice) != 0) + header_size :: size_of( ArrayHeader(Type)) + array := cursor(to_bytes(s))[ - header_size] + return +} + +array_to_slice :: #force_inline proc "contextless" ( using self : Array($ Type) ) -> []Type { return slice( data, int(num)) } +array_to_slice_capacity :: #force_inline proc "contextless" ( using self : Array($ Type) ) -> []Type { return slice( data, int(capacity)) } + +array_grow_formula :: proc( value : u64 ) -> u64 { + result := (2 * value) + 8 + return result +} + +array_init :: proc( $Array_Type : typeid/Array($Type), capacity : u64, + allocator := context.allocator, fixed_cap : b32 = false, dbg_name : string = "" +) -> ( result : Array(Type), alloc_error : AllocatorError ) +{ + header_size := size_of(ArrayHeader(Type)) + array_size := header_size + int(capacity) * size_of(Type) + + raw_mem : rawptr + raw_mem, alloc_error = alloc( array_size, allocator = allocator ) + // log( str_fmt_tmp("array reserved: %d", header_size + int(capacity) * size_of(Type) )) + if alloc_error != AllocatorError.None do return + + result.header = cast( ^ArrayHeader(Type)) raw_mem + result.backing = allocator + result.dbg_name = dbg_name + result.fixed_cap = fixed_cap + result.capacity = capacity + result.data = cast( [^]Type ) (cast( [^]ArrayHeader(Type)) result.header)[ 1:] + return +} \ No newline at end of file diff --git a/code2/grime/key_table_1_layer_chained_chunked_cells.odin b/code2/grime/key_table_1_layer_chained_chunked_cells.odin index d818769..9420d84 100644 --- a/code2/grime/key_table_1_layer_chained_chunked_cells.odin +++ b/code2/grime/key_table_1_layer_chained_chunked_cells.odin @@ -38,7 +38,6 @@ KT1CX_ByteMeta :: struct { type: typeid, } KT1CX_InfoMeta :: struct { - cell_pool_size: int, table_size: int, slot_size: int, slot_key_offset: uintptr, @@ -50,14 +49,11 @@ KT1CX_InfoMeta :: struct { } KT1CX_Info :: struct { backing_table: AllocatorInfo, - backing_cells: AllocatorInfo, } kt1cx_init :: proc(info: KT1CX_Info, m: KT1CX_InfoMeta, result: ^KT1CX_Byte) { assert(result != nil) - assert(info.backing_cells.procedure != nil) assert(info.backing_table.procedure != nil) assert(m.cell_depth > 0) - assert(m.cell_pool_size >= 4 * Kilo) assert(m.table_size >= 4 * Kilo) assert(m.type_width > 0) table_raw := transmute(SliceByte) mem_alloc(m.table_size * m.cell_size, ainfo = odin_allocator(info.backing_table)) @@ -75,7 +71,7 @@ kt1cx_clear :: proc(kt: KT1CX_Byte, m: KT1CX_ByteMeta) { for;; { slot := slice(slot_cursor, m.slot_size) // slot = slots[slot_id] zero(slot) // slot = {} - if slot_cursor == end(transmute([]byte) slots) { // if slot == end(slot) + if slot_cursor == end(slots) { // if slot == end(slot) next := slot_cursor[m.cell_next_offset:] // next = kt.table.cells[cell_id + 1] if next != nil { // if next != nil slots.data = next // slots = next.slots @@ -105,7 +101,7 @@ kt1cx_get :: proc(kt: KT1CX_Byte, key: u64, m: KT1CX_ByteMeta) -> ^byte { if slot.occupied && slot.key == key { return cast(^byte) slot_cursor } - if slot_cursor == end(transmute([]byte) slots) + if slot_cursor == end(slots) { cell_next := cell_cursor[m.cell_next_offset:] // cell.next if cell_next != nil { @@ -140,7 +136,7 @@ kt1cx_set :: proc(kt: KT1CX_Byte, key: u64, value: []byte, backing_cells: Alloca else if slot.key == key { return cast(^byte) slot_cursor } - if slot_cursor == end(transmute([]byte) slots) { + if slot_cursor == end(slots) { curr_cell := transmute(^KT1CX_Byte_Cell) (uintptr(cell_cursor) + m.cell_next_offset) // curr_cell = cell if curr_cell != nil { slots.data = curr_cell.next @@ -163,7 +159,6 @@ kt1cx_set :: proc(kt: KT1CX_Byte, key: u64, value: []byte, backing_cells: Alloca } } kt1cx_assert :: proc(kt: $type / KT1CX) { - slice_assert(kt.cell_pool) slice_assert(kt.table) } -kt1cx_byte :: proc(kt: $type / KT1CX) -> KT1CX_Byte { return { to_bytes(kt.cell_pool), slice( transmute([^]byte) cursor(kt.table), len(kt.table)) } } +kt1cx_byte :: proc(kt: $type / KT1CX) -> KT1CX_Byte { return { slice( transmute([^]byte) cursor(kt.table), len(kt.table)) } } diff --git a/code2/grime/memory.odin b/code2/grime/memory.odin index 86bc1e3..03ee8a3 100644 --- a/code2/grime/memory.odin +++ b/code2/grime/memory.odin @@ -27,7 +27,8 @@ slice_assert :: #force_inline proc (s: $SliceType / []$Type) { assert(len(s) > 0) assert(s != nil) } -slice_end :: #force_inline proc "contextless" (s : $SliceType / []$Type) -> ^Type { return & cursor(s)[len(s)] } +slice_end :: #force_inline proc "contextless" (s : $SliceType / []$Type) -> ^Type { return cursor(s)[len(s):] } +slice_byte_end :: #force_inline proc "contextless" (s : SliceByte) -> ^byte { return s.data[s.len:] } slice_copy :: #force_inline proc "contextless" (dst, src: $SliceType / []$Type) -> int { n := max(0, min(len(dst), len(src))) @@ -37,8 +38,8 @@ slice_copy :: #force_inline proc "contextless" (dst, src: $SliceType / []$Type) return n } -@(require_results) slice_to_bytes :: #force_inline proc "contextless" (s: []$Type) -> []byte { return ([^]byte)(raw_data(s))[:len(s) * size_of(Type)] } -@(require_results) slice_raw :: #force_inline proc "contextless" (s: []$Type) -> SliceRaw(Type) { return transmute(SliceRaw(Type)) s } +@(require_results) slice_to_bytes :: #force_inline proc "contextless" (s: []$Type) -> []byte { return ([^]byte)(raw_data(s))[:len(s) * size_of(Type)] } +@(require_results) slice_raw :: #force_inline proc "contextless" (s: []$Type) -> SliceRaw(Type) { return transmute(SliceRaw(Type)) s } //region Memory Math diff --git a/code2/grime/pkg_mappings.odin b/code2/grime/pkg_mappings.odin index c23e7f9..34df0f2 100644 --- a/code2/grime/pkg_mappings.odin +++ b/code2/grime/pkg_mappings.odin @@ -51,6 +51,9 @@ import "core:mem" align_pow2 :: mem.align_forward_int +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 @@ -102,6 +105,7 @@ cursor :: proc { end :: proc { slice_end, + slice_byte_end, string_end, } diff --git a/code2/grime/timing_windows.odin b/code2/grime/timing_windows.odin index bbbbd6e..7e2e6d1 100644 --- a/code2/grime/timing_windows.odin +++ b/code2/grime/timing_windows.odin @@ -18,16 +18,16 @@ 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_fmt("Failed to create win32 timer - ErrorCode: %v", win32.GetLastError() ) - log( msg, LogLevel.Warning, loc) + msg := str_pfmt("Failed to create win32 timer - ErrorCode: %v", win32.GetLastError() ) + log( msg, LoggerLevel.Warning, loc) return false } due_time := win32.LARGE_INTEGER(desired_ms * MS_To_NS) result := win32.SetWaitableTimerEx( timer, & due_time, 0, nil, nil, nil, 0 ) if ! result { - msg := str_fmt("Failed to set win32 timer - ErrorCode: %v", win32.GetLastError() ) - log( msg, LogLevel.Warning, loc) + msg := str_pfmt("Failed to set win32 timer - ErrorCode: %v", win32.GetLastError() ) + log( msg, LoggerLevel.Warning, loc) return false } @@ -41,23 +41,23 @@ thread__highres_wait :: proc( desired_ms : f64, loc := #caller_location ) -> b32 switch wait_result { case WAIT_ABANDONED: - msg := str_fmt("Failed to wait for win32 timer - Error: WAIT_ABANDONED" ) - log( msg, LogLevel.Error, loc) + msg := str_pfmt("Failed to wait for win32 timer - Error: WAIT_ABANDONED" ) + log( msg, LoggerLevel.Error, loc) return false case WAIT_IO_COMPLETION: - msg := str_fmt("Waited for win32 timer: Ended by APC queued to the thread" ) - log( msg, LogLevel.Error, loc) + msg := str_pfmt("Waited for win32 timer: Ended by APC queued to the thread" ) + log( msg, LoggerLevel.Error, loc) return false case WAIT_OBJECT_0: - msg := str_fmt("Waited for win32 timer- Reason : WAIT_OBJECT_0" ) + msg := str_pfmt("Waited for win32 timer- Reason : WAIT_OBJECT_0" ) log( msg, loc = loc) return false case WAIT_FAILED: - msg := str_fmt("Waited for win32 timer failed - ErrorCode: $v", win32.GetLastError() ) - log( msg, LogLevel.Error, loc) + msg := str_pfmt("Waited for win32 timer failed - ErrorCode: $v", win32.GetLastError() ) + log( msg, LoggerLevel.Error, loc) return false } diff --git a/code2/grime/unicode.odin b/code2/grime/unicode.odin index 8173642..5bd2840 100644 --- a/code2/grime/unicode.odin +++ b/code2/grime/unicode.odin @@ -2,6 +2,7 @@ package grime rune16 :: distinct u16 +when false { // Exposing the alloc_error @(require_results) string_to_runes :: proc ( content : string, allocator := context.allocator) -> (runes : []rune, alloc_error: Odin_AllocatorError) #optional_allocator_error { @@ -36,3 +37,5 @@ string_to_runes_array :: proc( content : string, allocator := context.allocator } return runes, alloc_error } + +} \ No newline at end of file diff --git a/code2/grime/virtual_memory.odin b/code2/grime/virtual_memory.odin index 36e3131..87f0a4d 100644 --- a/code2/grime/virtual_memory.odin +++ b/code2/grime/virtual_memory.odin @@ -95,7 +95,7 @@ virtual_release :: proc "contextless" ( vmem : VirtualMemoryRegion ) { } // If the OS is not windows, we just use the library's interface which does not support base_address. -when ODIN_OS != OS_Type.Windows { +when ODIN_OS != .Windows { virtual_resreve__platform_impl :: proc "contextless" ( base_address : uintptr, size : uint ) -> ( vmem : VirtualMemoryRegion, alloc_error : AllocatorError ) {