Code2 Progress: more sokol stuff
This commit is contained in:
@@ -205,7 +205,7 @@ mem_save_point :: proc(ainfo := context.allocator, loc := #caller_location) -> A
|
||||
resolve_allocator_proc(ainfo.procedure)({data = ainfo.data, op = .SavePoint, loc = loc}, & out)
|
||||
return out.save_point
|
||||
}
|
||||
mem_alloc :: proc(size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: bool = false, ainfo : $Type = context.allocator, loc := #caller_location) -> ([]byte, AllocatorError) {
|
||||
mem_alloc :: proc(size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: bool = false, ainfo: $Type = context.allocator, loc := #caller_location) -> ([]byte, AllocatorError) {
|
||||
assert(ainfo.procedure != nil)
|
||||
input := AllocatorProc_In {
|
||||
data = ainfo.data,
|
||||
|
@@ -159,7 +159,7 @@ array_append_at_value :: proc(self: ^Array($Type), item: Type, id: int) -> Alloc
|
||||
return AllocatorError.None
|
||||
}
|
||||
|
||||
array_back :: #force_inline proc "contextless" (self : Array($Type)) -> Type { assert(self.num > 0); return self.data[self.num - 1] }
|
||||
array_back :: #force_inline proc "contextless" (self : Array($Type)) -> Type { assert_contextless(self.num > 0); return self.data[self.num - 1] }
|
||||
|
||||
array_clear :: #force_inline proc "contextless" (self: Array($Type), zero_data: bool = false) {
|
||||
if zero_data do zero(self.data, int(self.num) * size_of(Type))
|
||||
|
@@ -15,9 +15,9 @@ align_pow2 :: #force_inline proc "contextless" (ptr, align: int) -> int {
|
||||
return ptr & ~(align-1)
|
||||
}
|
||||
|
||||
memory_zero_explicit :: #force_inline proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||
mem_zero_volatile(data, len) // Use the volatile mem_zero
|
||||
atomic_thread_fence(.Seq_Cst) // Prevent reordering
|
||||
sync_mem_zero :: #force_inline proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||
mem_zero_volatile(data, len) // Use the volatile mem_zero
|
||||
sync_fence(.Seq_Cst) // Prevent reordering
|
||||
return data
|
||||
}
|
||||
|
||||
@@ -38,11 +38,14 @@ slice_assert :: #force_inline proc "contextless" (s: $SliceType / []$Type) {
|
||||
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_zero :: #force_inline proc "contextless" (s: $SliceType / []$Type) {
|
||||
assert_contextless(len(s) > 0)
|
||||
mem_zero(raw_data(s), size_of(Type) * len(s))
|
||||
}
|
||||
slice_copy :: #force_inline proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
||||
n := max(0, min(len(dst), len(src)))
|
||||
if n > 0 {
|
||||
mem_copy(raw_data(dst), raw_data(src), n * size_of(Type))
|
||||
}
|
||||
assert_contextless(n > 0)
|
||||
mem_copy(raw_data(dst), raw_data(src), n * size_of(Type))
|
||||
return n
|
||||
}
|
||||
|
||||
@@ -84,37 +87,33 @@ calc_padding_with_header :: proc "contextless" (pointer: uintptr, alignment: uin
|
||||
}
|
||||
|
||||
// Helper to get the the beginning of memory after a slice
|
||||
memory_after :: #force_inline proc "contextless" ( s: []byte ) -> ( ^ byte) {
|
||||
@(require_results)
|
||||
memory_after :: #force_inline proc "contextless" (s: []byte ) -> (^byte) {
|
||||
return cursor(s)[len(s):]
|
||||
}
|
||||
|
||||
memory_after_header :: #force_inline proc "contextless" ( header : ^($ Type) ) -> ( [^]byte) {
|
||||
memory_after_header :: #force_inline proc "contextless" (header: ^($Type)) -> ([^]byte) {
|
||||
result := cast( [^]byte) ptr_offset( header, 1 )
|
||||
// result := cast( [^]byte) (cast( [^]Type) header)[ 1:]
|
||||
return result
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
memory_align_formula :: #force_inline proc "contextless" ( size, align : uint) -> uint {
|
||||
memory_align_formula :: #force_inline proc "contextless" (size, align: uint) -> uint {
|
||||
result := size + align - 1
|
||||
return result - result % align
|
||||
}
|
||||
|
||||
// This is here just for docs
|
||||
memory_misalignment :: #force_inline proc ( address, alignment : uintptr) -> uint {
|
||||
memory_misalignment :: #force_inline proc "contextless" (address, alignment: uintptr) -> uint {
|
||||
// address % alignment
|
||||
assert(is_power_of_two(alignment))
|
||||
assert_contextless(is_power_of_two(alignment))
|
||||
return uint( address & (alignment - 1) )
|
||||
}
|
||||
|
||||
// This is here just for docs
|
||||
@(require_results)
|
||||
memory_aign_forward :: #force_inline proc( address, alignment : uintptr) -> uintptr
|
||||
memory_aign_forward :: #force_inline proc "contextless" (address, alignment : uintptr) -> uintptr
|
||||
{
|
||||
assert(is_power_of_two(alignment))
|
||||
|
||||
assert_contextless(is_power_of_two(alignment))
|
||||
aligned_address := address
|
||||
misalignment := cast(uintptr) memory_misalignment( address, alignment )
|
||||
misalignment := transmute(uintptr) memory_misalignment( address, alignment )
|
||||
if misalignment != 0 {
|
||||
aligned_address += alignment - misalignment
|
||||
}
|
||||
|
@@ -80,7 +80,7 @@ import "core:os"
|
||||
file_truncate :: os.truncate
|
||||
file_write :: os.write
|
||||
|
||||
file_read_entire_from_filename :: #force_inline proc(name: string, allocator := context.allocator, loc := #caller_location) -> (data: []byte, success: bool) { return os.read_entire_file_from_filename(name, resolve_odin_allocator(allocator), loc) }
|
||||
file_read_entire_from_filename :: #force_inline proc(name: string, allocator := context.allocator, loc := #caller_location) -> ([]byte, bool) { return os.read_entire_file_from_filename(name, resolve_odin_allocator(allocator), loc) }
|
||||
file_write_entire :: os.write_entire_file
|
||||
|
||||
file_read_entire :: proc {
|
||||
@@ -91,15 +91,13 @@ import "core:strings"
|
||||
StrBuilder :: strings.Builder
|
||||
strbuilder_from_bytes :: strings.builder_from_bytes
|
||||
|
||||
import "core:slice"
|
||||
slice_zero :: slice.zero
|
||||
|
||||
import "core:prof/spall"
|
||||
Spall_Context :: spall.Context
|
||||
Spall_Buffer :: spall.Buffer
|
||||
|
||||
import "core:sync"
|
||||
Mutex :: sync.Mutex
|
||||
sync_fence :: sync.atomic_thread_fence
|
||||
sync_load :: sync.atomic_load_explicit
|
||||
sync_store :: sync.atomic_store_explicit
|
||||
|
||||
@@ -122,54 +120,50 @@ array_append :: proc {
|
||||
array_append_array,
|
||||
array_append_slice,
|
||||
}
|
||||
|
||||
array_append_at :: proc {
|
||||
// array_append_at_array,
|
||||
array_append_at_slice,
|
||||
array_append_at_value,
|
||||
}
|
||||
|
||||
cursor :: proc {
|
||||
raw_cursor,
|
||||
ptr_cursor,
|
||||
slice_cursor,
|
||||
string_cursor,
|
||||
}
|
||||
|
||||
end :: proc {
|
||||
slice_end,
|
||||
slice_byte_end,
|
||||
string_end,
|
||||
}
|
||||
|
||||
copy :: proc {
|
||||
mem_copy,
|
||||
slice_copy,
|
||||
}
|
||||
|
||||
copy_non_overlaping :: proc {
|
||||
mem_copy_non_overlapping,
|
||||
slice_copy_overlapping,
|
||||
}
|
||||
|
||||
fill :: proc {
|
||||
mem_fill,
|
||||
slice_fill,
|
||||
}
|
||||
|
||||
iterator :: proc {
|
||||
iterator_ringbuf_fixed,
|
||||
}
|
||||
make :: proc {
|
||||
array_init,
|
||||
}
|
||||
|
||||
peek_back :: proc {
|
||||
ringbuf_fixed_peak_back,
|
||||
}
|
||||
to_bytes :: proc {
|
||||
slice_to_bytes,
|
||||
type_to_bytes,
|
||||
}
|
||||
|
||||
to_string :: proc {
|
||||
strings.to_string,
|
||||
}
|
||||
|
||||
zero :: proc {
|
||||
mem_zero,
|
||||
slice_zero,
|
||||
|
@@ -1,126 +1,96 @@
|
||||
package grime
|
||||
|
||||
RingBufferFixed :: struct( $Type: typeid, $Size: u32 ) {
|
||||
FRingBuffer :: struct( $Type: typeid, $Size: u32 ) {
|
||||
head : u32,
|
||||
tail : u32,
|
||||
num : u32,
|
||||
items : [Size] Type,
|
||||
}
|
||||
|
||||
ringbuf_fixed_clear :: #force_inline proc "contextless" ( using buffer : ^RingBufferFixed( $Type, $Size)) {
|
||||
head = 0
|
||||
tail = 0
|
||||
num = 0
|
||||
}
|
||||
ringbuf_fixed_cslear :: #force_inline proc "contextless" (ring: ^FRingBuffer($Type, $Size)) { ring.head = 0; ring.tail = 0; ring.num = 0 }
|
||||
ringbuf_fixed_is_full :: #force_inline proc "contextless" (ring: FRingBuffer($Type, $Size)) -> bool { return ring.num == ring.Size }
|
||||
ringbuf_fixed_is_empty :: #force_inline proc "contextless" (ring: FRingBuffer($Type, $Size)) -> bool { return ring.num == 0 }
|
||||
|
||||
ringbuf_fixed_is_full :: #force_inline proc "contextless" ( using buffer : RingBufferFixed( $Type, $Size)) -> bool {
|
||||
return num == Size
|
||||
}
|
||||
|
||||
ringbuf_fixed_is_empty :: #force_inline proc "contextless" ( using buffer : RingBufferFixed( $Type, $Size)) -> bool {
|
||||
return num == 0
|
||||
}
|
||||
|
||||
ringbuf_fixed_peek_front_ref :: #force_inline proc "contextless" ( using buffer : ^RingBufferFixed( $Type, $Size)) -> ^Type {
|
||||
assert(num > 0, "Attempted to peek an empty ring buffer")
|
||||
ringbuf_fixed_peek_front_ref :: #force_inline proc "contextless" (using buffer: ^FRingBuffer($Type, $Size)) -> ^Type {
|
||||
assert_contextless(num > 0, "Attempted to peek an empty ring buffer")
|
||||
return & items[ head ]
|
||||
}
|
||||
|
||||
ringbuf_fixed_peek_front :: #force_inline proc "contextless" ( using buffer : RingBufferFixed( $Type, $Size)) -> Type {
|
||||
assert(num > 0, "Attempted to peek an empty ring buffer")
|
||||
ringbuf_fixed_peek_front :: #force_inline proc "contextless" ( using buffer : FRingBuffer( $Type, $Size)) -> Type {
|
||||
assert_contextless(num > 0, "Attempted to peek an empty ring buffer")
|
||||
return items[ head ]
|
||||
}
|
||||
|
||||
ringbuf_fixed_peak_back :: #force_inline proc ( using buffer : RingBufferFixed( $Type, $Size)) -> Type {
|
||||
assert(num > 0, "Attempted to peek an empty ring buffer")
|
||||
|
||||
ringbuf_fixed_peak_back :: #force_inline proc (using buffer : FRingBuffer( $Type, $Size)) -> Type {
|
||||
assert_contextless(num > 0, "Attempted to peek an empty ring buffer")
|
||||
buf_size := u32(Size)
|
||||
index := (tail - 1 + buf_size) % buf_size
|
||||
return items[ index ]
|
||||
}
|
||||
|
||||
ringbuf_fixed_push :: #force_inline proc(using buffer: ^RingBufferFixed($Type, $Size), value: Type) {
|
||||
ringbuf_fixed_push :: #force_inline proc(using buffer: ^FRingBuffer($Type, $Size), value: Type) {
|
||||
if num == Size do head = (head + 1) % Size
|
||||
else do num += 1
|
||||
|
||||
items[ tail ] = value
|
||||
tail = (tail + 1) % Size
|
||||
}
|
||||
|
||||
ringbuf_fixed_push_slice :: proc(buffer: ^RingBufferFixed($Type, $Size), slice: []Type) -> u32
|
||||
ringbuf_fixed_push_slice :: proc "contextless" (buffer: ^FRingBuffer($Type, $Size), slice: []Type) -> u32
|
||||
{
|
||||
size := u32(Size)
|
||||
slice_size := u32(len(slice))
|
||||
|
||||
// assert( slice_size <= size, "Attempting to append a slice that is larger than the ring buffer!" )
|
||||
assert_contextless( slice_size <= size, "Attempting to append a slice that is larger than the ring buffer!" )
|
||||
if slice_size == 0 do return 0
|
||||
|
||||
items_to_add := min( slice_size, size)
|
||||
items_added : u32 = 0
|
||||
|
||||
if items_to_add > Size - buffer.num
|
||||
{
|
||||
// Some or all existing items will be overwritten
|
||||
overwrite_count := items_to_add - (Size - buffer.num)
|
||||
buffer.head = (buffer.head + overwrite_count) % size
|
||||
buffer.num = size
|
||||
if items_to_add > Size - buffer.num {
|
||||
// Some or all existing items will be overwritten
|
||||
overwrite_count := items_to_add - (Size - buffer.num)
|
||||
buffer.head = (buffer.head + overwrite_count) % size
|
||||
buffer.num = size
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.num += items_to_add
|
||||
else {
|
||||
buffer.num += items_to_add
|
||||
}
|
||||
|
||||
if items_to_add <= size
|
||||
{
|
||||
// Case 1: Slice fits entirely or partially in the buffer
|
||||
space_to_end := size - buffer.tail
|
||||
first_chunk := min(items_to_add, space_to_end)
|
||||
|
||||
// First copy: from tail to end of buffer
|
||||
copy( buffer.items[ buffer.tail: ] , slice[ :first_chunk ] )
|
||||
|
||||
if first_chunk < items_to_add {
|
||||
// Second copy: wrap around to start of buffer
|
||||
second_chunk := items_to_add - first_chunk
|
||||
copy( buffer.items[:], slice[ first_chunk : items_to_add ] )
|
||||
}
|
||||
|
||||
buffer.tail = (buffer.tail + items_to_add) % Size
|
||||
items_added = items_to_add
|
||||
if items_to_add <= size {
|
||||
// Case 1: Slice fits entirely or partially in the buffer
|
||||
space_to_end := size - buffer.tail
|
||||
first_chunk := min(items_to_add, space_to_end)
|
||||
// First copy: from tail to end of buffer
|
||||
copy( buffer.items[ buffer.tail: ] , slice[ :first_chunk ] )
|
||||
if first_chunk < items_to_add {
|
||||
// Second copy: wrap around to start of buffer
|
||||
second_chunk := items_to_add - first_chunk
|
||||
copy( buffer.items[:], slice[ first_chunk : items_to_add ] )
|
||||
}
|
||||
buffer.tail = (buffer.tail + items_to_add) % Size
|
||||
items_added = items_to_add
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 2: Slice is larger than buffer, only keep last Size elements
|
||||
to_add := slice[ slice_size - size: ]
|
||||
|
||||
// First copy: from start of buffer to end
|
||||
first_chunk := min(Size, u32(len(to_add)))
|
||||
copy( buffer.items[:], to_add[ :first_chunk ] )
|
||||
|
||||
if first_chunk < Size
|
||||
{
|
||||
if first_chunk < Size {
|
||||
// Second copy: wrap around
|
||||
copy( buffer.items[ first_chunk: ], to_add[ first_chunk: ] )
|
||||
}
|
||||
|
||||
buffer.head = 0
|
||||
buffer.tail = 0
|
||||
buffer.num = Size
|
||||
items_added = Size
|
||||
}
|
||||
|
||||
return items_added
|
||||
}
|
||||
|
||||
ringbuf_fixed_pop :: #force_inline proc "contextless" ( using buffer : ^RingBufferFixed( $Type, $Size )) -> Type {
|
||||
assert(num > 0, "Attempted to pop an empty ring buffer")
|
||||
ringbuf_fixed_pop :: #force_inline proc "contextless" (using buffer: ^FRingBuffer($Type, $Size)) -> Type {
|
||||
assert_contextless(num > 0, "Attempted to pop an empty ring buffer")
|
||||
value := items[ head ]
|
||||
head = ( head + 1 ) % Size
|
||||
num -= 1
|
||||
num -= 1
|
||||
return value
|
||||
}
|
||||
|
||||
RingBufferFixedIterator :: struct( $Type : typeid) {
|
||||
FRingBufferIterator :: struct($Type : typeid) {
|
||||
items : []Type,
|
||||
head : u32,
|
||||
tail : u32,
|
||||
@@ -128,41 +98,29 @@ RingBufferFixedIterator :: struct( $Type : typeid) {
|
||||
remaining : u32,
|
||||
}
|
||||
|
||||
iterator_ringbuf_fixed :: proc(buffer: ^RingBufferFixed($Type, $Size)) -> RingBufferFixedIterator(Type)
|
||||
iterator_ringbuf_fixed :: proc "contextless" (buffer: ^FRingBuffer($Type, $Size)) -> FRingBufferIterator(Type)
|
||||
{
|
||||
iter := RingBufferFixedIterator(Type){
|
||||
iter := FRingBufferIterator(Type){
|
||||
items = buffer.items[:],
|
||||
head = buffer.head,
|
||||
tail = buffer.tail,
|
||||
remaining = buffer.num,
|
||||
}
|
||||
|
||||
buff_size := u32(Size)
|
||||
|
||||
if buffer.num > 0 {
|
||||
// Start from the last pushed item (one before tail)
|
||||
iter.index = (buffer.tail - 1 + buff_size) % buff_size
|
||||
} else {
|
||||
iter.index = buffer.tail // This will not be used as remaining is 0
|
||||
}
|
||||
|
||||
return iter
|
||||
}
|
||||
|
||||
next_ringbuf_fixed_iterator :: proc(iter : ^RingBufferFixedIterator( $Type)) -> ^Type
|
||||
{
|
||||
using iter
|
||||
if remaining == 0 {
|
||||
return nil // If there are no items left to iterate over
|
||||
}
|
||||
|
||||
next_ringbuf_fixed_iterator :: proc(iter: ^FRingBufferIterator($Type)) -> ^Type {
|
||||
using iter; if remaining == 0 do return nil // If there are no items left to iterate over
|
||||
buf_size := cast(u32) len(items)
|
||||
|
||||
result := &items[index]
|
||||
|
||||
result := &items[index]
|
||||
// Decrement index and wrap around if necessary
|
||||
index = (index - 1 + buf_size) % buf_size
|
||||
|
||||
index = (index - 1 + buf_size) % buf_size
|
||||
remaining -= 1
|
||||
return result
|
||||
}
|
||||
|
@@ -1,9 +1,7 @@
|
||||
package grime
|
||||
|
||||
//region STATIC MEMORY
|
||||
grime_memory: StaticMemory
|
||||
@thread_local grime_thread: ThreadMemory
|
||||
//endregion STATIC MEMORY
|
||||
@(private) grime_memory: StaticMemory
|
||||
@(private, thread_local) grime_thread: ThreadMemory
|
||||
|
||||
StaticMemory :: struct {
|
||||
spall_context: ^Spall_Context,
|
||||
|
@@ -8,3 +8,13 @@ string_cursor :: #force_inline proc "contextless" (s: string) -> [^]u8 { return
|
||||
string_copy :: #force_inline proc "contextless" (dst, src: string) { slice_copy (transmute([]byte) dst, transmute([]byte) src) }
|
||||
string_end :: #force_inline proc "contextless" (s: string) -> ^u8 { return slice_end (transmute([]byte) s) }
|
||||
string_assert :: #force_inline proc "contextless" (s: string) { slice_assert(transmute([]byte) s) }
|
||||
|
||||
str_to_cstr_capped :: proc(content: string, mem: []byte) -> cstring {
|
||||
copy_len := min(len(content), len(mem) - 1)
|
||||
if copy_len > 0 do copy(mem[:copy_len], transmute([]byte) content)
|
||||
mem[copy_len] = 0
|
||||
return transmute(cstring) raw_data(mem)
|
||||
}
|
||||
|
||||
cstr_len_capped :: #force_inline proc "contextless" (content: cstring, cap: int) -> (len: int) { for len = 0; (len <= cap) && (transmute([^]byte)content)[len] != 0; len += 1 {} return }
|
||||
cstr_to_str_capped :: #force_inline proc "contextless" (content: cstring, mem: []byte) -> string { return transmute(string) Raw_String { cursor(mem), cstr_len_capped (content, len(mem)) } }
|
||||
|
@@ -271,7 +271,6 @@ host_job_worker_entrypoint :: proc(worker_thread: ^SysThread)
|
||||
leader := barrier_wait(& host_memory.lane_job_sync)
|
||||
}
|
||||
|
||||
@export
|
||||
sync_client_api :: proc()
|
||||
{
|
||||
profile(#procedure)
|
||||
|
@@ -35,12 +35,11 @@ then prepare for multi-threaded "laned" tick: thread_wide_startup.
|
||||
@export
|
||||
startup :: proc(host_mem: ^ProcessMemory, thread_mem: ^ThreadMemory)
|
||||
{
|
||||
// Rad Debugger driving me crazy..
|
||||
// NOTE(Ed): This is not necessary, they're just loops for my sanity.
|
||||
for ; memory == nil; { memory = host_mem }
|
||||
for ; thread == nil; { thread = thread_mem }
|
||||
grime_set_profiler_module_context(& memory.spall_context)
|
||||
grime_set_profiler_thread_buffer(& thread.spall_buffer)
|
||||
// (Ignore RAD Debugger's values being null)
|
||||
memory = host_mem
|
||||
thread = thread_mem
|
||||
// grime_set_profiler_module_context(& memory.spall_context)
|
||||
// grime_set_profiler_thread_buffer(& thread.spall_buffer)
|
||||
profile(#procedure)
|
||||
|
||||
startup_tick := tick_now()
|
||||
@@ -126,14 +125,14 @@ hot_reload :: proc(host_mem: ^ProcessMemory, thread_mem: ^ThreadMemory)
|
||||
thread = thread_mem
|
||||
if thread.id == .Master_Prepper {
|
||||
sync_store(& memory, host_mem, .Release)
|
||||
grime_set_profiler_module_context(& memory.spall_context)
|
||||
// grime_set_profiler_module_context(& memory.spall_context)
|
||||
}
|
||||
else {
|
||||
// NOTE(Ed): This is problably not necessary, they're just loops for my sanity.
|
||||
for ; memory == nil; { sync_load(& memory, .Acquire) }
|
||||
for ; thread == nil; { thread = thread_mem }
|
||||
}
|
||||
grime_set_profiler_thread_buffer(& thread.spall_buffer)
|
||||
// grime_set_profiler_thread_buffer(& thread.spall_buffer)
|
||||
}
|
||||
profile(#procedure)
|
||||
// Do hot-reload stuff...
|
||||
@@ -177,7 +176,7 @@ tick_lane_startup :: proc(thread_mem: ^ThreadMemory)
|
||||
{
|
||||
if thread_mem.id != .Master_Prepper {
|
||||
thread = thread_mem
|
||||
grime_set_profiler_thread_buffer(& thread.spall_buffer)
|
||||
// grime_set_profiler_thread_buffer(& thread.spall_buffer)
|
||||
}
|
||||
profile(#procedure)
|
||||
}
|
||||
@@ -187,7 +186,7 @@ job_worker_startup :: proc(thread_mem: ^ThreadMemory)
|
||||
{
|
||||
if thread_mem.id != .Master_Prepper {
|
||||
thread = thread_mem
|
||||
grime_set_profiler_thread_buffer(& thread.spall_buffer)
|
||||
// grime_set_profiler_thread_buffer(& thread.spall_buffer)
|
||||
}
|
||||
profile(#procedure)
|
||||
}
|
||||
|
@@ -2,10 +2,13 @@ package sectr
|
||||
|
||||
import sokol_app "thirdparty:sokol/app"
|
||||
|
||||
//region Sokol App
|
||||
|
||||
sokol_app_init_callback :: proc "c" () {
|
||||
context = memory.client_memory.sokol_context
|
||||
log_print("sokol_app: Confirmed initialization")
|
||||
}
|
||||
|
||||
// This is being filled in but we're directly controlling the lifetime of sokol_app's execution.
|
||||
// So this will only get called during window pan or resize events (on Win32 at least)
|
||||
sokol_app_frame_callback :: proc "c" ()
|
||||
@@ -37,3 +40,220 @@ sokol_app_frame_callback :: proc "c" ()
|
||||
tick_lane_frametime( & client_tick, sokol_delta_ms, sokol_delta_ns, can_sleep = false )
|
||||
window.resized = false
|
||||
}
|
||||
|
||||
sokol_app_cleanup_callback :: proc "c" () {
|
||||
context = memory.client_memory.sokol_context
|
||||
log_print("sokol_app: Confirmed cleanup")
|
||||
}
|
||||
|
||||
sokol_app_alloc :: proc "c" ( size : uint, user_data : rawptr ) -> rawptr {
|
||||
context = memory.client_memory.sokol_context
|
||||
// block, error := mem_alloc( int(size), allocator = persistent_slab_allocator() )
|
||||
// ensure(error == AllocatorError.None, "sokol_app allocation failed")
|
||||
// return block
|
||||
// TODO(Ed): Implement
|
||||
return nil
|
||||
}
|
||||
|
||||
sokol_app_free :: proc "c" ( data : rawptr, user_data : rawptr ) {
|
||||
context = memory.client_memory.sokol_context
|
||||
// mem_free(data, allocator = persistent_slab_allocator() )
|
||||
// TODO(Ed): Implement
|
||||
}
|
||||
|
||||
sokol_app_log_callback :: proc "c" (
|
||||
tag: cstring,
|
||||
log_level: u32,
|
||||
log_item_id: u32,
|
||||
message_or_null: cstring,
|
||||
line_nr: u32,
|
||||
filename_or_null: cstring,
|
||||
user_data: rawptr)
|
||||
{
|
||||
context = memory.client_memory.sokol_context
|
||||
odin_level: LoggerLevel
|
||||
switch log_level {
|
||||
case 0: odin_level = .Fatal
|
||||
case 1: odin_level = .Error
|
||||
case 2: odin_level = .Warning
|
||||
case 3: odin_level = .Info
|
||||
}
|
||||
clone_backing: [16 * Kilo]byte
|
||||
|
||||
cloned_msg: string = "";
|
||||
if message_or_null != nil {
|
||||
cloned_msg = cstr_to_str_capped(message_or_null, clone_backing[:])
|
||||
}
|
||||
cloned_fname: string = ""
|
||||
if filename_or_null != nil {
|
||||
cloned_fname = cstr_to_str_capped(filename_or_null, clone_backing[len(cloned_msg):])
|
||||
}
|
||||
cloned_tag := cstr_to_str_capped(tag, clone_backing[len(cloned_msg) + len(cloned_fname):])
|
||||
log_print_fmt( "%-80s %s::%v", cloned_msg, cloned_tag, line_nr, level = odin_level )
|
||||
}
|
||||
|
||||
// TODO(Ed): Does this need to be queued to a separate thread?
|
||||
sokol_app_event_callback :: proc "c" (sokol_event: ^sokol_app.Event)
|
||||
{
|
||||
context = memory.client_memory.sokol_context
|
||||
event: InputEvent
|
||||
using event
|
||||
|
||||
_sokol_frame_id = sokol_event.frame_count
|
||||
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 }
|
||||
|
||||
switch sokol_event.type
|
||||
{
|
||||
case .INVALID:
|
||||
log_print_fmt("sokol_app - event: INVALID?")
|
||||
log_print_fmt("%v", sokol_event)
|
||||
|
||||
case .KEY_DOWN:
|
||||
if sokol_event.key_repeat do return
|
||||
|
||||
type = .Key_Pressed
|
||||
key = to_key_from_sokol( sokol_event.key_code )
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
// logf("Key pressed(sokol): %v", key)
|
||||
// logf("frame (sokol): %v", frame_id )
|
||||
|
||||
case .KEY_UP:
|
||||
if sokol_event.key_repeat do return
|
||||
|
||||
type = .Key_Released
|
||||
key = to_key_from_sokol( sokol_event.key_code )
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
// logf("Key released(sokol): %v", key)
|
||||
// logf("frame (sokol): %v", frame_id )
|
||||
|
||||
case .CHAR:
|
||||
if sokol_event.key_repeat do return
|
||||
|
||||
type = .Unicode
|
||||
codepoint = transmute(rune) sokol_event.char_code
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_DOWN:
|
||||
type = .Mouse_Pressed
|
||||
mouse.btn = to_mouse_btn_from_sokol( sokol_event.mouse_button )
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_UP:
|
||||
type = .Mouse_Released
|
||||
mouse.btn = to_mouse_btn_from_sokol( sokol_event.mouse_button )
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_SCROLL:
|
||||
type = .Mouse_Scroll
|
||||
mouse.scroll = { sokol_event.scroll_x, sokol_event.scroll_y }
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_MOVE:
|
||||
type = .Mouse_Move
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_ENTER:
|
||||
type = .Mouse_Enter
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
case .MOUSE_LEAVE:
|
||||
type = .Mouse_Leave
|
||||
modifiers = to_modifiers_code_from_sokol( sokol_event.modifiers )
|
||||
sokol_app.consume_event()
|
||||
append_staged_input_events( event )
|
||||
|
||||
// TODO(Ed): Add support
|
||||
case .TOUCHES_BEGAN:
|
||||
case .TOUCHES_MOVED:
|
||||
case .TOUCHES_ENDED:
|
||||
case .TOUCHES_CANCELLED:
|
||||
|
||||
case .RESIZED: sokol_app.consume_event()
|
||||
case .ICONIFIED: sokol_app.consume_event()
|
||||
case .RESTORED: sokol_app.consume_event()
|
||||
case .FOCUSED: sokol_app.consume_event()
|
||||
case .UNFOCUSED: sokol_app.consume_event()
|
||||
case .SUSPENDED: sokol_app.consume_event()
|
||||
case .RESUMED: sokol_app.consume_event()
|
||||
case .QUIT_REQUESTED: sokol_app.consume_event()
|
||||
case .CLIPBOARD_PASTED: sokol_app.consume_event()
|
||||
case .FILES_DROPPED: sokol_app.consume_event()
|
||||
|
||||
case .DISPLAY_CHANGED:
|
||||
log_print_fmt("sokol_app - event: Display changed")
|
||||
log_print_fmt("refresh rate: %v", sokol_app.refresh_rate())
|
||||
monitor_refresh_hz := sokol_app.refresh_rate()
|
||||
sokol_app.consume_event()
|
||||
}
|
||||
}
|
||||
|
||||
//endregion Sokol App
|
||||
|
||||
//region Sokol GFX
|
||||
|
||||
sokol_gfx_alloc :: proc "c" ( size : uint, user_data : rawptr ) -> rawptr {
|
||||
context = memory.client_memory.sokol_context
|
||||
// block, error := mem_alloc( int(size), allocator = persistent_slab_allocator() )
|
||||
// ensure(error == AllocatorError.None, "sokol_gfx allocation failed")
|
||||
// return block
|
||||
// TODO(Ed): Implement
|
||||
return nil
|
||||
}
|
||||
|
||||
sokol_gfx_free :: proc "c" ( data : rawptr, user_data : rawptr ) {
|
||||
context = memory.client_memory.sokol_context
|
||||
// TODO(Ed): Implement
|
||||
// free(data, allocator = persistent_slab_allocator() )
|
||||
}
|
||||
|
||||
sokol_gfx_log_callback :: proc "c" (
|
||||
tag: cstring,
|
||||
log_level: u32,
|
||||
log_item_id: u32,
|
||||
message_or_null: cstring,
|
||||
line_nr: u32,
|
||||
filename_or_null: cstring,
|
||||
user_data: rawptr)
|
||||
{
|
||||
context = memory.client_memory.sokol_context
|
||||
odin_level : LoggerLevel
|
||||
switch log_level {
|
||||
case 0: odin_level = .Fatal
|
||||
case 1: odin_level = .Error
|
||||
case 2: odin_level = .Warning
|
||||
case 3: odin_level = .Info
|
||||
}
|
||||
clone_backing: [16 * Kilo]byte
|
||||
|
||||
cloned_msg : string = ""
|
||||
if message_or_null != nil {
|
||||
cloned_msg = cstr_to_str_capped(message_or_null, clone_backing[:])
|
||||
}
|
||||
cloned_fname : string = ""
|
||||
if filename_or_null != nil {
|
||||
cloned_fname = cstr_to_str_capped(filename_or_null, clone_backing[len(cloned_msg):])
|
||||
}
|
||||
cloned_tag := cstr_to_str_capped(tag, clone_backing[len(cloned_msg) + len(cloned_fname):])
|
||||
log_print_fmt( "%-80s %s::%v", cloned_msg, cloned_tag, line_nr, level = odin_level )
|
||||
}
|
||||
|
||||
//endregion Sokol GFX
|
||||
|
@@ -19,6 +19,7 @@ import "core:log"
|
||||
LoggerLevel :: log.Level
|
||||
|
||||
import "core:mem"
|
||||
AllocatorError :: mem.Allocator_Error
|
||||
// Used strickly for the logger
|
||||
Odin_Arena :: mem.Arena
|
||||
odin_arena_allocator :: mem.arena_allocator
|
||||
@@ -60,14 +61,38 @@ import "core:time"
|
||||
tick_now :: time.tick_now
|
||||
|
||||
import "codebase:grime"
|
||||
Logger :: grime.Logger
|
||||
logger_init :: grime.logger_init
|
||||
to_odin_logger :: grime.to_odin_logger
|
||||
|
||||
Array :: grime.Array
|
||||
array_to_slice :: grime.array_to_slice
|
||||
array_append_array :: grime.array_append_array
|
||||
array_append_slice :: grime.array_append_slice
|
||||
array_append_value :: grime.array_append_value
|
||||
array_back :: grime.array_back
|
||||
array_clear :: grime.array_clear
|
||||
// Logging
|
||||
Logger :: grime.Logger
|
||||
logger_init :: grime.logger_init
|
||||
// Memory
|
||||
mem_alloc :: grime.mem_alloc
|
||||
mem_copy :: grime.mem_copy
|
||||
mem_copy_non_overlapping :: grime.mem_copy_non_overlapping
|
||||
mem_zero :: grime.mem_zero
|
||||
slice_zero :: grime.slice_zero
|
||||
// Ring Buffer
|
||||
FRingBuffer :: grime.FRingBuffer
|
||||
FRingBufferIterator :: grime.FRingBufferIterator
|
||||
ringbuf_fixed_peak_back :: grime.ringbuf_fixed_peak_back
|
||||
ringbuf_fixed_push :: grime.ringbuf_fixed_push
|
||||
ringbuf_fixed_push_slice :: grime.ringbuf_fixed_push_slice
|
||||
iterator_ringbuf_fixed :: grime.iterator_ringbuf_fixed
|
||||
next_ringbuf_fixed_iterator :: grime.next_ringbuf_fixed_iterator
|
||||
// Strings
|
||||
cstr_to_str_capped :: grime.cstr_to_str_capped
|
||||
to_odin_logger :: grime.to_odin_logger
|
||||
// Operating System
|
||||
set__scheduler_granularity :: grime.set__scheduler_granularity
|
||||
|
||||
grime_set_profiler_module_context :: grime.set_profiler_module_context
|
||||
grime_set_profiler_thread_buffer :: grime.set_profiler_thread_buffer
|
||||
// grime_set_profiler_module_context :: grime.set_profiler_module_context
|
||||
// grime_set_profiler_thread_buffer :: grime.set_profiler_thread_buffer
|
||||
|
||||
Kilo :: 1024
|
||||
Mega :: Kilo * 1024
|
||||
@@ -141,13 +166,24 @@ add :: proc {
|
||||
add_r2f4,
|
||||
add_biv3f4,
|
||||
}
|
||||
|
||||
append :: proc {
|
||||
array_append_array,
|
||||
array_append_slice,
|
||||
array_append_value,
|
||||
}
|
||||
array_append :: proc {
|
||||
array_append_array,
|
||||
array_append_slice,
|
||||
array_append_value,
|
||||
}
|
||||
biv3f4 :: proc {
|
||||
biv3f4_via_f32s,
|
||||
v3f4_to_biv3f4,
|
||||
}
|
||||
bivec :: biv3f4
|
||||
|
||||
clear :: proc {
|
||||
array_clear,
|
||||
}
|
||||
cross :: proc {
|
||||
cross_s,
|
||||
cross_v2,
|
||||
@@ -156,11 +192,9 @@ cross :: proc {
|
||||
cross_v3f4_uv3f4,
|
||||
cross_u3f4_v3f4,
|
||||
}
|
||||
|
||||
div :: proc {
|
||||
div_biv3f4_f32,
|
||||
}
|
||||
|
||||
dot :: proc {
|
||||
sdot,
|
||||
vdot,
|
||||
@@ -171,75 +205,76 @@ dot :: proc {
|
||||
dot_v3f4_uv3f4,
|
||||
dot_uv3f4_v3f4,
|
||||
}
|
||||
|
||||
equal :: proc {
|
||||
equal_r2f4,
|
||||
}
|
||||
|
||||
is_power_of_two :: proc {
|
||||
is_power_of_two_u32,
|
||||
// is_power_of_two_uintptr,
|
||||
}
|
||||
|
||||
iterator :: proc {
|
||||
iterator_ringbuf_fixed,
|
||||
}
|
||||
mov_avg_exp :: proc {
|
||||
mov_avg_exp_f32,
|
||||
mov_avg_exp_f64,
|
||||
}
|
||||
|
||||
mul :: proc {
|
||||
mul_biv3f4,
|
||||
mul_biv3f4_f32,
|
||||
mul_f32_biv3f4,
|
||||
}
|
||||
|
||||
join :: proc {
|
||||
join_r2f4,
|
||||
}
|
||||
|
||||
inverse_sqrt :: proc {
|
||||
inverse_sqrt_f32,
|
||||
}
|
||||
|
||||
next :: proc {
|
||||
next_ringbuf_fixed_iterator,
|
||||
}
|
||||
point3 :: proc {
|
||||
v3f4_to_point3f4,
|
||||
}
|
||||
|
||||
pow2 :: proc {
|
||||
pow2_v3f4,
|
||||
}
|
||||
|
||||
peek_back :: proc {
|
||||
ringbuf_fixed_peak_back,
|
||||
}
|
||||
push :: proc {
|
||||
ringbuf_fixed_push,
|
||||
ringbuf_fixed_push_slice,
|
||||
}
|
||||
quatf4 :: proc {
|
||||
quatf4_from_rotor3f4,
|
||||
}
|
||||
|
||||
regress :: proc {
|
||||
regress_biv3f4,
|
||||
}
|
||||
|
||||
rotor3 :: proc {
|
||||
rotor3f4_via_comps_f4,
|
||||
rotor3f4_via_bv_s_f4,
|
||||
// rotor3f4_via_from_to_v3f4,
|
||||
}
|
||||
|
||||
size :: proc {
|
||||
size_r2f4,
|
||||
}
|
||||
|
||||
sub :: proc {
|
||||
sub_r2f4,
|
||||
sub_biv3f4,
|
||||
// join_point3_f4,
|
||||
// join_pointflat3_f4,
|
||||
}
|
||||
|
||||
to_slice :: proc {
|
||||
array_to_slice,
|
||||
}
|
||||
v2f4 :: proc {
|
||||
v2f4_from_f32s,
|
||||
v2f4_from_scalar,
|
||||
v2f4_from_v2s4,
|
||||
v2s4_from_v2f4,
|
||||
}
|
||||
|
||||
v3f4 :: proc {
|
||||
v3f4_via_f32s,
|
||||
biv3f4_to_v3f4,
|
||||
@@ -247,14 +282,12 @@ v3f4 :: proc {
|
||||
pointflat3f4_to_v3f4,
|
||||
uv3f4_to_v3f4,
|
||||
}
|
||||
|
||||
v2 :: proc {
|
||||
v2f4_from_f32s,
|
||||
v2f4_from_scalar,
|
||||
v2f4_from_v2s4,
|
||||
v2s4_from_v2f4,
|
||||
}
|
||||
|
||||
v3 :: proc {
|
||||
v3f4_via_f32s,
|
||||
biv3f4_to_v3f4,
|
||||
@@ -262,12 +295,14 @@ v3 :: proc {
|
||||
pointflat3f4_to_v3f4,
|
||||
uv3f4_to_v3f4,
|
||||
}
|
||||
|
||||
v4 :: proc {
|
||||
uv4f4_to_v4f4,
|
||||
}
|
||||
|
||||
wedge :: proc {
|
||||
wedge_v3f4,
|
||||
wedge_biv3f4,
|
||||
}
|
||||
zero :: proc {
|
||||
mem_zero,
|
||||
slice_zero,
|
||||
}
|
||||
|
@@ -97,6 +97,7 @@ $flag_radlink = '-radlink'
|
||||
$flag_sanitize_address = '-sanitize:address'
|
||||
$flag_sanitize_memory = '-sanitize:memory'
|
||||
$flag_sanitize_thread = '-sanitize:thread'
|
||||
$flag_show_definables = '-show-defineables'
|
||||
$flag_subsystem = '-subsystem:'
|
||||
$flag_show_debug_messages = '-show-debug-messages'
|
||||
$flag_show_timings = '-show-timings'
|
||||
@@ -233,13 +234,14 @@ push-location $path_root
|
||||
# $build_args += $flag_sanitize_address
|
||||
# $build_args += $flag_sanitize_memory
|
||||
# $build_args += $flag_show_debug_messages
|
||||
$build_args += $flag_show_definabless
|
||||
$build_args += $flag_show_timings
|
||||
# $build_args += $flag_build_diagnostics
|
||||
# TODO(Ed): Enforce nil default allocator
|
||||
|
||||
foreach ($arg in $build_args) {
|
||||
write-host `t $arg -ForegroundColor Cyan
|
||||
}
|
||||
# foreach ($arg in $build_args) {
|
||||
# write-host `t $arg -ForegroundColor Cyan
|
||||
# }
|
||||
|
||||
if ( Test-Path $module_dll) {
|
||||
$module_dll_pre_build_hash = get-filehash -path $module_dll -Algorithm MD5
|
||||
@@ -301,8 +303,8 @@ push-location $path_root
|
||||
# $build_args += $flag_micro_architecture_native
|
||||
$build_args += $flag_microarch_zen5
|
||||
$build_args += $flag_thread_count + $CoreCount_Physical
|
||||
$build_args += $flag_optimize_none
|
||||
# $build_args += $flag_optimize_minimal
|
||||
# $build_args += $flag_optimize_none
|
||||
$build_args += $flag_optimize_minimal
|
||||
# $build_args += $flag_optimize_speed
|
||||
# $build_args += $falg_optimize_aggressive
|
||||
$build_args += $flag_debug
|
||||
@@ -318,11 +320,12 @@ push-location $path_root
|
||||
# $build_args += $flag_sanitize_address
|
||||
# $build_args += $flag_sanitize_memory
|
||||
# $build_args += $flag_build_diagnostics
|
||||
$build_args += $flag_show_definabless
|
||||
# TODO(Ed): Enforce nil default allocator
|
||||
|
||||
foreach ($arg in $build_args) {
|
||||
write-host `t $arg -ForegroundColor Cyan
|
||||
}
|
||||
# foreach ($arg in $build_args) {
|
||||
# write-host `t $arg -ForegroundColor Cyan
|
||||
# }
|
||||
|
||||
if ( Test-Path $executable) {
|
||||
$executable_pre_build_hash = get-filehash -path $executable -Algorithm MD5
|
||||
|
Reference in New Issue
Block a user