diff --git a/Code/Dqn.h b/Code/Dqn.h index e8ee747..5eb060e 100644 --- a/Code/Dqn.h +++ b/Code/Dqn.h @@ -564,42 +564,53 @@ DQN_HEADER_COPY_PROTOTYPE(template T *, Dqn_MemZero(T *src)) return result; } +// @ ------------------------------------------------------------------------------------------------- +// @ +// @ NOTE: Dqn_Allocator +// @ +// @ ------------------------------------------------------------------------------------------------- +DQN_HEADER_COPY_BEGIN +// NOTE: The default allocator is the heap allocator +enum struct Dqn_Allocator_Type +{ + Heap, // Malloc, realloc, free + XHeap, // Malloc realloc, free, crash on failure + Arena, + NullAllocator, +}; + +struct Dqn_Allocator +{ + Dqn_Allocator_Type type; + void *data; +}; +DQN_HEADER_COPY_END + // @ ------------------------------------------------------------------------------------------------- // @ // @ NOTE: Dqn_MemArena // @ // @ ------------------------------------------------------------------------------------------------- DQN_HEADER_COPY_BEGIN -using Dqn_MemSize = Dqn_usize; struct Dqn_MemBlock { - // NOTE: Read only state - Dqn_b32 allocated_by_user_or_fixed_mem; void *memory; - Dqn_MemSize size; - Dqn_MemSize used; + Dqn_usize size; + Dqn_usize used; Dqn_MemBlock *prev; Dqn_MemBlock *next; }; -enum Dqn_MemArenaFlag -{ - Dqn_MemArenaFlag_NoCRTAllocation = (1 << 0), // If my_calloc/my_free aren't null, it defaults to calloc and free, setting this flag disables that -}; - struct Dqn_MemArena { - // NOTE: Configuration (fill once) - void *(*my_calloc)(Dqn_usize bytes); // If nullptr, use CRT calloc unless disabled in flags - void (*my_free) (void *ptr, Dqn_usize bytes_to_free); // If nullptr, use CRT free unless disabled in flags - Dqn_u32 flags; + // NOTE: Configuration (fill once after "Zero Initialisation {}") + int min_block_size = DQN_KILOBYTES(4); + Dqn_Allocator allocator; // NOTE: Read Only - Dqn_u8 fixed_mem[DQN_KILOBYTES(16)]; - Dqn_MemBlock fixed_mem_block; Dqn_MemBlock *curr_mem_block; Dqn_MemBlock *top_mem_block; - Dqn_MemSize highest_used_mark; + Dqn_usize highest_used_mark; int total_allocated_mem_blocks; }; @@ -621,12 +632,11 @@ struct Dqn_MemArenaScopedRegion #define DQN_DEBUG_PARAMS #endif +#define DQN_MEM_ARENA_INIT_MEMORY(arena, src, size) Dqn_MemArena_InitMemory(arena, src, size DQN_DEBUG_PARAMS) #define DQN_MEM_ARENA_ALLOC(arena, size) Dqn_MemArena_Alloc(arena, size DQN_DEBUG_PARAMS) #define DQN_MEM_ARENA_ALLOC_ARRAY(arena, T, num) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) * num DQN_DEBUG_PARAMS) #define DQN_MEM_ARENA_ALLOC_STRUCT(arena, T) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) DQN_DEBUG_PARAMS) #define DQN_MEM_ARENA_RESERVE(arena, size) Dqn_MemArena_Reserve(arena, size DQN_DEBUG_PARAMS) -#define DQN_MEM_ARENA_RESERVE_FROM(arena, src, size) Dqn_MemArena_ReserveFrom(arena, src, size DQN_DEBUG_PARAMS) -#define DQN_MEM_ARENA_CLEAR_USED(arena) Dqn_MemArena_ClearUsed(arena DQN_DEBUG_PARAMS) #define DQN_MEM_ARENA_FREE(arena) Dqn_MemArena_Free DQN_HEADER_COPY_END @@ -639,8 +649,8 @@ DQN_HEADER_COPY_BEGIN struct Dqn_StringBuilderBuffer { char *mem; - Dqn_MemSize size; - Dqn_MemSize used; + Dqn_usize size; + usize used; Dqn_StringBuilderBuffer *next; }; @@ -648,11 +658,9 @@ Dqn_usize constexpr DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE = DQN_KILOBYTES(4) template struct Dqn_StringBuilder { - void *(*my_malloc)(size_t bytes) = malloc; // Set to nullptr to disable heap allocation - void (*my_free) (void *ptr) = free; // Set to nullptr to disable heap allocation - + Dqn_Allocator allocator; char fixed_mem[N]; - Dqn_MemSize fixed_mem_used; + Dqn_usize fixed_mem_used; Dqn_StringBuilderBuffer *next_mem_buf; Dqn_StringBuilderBuffer *last_mem_buf; Dqn_isize string_len; @@ -668,23 +676,20 @@ template DQN_FILE_SCOPE char *Dqn_StringBuilder__GetWriteBufferAnd if (builder->last_mem_buf) { Dqn_StringBuilderBuffer *last_buf = builder->last_mem_buf; - result = last_buf->mem + last_buf->used; - space = last_buf->size - last_buf->used; - usage = &last_buf->used; + result = last_buf->mem + last_buf->used; + space = last_buf->size - last_buf->used; + usage = &last_buf->used; } if (space < size_required) { - DQN_ASSERT(builder->my_malloc); - if (!builder->my_malloc) - return nullptr; - // NOTE: Need to allocate new buf Dqn_usize allocation_size = sizeof(*builder->last_mem_buf) + DQN_MAX(size_required, DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE); - void *memory = builder->my_malloc(allocation_size); - auto *new_buf = reinterpret_cast(memory); + void *memory = Dqn_Allocator_Allocate(&builder->allocator, allocation_size); + if (!memory) return nullptr; + auto *new_buf = DQN_CAST(Dqn_StringBuilderBuffer *)memory; *new_buf = {}; - new_buf->mem = static_cast(memory) + sizeof(*new_buf); + new_buf->mem = DQN_CAST(char *)memory + sizeof(*new_buf); new_buf->size = allocation_size; result = new_buf->mem; usage = &new_buf->used; @@ -746,11 +751,6 @@ template DQN_FILE_SCOPE void Dqn_StringBuilder__BuildOutput(Dqn_St DQN_ASSERT(buf_ptr == dest + dest_size); } -// ----------------------------------------------------------------------------------------------- -// -// NOTE: String Builder -// -// ----------------------------------------------------------------------------------------------- // @ The necessary length to build the string, it returns the length including the null-terminator DQN_HEADER_COPY_PROTOTYPE(template Dqn_isize, Dqn_StringBuilder_BuildLen(Dqn_StringBuilder const *builder)) { @@ -817,6 +817,22 @@ DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_AppendC buf[1] = 0; } +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_Free(Dqn_StringBuilder *builder)) +{ + for (Dqn_StringBuilderBuffer *buffer = builder->next_mem_buf; + buffer; + ) + { + Dqn_StringBuilderBuffer buffer_to_free = buffer; + buffer = buffer->next; + Dqn_Allocator_Free(&builder->allocator, buffer_to_free); + } + + builder->next_mem_buf = builder->last_mem_buf = nullptr; + builder->fixed_mem_used = 0; + builder->string_len = 0; +} + // @ ------------------------------------------------------------------------------------------------- // @ // @ NOTE: Dqn_Slices @@ -1072,22 +1088,6 @@ template T *Dqn_FixedStack_Push (Dqn_FixedStack void Dqn_FixedStack_Clear(Dqn_FixedStack *array) { Dqn_FixedArray_Clear(array); } DQN_HEADER_COPY_END -DQN_HEADER_COPY_BEGIN -enum struct Dqn_Allocator_Type -{ - Heap, // Malloc, realloc, free - XHeap, // Malloc realloc, free, crash on failure - Arena, - NullAllocator, -}; - -struct Dqn_Allocator -{ - Dqn_Allocator_Type type; - void *data; -}; -DQN_HEADER_COPY_END - // @ ------------------------------------------------------------------------------------------------- // @ // @ NOTE: Dqn_Array @@ -1335,213 +1335,8 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_Log(Dqn_LogType type, char const *file, Dqn_ va_end(va); } -// @ ------------------------------------------------------------------------------------------------- -// @ -// @ NOTE: Dqn_MemArena -// @ -// @ ------------------------------------------------------------------------------------------------- -DQN_FILE_SCOPE Dqn_MemBlock *Dqn_MemArena__AllocateBlock(Dqn_MemArena *arena, Dqn_usize requested_size) -{ - Dqn_usize mem_block_size = DQN_MAX(Dqn_ArrayCount(arena->fixed_mem), requested_size); - Dqn_usize const allocate_size = sizeof(*arena->curr_mem_block) + mem_block_size; - Dqn_MemBlock *result = nullptr; - - if (arena->my_calloc) - { - DQN_ASSERT(arena->my_free); - result = static_cast(arena->my_calloc(allocate_size)); - } - else - { - if (!(arena->flags & Dqn_MemArenaFlag_NoCRTAllocation)) - result = static_cast(calloc(1, allocate_size)); - } - - if (!result) - return result; - - *result = {}; - result->size = mem_block_size; - result->memory = reinterpret_cast(result) + sizeof(*result); - arena->total_allocated_mem_blocks++; - return result; -} - -DQN_FILE_SCOPE void Dqn_MemArena__FreeBlock(Dqn_MemArena *arena, Dqn_MemBlock *block) -{ - if (!block) - return; - - if (block->next) - block->next->prev = block->prev; - - if (block->prev) - block->prev->next = block->next; - - if (!block->allocated_by_user_or_fixed_mem) - { - if (arena->my_free) - { - DQN_ASSERT(arena->my_calloc); - arena->my_free(block, sizeof(*block) + block->size); - } - else - { - if (!(arena->flags & Dqn_MemArenaFlag_NoCRTAllocation)) - free(block); - } - } -} - -DQN_FILE_SCOPE void Dqn_MemArena__AttachBlock(Dqn_MemArena *arena, Dqn_MemBlock *new_block) -{ - DQN_ASSERT(arena->curr_mem_block); - DQN_ASSERT(arena->top_mem_block->next == nullptr); - arena->top_mem_block->next = new_block; - new_block->prev = arena->top_mem_block; - arena->top_mem_block = new_block; -} - -DQN_FILE_SCOPE void Dqn_MemArena__LazyInit(Dqn_MemArena *arena) -{ - if (!arena->curr_mem_block) - { - DQN_ASSERT(!arena->top_mem_block); - arena->fixed_mem_block = {}; - arena->fixed_mem_block.allocated_by_user_or_fixed_mem = true; - arena->fixed_mem_block.memory = arena->fixed_mem; - arena->fixed_mem_block.size = Dqn_ArrayCount(arena->fixed_mem); - arena->curr_mem_block = &arena->fixed_mem_block; - arena->top_mem_block = arena->curr_mem_block; - } -} - - -DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemArena_Alloc(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS)) -{ -#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) - (void)file; (void)file_len; (void)func; (void)func_len; (void)line; -#endif - Dqn_MemArena__LazyInit(arena); - Dqn_b32 need_new_mem_block = true; - - for (Dqn_MemBlock *mem_block = arena->curr_mem_block; mem_block; mem_block = mem_block->next) - { - Dqn_b32 can_fit_in_block = (mem_block->used + size) <= mem_block->size; - if (can_fit_in_block) - { - arena->curr_mem_block = mem_block; - need_new_mem_block = false; - break; - } - } - - if (need_new_mem_block) - { - Dqn_MemBlock *new_block = Dqn_MemArena__AllocateBlock(arena, size); - if (!new_block) return nullptr; - Dqn_MemArena__AttachBlock(arena, new_block); - arena->curr_mem_block = arena->top_mem_block; - } - - void *result = static_cast(arena->curr_mem_block->memory) + arena->curr_mem_block->used; - arena->curr_mem_block->used += size; - DQN_ASSERT(arena->curr_mem_block->used <= arena->curr_mem_block->size); - return result; -} - -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_Free(Dqn_MemArena *arena DQN_DEBUG_ARGS)) -{ -#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) - (void)file; (void)file_len; (void)func; (void)func_len; (void)line; -#endif - for (Dqn_MemBlock *mem_block = arena->top_mem_block; mem_block;) - { - Dqn_MemBlock *block_to_free = mem_block; - mem_block = block_to_free->prev; - Dqn_MemArena__FreeBlock(arena, block_to_free); - } - - auto my_calloc = arena->my_calloc; - auto my_free = arena->my_free; - auto highest_used_mark = arena->highest_used_mark; - *arena = {}; - arena->highest_used_mark = highest_used_mark; - arena->my_calloc = my_calloc; - arena->my_free = my_free; -} - -DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS)) -{ -#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) - (void)file; (void)file_len; (void)func; (void)func_len; (void)line; -#endif - Dqn_MemArena__LazyInit(arena); - Dqn_MemSize remaining_space = arena->top_mem_block->size - arena->top_mem_block->used; - if (remaining_space >= size) return true; - - Dqn_MemBlock *new_block = Dqn_MemArena__AllocateBlock(arena, size); - if (!new_block) return false; - Dqn_MemArena__AttachBlock(arena, new_block); - return true; -} - -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_ReserveFrom(Dqn_MemArena *arena, void *memory, Dqn_usize size DQN_DEBUG_ARGS)) -{ -#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) - (void)file; (void)file_len; (void)func; (void)func_len; (void)line; -#endif - DQN_ASSERT_MSG(size >= sizeof(*arena->curr_mem_block), - "(%zu >= %zu) There needs to be enough space to encode the Dqn_MemBlock struct into the memory buffer", size, sizeof(*arena->curr_mem_block)); - Dqn_MemArena__LazyInit(arena); - auto *mem_block = static_cast(memory); - *mem_block = {}; - mem_block->memory = static_cast(memory) + sizeof(*mem_block); - mem_block->size = size - sizeof(*mem_block); - mem_block->allocated_by_user_or_fixed_mem = true; - Dqn_MemArena__AttachBlock(arena, mem_block); -} - -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_ClearUsed(Dqn_MemArena *arena DQN_DEBUG_ARGS)) -{ -#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) - (void)file; (void)file_len; (void)func; (void)func_len; (void)line; -#endif - for (Dqn_MemBlock *mem_block = arena->top_mem_block; mem_block; mem_block = mem_block->prev) - mem_block->used = 0; - arena->curr_mem_block = &arena->fixed_mem_block; -} - -DQN_HEADER_COPY_PROTOTYPE(Dqn_MemArenaScopedRegion, Dqn_MemArena_MakeScopedRegion(Dqn_MemArena *arena)) -{ - return Dqn_MemArenaScopedRegion(arena); -} - -Dqn_MemArenaScopedRegion::Dqn_MemArenaScopedRegion(Dqn_MemArena *arena) -{ - this->arena = arena; - this->curr_mem_block = arena->curr_mem_block; - this->curr_mem_block_used = (arena->curr_mem_block) ? arena->curr_mem_block->used : 0; - this->top_mem_block = arena->top_mem_block; -} - -Dqn_MemArenaScopedRegion::~Dqn_MemArenaScopedRegion() -{ - while (this->top_mem_block != this->arena->top_mem_block) - { - Dqn_MemBlock *block_to_free = this->arena->top_mem_block; - if (this->arena->curr_mem_block == block_to_free) - this->arena->curr_mem_block = block_to_free->prev; - this->arena->top_mem_block = block_to_free->prev; - Dqn_MemArena__FreeBlock(this->arena, block_to_free); - } - - for (Dqn_MemBlock *mem_block = this->arena->top_mem_block; mem_block != this->curr_mem_block; mem_block = mem_block->prev) - mem_block->used = 0; - - this->arena->curr_mem_block->used = this->curr_mem_block_used; -} - +void *Dqn_MemArena_Alloc(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS); +Dqn_b32 Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS); // @ ------------------------------------------------------------------------------------------------- // @ // @ NOTE: Dqn_Allocator @@ -1649,6 +1444,163 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_Allocator_Free(Dqn_Allocator *allocator, voi } } +// @ ------------------------------------------------------------------------------------------------- +// @ +// @ NOTE: Dqn_MemArena +// @ +// @ ------------------------------------------------------------------------------------------------- +DQN_FILE_SCOPE Dqn_MemBlock *Dqn_MemArena__AllocateBlock(Dqn_MemArena *arena, Dqn_usize requested_size) +{ + Dqn_usize mem_block_size = DQN_MAX(arena->min_block_size, requested_size); + Dqn_usize const allocate_size = sizeof(*arena->curr_mem_block) + mem_block_size; + Dqn_MemBlock *result = DQN_CAST(Dqn_MemBlock *) Dqn_Allocator_Allocate(&arena->allocator, allocate_size); + if (!result) return result; + + *result = {}; + result->size = mem_block_size; + result->memory = DQN_CAST(Dqn_u8 *)result + sizeof(*result); + arena->total_allocated_mem_blocks++; + return result; +} + +DQN_FILE_SCOPE void Dqn_MemArena__FreeBlock(Dqn_MemArena *arena, Dqn_MemBlock *block) +{ + if (!block) + return; + + if (block->next) + block->next->prev = block->prev; + + if (block->prev) + block->prev->next = block->next; + + Dqn_Allocator_Free(&arena->allocator, block); +} + +DQN_FILE_SCOPE void Dqn_MemArena__AttachBlock(Dqn_MemArena *arena, Dqn_MemBlock *new_block) +{ + if (arena->top_mem_block) + { + DQN_ASSERT(arena->top_mem_block->next == nullptr); + arena->top_mem_block->next = new_block; + new_block->prev = arena->top_mem_block; + arena->top_mem_block = new_block; + } + else + { + arena->top_mem_block = new_block; + arena->curr_mem_block = new_block; + } +} + +DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemArena_Alloc(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS)) +{ +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) + (void)file; (void)file_len; (void)func; (void)func_len; (void)line; +#endif + Dqn_b32 need_new_mem_block = true; + for (Dqn_MemBlock *mem_block = arena->curr_mem_block; mem_block; mem_block = mem_block->next) + { + Dqn_b32 can_fit_in_block = (mem_block->used + size) <= mem_block->size; + if (can_fit_in_block) + { + arena->curr_mem_block = mem_block; + need_new_mem_block = false; + break; + } + } + + if (need_new_mem_block) + { + Dqn_MemBlock *new_block = Dqn_MemArena__AllocateBlock(arena, size); + if (!new_block) return nullptr; + Dqn_MemArena__AttachBlock(arena, new_block); + arena->curr_mem_block = arena->top_mem_block; + } + + void *result = static_cast(arena->curr_mem_block->memory) + arena->curr_mem_block->used; + arena->curr_mem_block->used += size; + DQN_ASSERT(arena->curr_mem_block->used <= arena->curr_mem_block->size); + return result; +} + +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_Free(Dqn_MemArena *arena DQN_DEBUG_ARGS)) +{ +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) + (void)file; (void)file_len; (void)func; (void)func_len; (void)line; +#endif + for (Dqn_MemBlock *mem_block = arena->top_mem_block; mem_block;) + { + Dqn_MemBlock *block_to_free = mem_block; + mem_block = block_to_free->prev; + Dqn_MemArena__FreeBlock(arena, block_to_free); + } + + auto allocator = arena->allocator; + auto highest_used_mark = arena->highest_used_mark; + *arena = {}; + arena->highest_used_mark = highest_used_mark; + arena->allocator = allocator; +} + +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS)) +{ +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) + (void)file; (void)file_len; (void)func; (void)func_len; (void)line; +#endif + Dqn_usize remaining_space = arena->top_mem_block->size - arena->top_mem_block->used; + if (remaining_space >= size) return true; + + Dqn_MemBlock *new_block = Dqn_MemArena__AllocateBlock(arena, size); + if (!new_block) return false; + Dqn_MemArena__AttachBlock(arena, new_block); + return true; +} + +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_InitMemory(Dqn_MemArena *arena, void *memory, Dqn_usize size DQN_DEBUG_ARGS)) +{ +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) + (void)file; (void)file_len; (void)func; (void)func_len; (void)line; +#endif + DQN_ASSERT_MSG(size >= sizeof(*arena->curr_mem_block), "(%zu >= %zu) There needs to be enough space to encode the Dqn_MemBlock struct into the memory buffer", size, sizeof(*arena->curr_mem_block)); + *arena = {}; + arena->allocator = Dqn_Allocator_NullAllocator(); + auto *mem_block = DQN_CAST(Dqn_MemBlock *)memory; + *mem_block = {}; + mem_block->memory = DQN_CAST(Dqn_u8 *)memory + sizeof(*mem_block); + mem_block->size = size - sizeof(*mem_block); + Dqn_MemArena__AttachBlock(arena, mem_block); +} + +DQN_HEADER_COPY_PROTOTYPE(Dqn_MemArenaScopedRegion, Dqn_MemArena_MakeScopedRegion(Dqn_MemArena *arena)) +{ + return Dqn_MemArenaScopedRegion(arena); +} + +Dqn_MemArenaScopedRegion::Dqn_MemArenaScopedRegion(Dqn_MemArena *arena) +{ + this->arena = arena; + this->curr_mem_block = arena->curr_mem_block; + this->curr_mem_block_used = (arena->curr_mem_block) ? arena->curr_mem_block->used : 0; + this->top_mem_block = arena->top_mem_block; +} + +Dqn_MemArenaScopedRegion::~Dqn_MemArenaScopedRegion() +{ + while (this->top_mem_block != this->arena->top_mem_block) + { + Dqn_MemBlock *block_to_free = this->arena->top_mem_block; + if (this->arena->curr_mem_block == block_to_free) + this->arena->curr_mem_block = block_to_free->prev; + this->arena->top_mem_block = block_to_free->prev; + Dqn_MemArena__FreeBlock(this->arena, block_to_free); + } + + for (Dqn_MemBlock *mem_block = this->arena->top_mem_block; mem_block != this->curr_mem_block; mem_block = mem_block->prev) + mem_block->used = 0; + + this->arena->curr_mem_block->used = this->curr_mem_block_used; +} // @ ------------------------------------------------------------------------------------------------- // @ diff --git a/Code/DqnHeader.h b/Code/DqnHeader.h index 0346571..c3a885b 100644 --- a/Code/DqnHeader.h +++ b/Code/DqnHeader.h @@ -157,6 +157,7 @@ int main(int argc, char *argv[]) } Dqn_MemArena arena = {}; + DQN_MEM_ARENA_RESERVE(&arena, DQN_MEGABYTES(16)); for (isize arg_index = 1; arg_index < argc; ++arg_index) { char const *file = argv[arg_index]; diff --git a/Code/DqnHeader_Generated.h b/Code/DqnHeader_Generated.h index 4f64f64..e69de29 100644 --- a/Code/DqnHeader_Generated.h +++ b/Code/DqnHeader_Generated.h @@ -1,607 +0,0 @@ -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Typedefs, Macros, Utils -// -// ------------------------------------------------------------------------------------------------- -constexpr Dqn_usize Dqn_ArrayCount(T const (&)[N]); -constexpr Dqn_isize Dqn_ArrayCountI(T const (&)[N]); -constexpr Dqn_usize Dqn_CharCount(char const (&)[N]); -constexpr Dqn_isize Dqn_CharCountI(char const (&)[N]); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Logging -// -// ------------------------------------------------------------------------------------------------- -constexpr inline char const * Dqn_LogTypeTag(Dqn_LogType type); -// NOTE: Set the callback to get called whenever a log message has been printed -#define DQN_LOG_CALLBACK(name) void name(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *log_str) -typedef DQN_LOG_CALLBACK(Dqn_LogCallback); -Dqn_LogCallback *Dqn_log_callback; - -#define DQN_LOG_E(fmt, ...) Dqn_Log(Dqn_LogType::Error, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) -#define DQN_LOG_D(fmt, ...) Dqn_Log(Dqn_LogType::Debug, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) -#define DQN_LOG_W(fmt, ...) Dqn_Log(Dqn_LogType::Warning, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) -#define DQN_LOG_I(fmt, ...) Dqn_Log(Dqn_LogType::Info, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) -#define DQN_LOG_M(fmt, ...) Dqn_Log(Dqn_LogType::Info, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) -#define DQN_LOG(log_type, fmt, ...) Dqn_Log(log_type, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) - -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Math -// -// ------------------------------------------------------------------------------------------------- -union Dqn_V2I -{ - struct { Dqn_i32 x, y; }; - struct { Dqn_i32 w, h; }; - struct { Dqn_i32 min, max; }; - Dqn_i32 e[2]; - - constexpr Dqn_V2I() = default; - constexpr Dqn_V2I(Dqn_f32 x_, Dqn_f32 y_): x((Dqn_i32)x_), y((Dqn_i32)y_) {} - constexpr Dqn_V2I(Dqn_i32 x_, Dqn_i32 y_): x(x_), y(y_) {} - constexpr Dqn_V2I(Dqn_i32 xy): x(xy), y(xy) {} - - constexpr bool operator!=(Dqn_V2I other) const { return !(*this == other); } - constexpr bool operator==(Dqn_V2I other) const { return (x == other.x) && (y == other.y); } - constexpr bool operator>=(Dqn_V2I other) const { return (x >= other.x) && (y >= other.y); } - constexpr bool operator<=(Dqn_V2I other) const { return (x <= other.x) && (y <= other.y); } - constexpr bool operator< (Dqn_V2I other) const { return (x < other.x) && (y < other.y); } - constexpr bool operator> (Dqn_V2I other) const { return (x > other.x) && (y > other.y); } - constexpr Dqn_V2I operator- (Dqn_V2I other) const { Dqn_V2I result(x - other.x, y - other.y); return result; } - constexpr Dqn_V2I operator+ (Dqn_V2I other) const { Dqn_V2I result(x + other.x, y + other.y); return result; } - constexpr Dqn_V2I operator* (Dqn_V2I other) const { Dqn_V2I result(x * other.x, y * other.y); return result; } - constexpr Dqn_V2I operator* (Dqn_f32 other) const { Dqn_V2I result(x * other, y * other); return result; } - constexpr Dqn_V2I operator* (Dqn_i32 other) const { Dqn_V2I result(x * other, y * other); return result; } - constexpr Dqn_V2I operator/ (Dqn_V2I other) const { Dqn_V2I result(x / other.x, y / other.y); return result; } - constexpr Dqn_V2I operator/ (Dqn_f32 other) const { Dqn_V2I result(x / other, y / other); return result; } - constexpr Dqn_V2I operator/ (Dqn_i32 other) const { Dqn_V2I result(x / other, y / other); return result; } - constexpr Dqn_V2I &operator*=(Dqn_V2I other) { *this = *this * other; return *this; } - constexpr Dqn_V2I &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } - constexpr Dqn_V2I &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } - constexpr Dqn_V2I &operator-=(Dqn_V2I other) { *this = *this - other; return *this; } - constexpr Dqn_V2I &operator+=(Dqn_V2I other) { *this = *this + other; return *this; } -}; - -union Dqn_V2 -{ - struct { Dqn_f32 x, y; }; - struct { Dqn_f32 w, h; }; - struct { Dqn_f32 min, max; }; - Dqn_f32 e[2]; - - constexpr Dqn_V2() = default; - constexpr Dqn_V2(Dqn_f32 a) : x(a), y(a) {} - constexpr Dqn_V2(Dqn_i32 a) : x((Dqn_f32)a), y((Dqn_f32)a) {} - constexpr Dqn_V2(Dqn_f32 x_, Dqn_f32 y_): x(x_), y(y_) {} - constexpr Dqn_V2(Dqn_i32 x_, Dqn_i32 y_): x((Dqn_f32)x_), y((Dqn_f32)y_) {} - constexpr Dqn_V2(Dqn_V2I a) : x((Dqn_f32)a.x), y((Dqn_f32)a.y) {} - - constexpr bool operator!=(Dqn_V2 other) const { return !(*this == other); } - constexpr bool operator==(Dqn_V2 other) const { return (x == other.x) && (y == other.y); } - constexpr bool operator>=(Dqn_V2 other) const { return (x >= other.x) && (y >= other.y); } - constexpr bool operator<=(Dqn_V2 other) const { return (x <= other.x) && (y <= other.y); } - constexpr bool operator< (Dqn_V2 other) const { return (x < other.x) && (y < other.y); } - constexpr bool operator> (Dqn_V2 other) const { return (x > other.x) && (y > other.y); } - constexpr Dqn_V2 operator- (Dqn_V2 other) const { Dqn_V2 result(x - other.x, y - other.y); return result; } - constexpr Dqn_V2 operator+ (Dqn_V2 other) const { Dqn_V2 result(x + other.x, y + other.y); return result; } - constexpr Dqn_V2 operator* (Dqn_V2 other) const { Dqn_V2 result(x * other.x, y * other.y); return result; } - constexpr Dqn_V2 operator* (Dqn_f32 other) const { Dqn_V2 result(x * other, y * other); return result; } - constexpr Dqn_V2 operator* (Dqn_i32 other) const { Dqn_V2 result(x * other, y * other); return result; } - constexpr Dqn_V2 operator/ (Dqn_V2 other) const { Dqn_V2 result(x / other.x, y / other.y); return result; } - constexpr Dqn_V2 operator/ (Dqn_f32 other) const { Dqn_V2 result(x / other, y / other); return result; } - constexpr Dqn_V2 operator/ (Dqn_i32 other) const { Dqn_V2 result(x / other, y / other); return result; } - constexpr Dqn_V2 &operator*=(Dqn_V2 other) { *this = *this * other; return *this; } - constexpr Dqn_V2 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } - constexpr Dqn_V2 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } - constexpr Dqn_V2 &operator/=(Dqn_V2 other) { *this = *this / other; return *this; } - constexpr Dqn_V2 &operator/=(Dqn_f32 other) { *this = *this / other; return *this; } - constexpr Dqn_V2 &operator/=(Dqn_i32 other) { *this = *this / other; return *this; } - constexpr Dqn_V2 &operator-=(Dqn_V2 other) { *this = *this - other; return *this; } - constexpr Dqn_V2 &operator+=(Dqn_V2 other) { *this = *this + other; return *this; } -}; - -union Dqn_V3 -{ - struct { Dqn_f32 x, y, z; }; - struct { Dqn_f32 r, g, b; }; - Dqn_V2 xy; - Dqn_f32 e[3]; - - constexpr Dqn_V3() = default; - constexpr Dqn_V3(Dqn_f32 a) : x(a), y(a), z(a) {} - constexpr Dqn_V3(Dqn_i32 a) : x((Dqn_f32)a), y((Dqn_f32)a), z((Dqn_f32)a) {} - constexpr Dqn_V3(Dqn_f32 x_, Dqn_f32 y_, Dqn_f32 z_): x(x_), y(y_), z(z_) {} - constexpr Dqn_V3(Dqn_i32 x_, Dqn_i32 y_, Dqn_f32 z_): x((Dqn_f32)x_), y((Dqn_f32)y_), z((Dqn_f32)z_) {} - constexpr Dqn_V3(Dqn_V2 xy, Dqn_f32 z_) : x(xy.x), y(xy.y), z(z_) {} - - constexpr bool operator!= (Dqn_V3 other) const { return !(*this == other); } - constexpr bool operator== (Dqn_V3 other) const { return (x == other.x) && (y == other.y) && (z == other.z); } - constexpr bool operator>= (Dqn_V3 other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z); } - constexpr bool operator<= (Dqn_V3 other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z); } - constexpr bool operator< (Dqn_V3 other) const { return (x < other.x) && (y < other.y) && (z < other.z); } - constexpr bool operator> (Dqn_V3 other) const { return (x > other.x) && (y > other.y) && (z > other.z); } - constexpr Dqn_V3 operator- (Dqn_V3 other) const { Dqn_V3 result(x - other.x, y - other.y, z - other.z); return result; } - constexpr Dqn_V3 operator+ (Dqn_V3 other) const { Dqn_V3 result(x + other.x, y + other.y, z + other.z); return result; } - constexpr Dqn_V3 operator* (Dqn_V3 other) const { Dqn_V3 result(x * other.x, y * other.y, z * other.z); return result; } - constexpr Dqn_V3 operator* (Dqn_f32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; } - constexpr Dqn_V3 operator* (Dqn_i32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; } - constexpr Dqn_V3 operator/ (Dqn_V3 other) const { Dqn_V3 result(x / other.x, y / other.y, z / other.z); return result; } - constexpr Dqn_V3 operator/ (Dqn_f32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; } - constexpr Dqn_V3 operator/ (Dqn_i32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; } - constexpr Dqn_V3 &operator*=(Dqn_V3 other) { *this = *this * other; return *this; } - constexpr Dqn_V3 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } - constexpr Dqn_V3 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } - constexpr Dqn_V3 &operator/=(Dqn_V3 other) { *this = *this / other; return *this; } - constexpr Dqn_V3 &operator/=(Dqn_f32 other) { *this = *this / other; return *this; } - constexpr Dqn_V3 &operator/=(Dqn_i32 other) { *this = *this / other; return *this; } - constexpr Dqn_V3 &operator-=(Dqn_V3 other) { *this = *this - other; return *this; } - constexpr Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; } -}; - -union Dqn_V4 -{ - struct { Dqn_f32 x, y, z, w; }; - struct { Dqn_f32 r, g, b, a; }; - Dqn_V3 rgb; - Dqn_f32 e[4]; - - constexpr Dqn_V4() = default; - constexpr Dqn_V4(Dqn_f32 xyzw) : x(xyzw), y(xyzw), z(xyzw), w(xyzw) {} - constexpr Dqn_V4(Dqn_f32 x_, Dqn_f32 y_, Dqn_f32 z_, Dqn_f32 w_): x(x_), y(y_), z(z_), w(w_) {} - constexpr Dqn_V4(Dqn_i32 x_, Dqn_i32 y_, Dqn_i32 z_, Dqn_i32 w_): x((Dqn_f32)x_), y((Dqn_f32)y_), z((Dqn_f32)z_), w((Dqn_f32)w_) {} - constexpr Dqn_V4(Dqn_V3 xyz, Dqn_f32 w_) : x(xyz.x), y(xyz.y), z(xyz.z), w(w_) {} - - constexpr bool operator!=(Dqn_V4 other) const { return !(*this == other); } - constexpr bool operator==(Dqn_V4 other) const { return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w); } - constexpr bool operator>=(Dqn_V4 other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z) && (w >= other.w); } - constexpr bool operator<=(Dqn_V4 other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z) && (w <= other.w); } - constexpr bool operator< (Dqn_V4 other) const { return (x < other.x) && (y < other.y) && (z < other.z) && (w < other.w); } - constexpr bool operator> (Dqn_V4 other) const { return (x > other.x) && (y > other.y) && (z > other.z) && (w > other.w); } - constexpr Dqn_V4 operator- (Dqn_V4 other) const { Dqn_V4 result(x - other.x, y - other.y, z - other.z, w - other.w); return result; } - constexpr Dqn_V4 operator+ (Dqn_V4 other) const { Dqn_V4 result(x + other.x, y + other.y, z + other.z, w + other.w); return result; } - constexpr Dqn_V4 operator* (Dqn_V4 other) const { Dqn_V4 result(x * other.x, y * other.y, z * other.z, w * other.w); return result; } - constexpr Dqn_V4 operator* (Dqn_f32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; } - constexpr Dqn_V4 operator* (Dqn_i32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; } - constexpr Dqn_V4 operator/ (Dqn_f32 other) const { Dqn_V4 result(x / other, y / other, z / other, w / other); return result; } - constexpr Dqn_V4 &operator*=(Dqn_V4 other) { *this = *this * other; return *this; } - constexpr Dqn_V4 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } - constexpr Dqn_V4 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } - constexpr Dqn_V4 &operator-=(Dqn_V4 other) { *this = *this - other; return *this; } - constexpr Dqn_V4 &operator+=(Dqn_V4 other) { *this = *this + other; return *this; } -}; - -struct Dqn_Rect -{ - Dqn_V2 min, max; - Dqn_Rect() = default; - Dqn_Rect(Dqn_V2 min, Dqn_V2 max) : min(min), max(max) {} - Dqn_Rect(Dqn_V2I min, Dqn_V2I max) : min(min), max(max) {} -}; - -struct Dqn_RectI32 -{ - Dqn_V2I min, max; - Dqn_RectI32() = default; - Dqn_RectI32(Dqn_V2I min, Dqn_V2I max) : min(min), max(max) {} -}; - -union Dqn_Mat4 -{ - Dqn_f32 e[16]; - Dqn_V4 row[4]; - Dqn_f32 row_major[4][4]; - Dqn_f32 operator[](Dqn_usize i) const { return e[i]; } -}; - -template int Dqn_MemCmpType(T const *ptr1, T const *ptr2); -template T * Dqn_MemZero(T *src); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_MemArena -// -// ------------------------------------------------------------------------------------------------- -using Dqn_MemSize = Dqn_usize; -struct Dqn_MemBlock -{ - // NOTE: Read only state - Dqn_b32 allocated_by_user_or_fixed_mem; - void *memory; - Dqn_MemSize size; - Dqn_MemSize used; - Dqn_MemBlock *prev; - Dqn_MemBlock *next; -}; - -enum Dqn_MemArenaFlag -{ - Dqn_MemArenaFlag_NoCRTAllocation = (1 << 0), // If my_calloc/my_free aren't null, it defaults to calloc and free, setting this flag disables that -}; - -struct Dqn_MemArena -{ - // NOTE: Configuration (fill once) - void *(*my_calloc)(Dqn_usize bytes); // If nullptr, use CRT calloc unless disabled in flags - void (*my_free) (void *ptr, Dqn_usize bytes_to_free); // If nullptr, use CRT free unless disabled in flags - Dqn_u32 flags; - - // NOTE: Read Only - Dqn_u8 fixed_mem[DQN_KILOBYTES(16)]; - Dqn_MemBlock fixed_mem_block; - Dqn_MemBlock *curr_mem_block; - Dqn_MemBlock *top_mem_block; - Dqn_MemSize highest_used_mark; - int total_allocated_mem_blocks; -}; - -struct Dqn_MemArenaScopedRegion -{ - Dqn_MemArenaScopedRegion(Dqn_MemArena *arena); - ~Dqn_MemArenaScopedRegion(); - Dqn_MemArena *arena; - Dqn_MemBlock *curr_mem_block; - Dqn_usize curr_mem_block_used; - Dqn_MemBlock *top_mem_block; -}; - -#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) - #define DQN_DEBUG_ARGS , char const *file, Dqn_isize file_len, char const *func, Dqn_isize func_len, Dqn_isize line - #define DQN_DEBUG_PARAMS , DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__ -#else - #define DQN_DEBUG_ARGS - #define DQN_DEBUG_PARAMS -#endif - -#define DQN_MEM_ARENA_ALLOC(arena, size) Dqn_MemArena_Alloc(arena, size DQN_DEBUG_PARAMS) -#define DQN_MEM_ARENA_ALLOC_ARRAY(arena, T, num) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) * num DQN_DEBUG_PARAMS) -#define DQN_MEM_ARENA_ALLOC_STRUCT(arena, T) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) DQN_DEBUG_PARAMS) -#define DQN_MEM_ARENA_RESERVE(arena, size) Dqn_MemArena_Reserve(arena, size DQN_DEBUG_PARAMS) -#define DQN_MEM_ARENA_RESERVE_FROM(arena, src, size) Dqn_MemArena_ReserveFrom(arena, src, size DQN_DEBUG_PARAMS) -#define DQN_MEM_ARENA_CLEAR_USED(arena) Dqn_MemArena_ClearUsed(arena DQN_DEBUG_PARAMS) -#define DQN_MEM_ARENA_FREE(arena) Dqn_MemArena_Free - -// ------------------------------------------------------------------------------------------------- -// -// NOTE: String Builder -// -// ------------------------------------------------------------------------------------------------- -struct Dqn_StringBuilderBuffer -{ - char *mem; - Dqn_MemSize size; - Dqn_MemSize used; - Dqn_StringBuilderBuffer *next; -}; - -Dqn_usize constexpr DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE = DQN_KILOBYTES(4); -template -struct Dqn_StringBuilder -{ - void *(*my_malloc)(size_t bytes) = malloc; // Set to nullptr to disable heap allocation - void (*my_free) (void *ptr) = free; // Set to nullptr to disable heap allocation - - char fixed_mem[N]; - Dqn_MemSize fixed_mem_used; - Dqn_StringBuilderBuffer *next_mem_buf; - Dqn_StringBuilderBuffer *last_mem_buf; - Dqn_isize string_len; -}; - -// The necessary length to build the string, it returns the length including the null-terminator -template Dqn_isize Dqn_StringBuilder_BuildLen(Dqn_StringBuilder const *builder); -template void Dqn_StringBuilder_BuildInBuffer(Dqn_StringBuilder const *builder, char *dest, Dqn_usize dest_size); -template char * Dqn_StringBuilder_BuildFromMalloc(Dqn_StringBuilder *builder, Dqn_isize *len = nullptr); -template char * Dqn_StringBuilder_BuildFromArena(Dqn_StringBuilder *builder, Dqn_MemArena *arena, Dqn_isize *len = nullptr); -template void Dqn_StringBuilder_VFmtAppend(Dqn_StringBuilder *builder, char const *fmt, va_list va); -template void Dqn_StringBuilder_FmtAppend(Dqn_StringBuilder *builder, char const *fmt, ...); -template void Dqn_StringBuilder_Append(Dqn_StringBuilder *builder, char const *str, Dqn_isize len = -1); -template void Dqn_StringBuilder_AppendChar(Dqn_StringBuilder *builder, char ch); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_Slices -// -// ------------------------------------------------------------------------------------------------- -template inline Dqn_Slice Dqn_Slice_CopyNullTerminated(Dqn_MemArena *arena, T const *src, Dqn_isize len); -template inline Dqn_Slice Dqn_Slice_CopyNullTerminated(Dqn_MemArena *arena, Dqn_Slice const src); -template inline Dqn_Slice Dqn_Slice_Copy(Dqn_MemArena *arena, T const *src, Dqn_isize len); -template inline Dqn_Slice Dqn_Slice_Copy(Dqn_MemArena *arena, Dqn_Slice const src); -template inline bool Dqn_Slice_Equals(Dqn_Slice const a, Dqn_Slice const b); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_Asprintf (Allocate Sprintf) -// -// ------------------------------------------------------------------------------------------------- -template Dqn_Slice Dqn_AsprintfSlice(T *arena, char const *fmt, va_list va); -template Dqn_Slice Dqn_AsprintfSlice(T *arena, char const *fmt, ...); -template char * Dqn_Asprintf(T *arena, int *len, char const *fmt, ...); -template char * Dqn_Asprintf(T *arena, char const *fmt, ...); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_FixedArray -// -// ------------------------------------------------------------------------------------------------- -#define DQN_FIXED_ARRAY_TEMPLATE template -#define DQN_FIXED_ARRAY_TEMPLATE_DECL Dqn_FixedArray -DQN_FIXED_ARRAY_TEMPLATE struct Dqn_FixedArray -{ - T data[MAX_]; - Dqn_isize len; - Dqn_isize Max() const { return MAX_; } - - T &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - T *begin () { return data; } - T *end () { return data + len; } - T *operator+ (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } - - T const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - T const *begin () const { return data; } - T const *end () const { return data + len; } - T const *operator+ (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } -}; - -DQN_FIXED_ARRAY_TEMPLATE_DECL Dqn_FixedArray_Init(T const *item, int num); -T * Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *items, Dqn_isize num); -T * Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const item); -T * Dqn_FixedArray_Make(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num); -void Dqn_FixedArray_Clear(DQN_FIXED_ARRAY_TEMPLATE_DECL *a); -void Dqn_FixedArray_EraseStable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize index); -void Dqn_FixedArray_EraseUnstable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize index); -void Dqn_FixedArray_Pop(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num); -T * Dqn_FixedArray_Peek(DQN_FIXED_ARRAY_TEMPLATE_DECL *a); -Dqn_isize Dqn_FixedArray_GetIndex(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *entry); -T * Dqn_FixedArray_Find(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, EqualityProc IsEqual); -T * Dqn_FixedArray_Find(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T *entry); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_FixedStack -// -// ------------------------------------------------------------------------------------------------- -template using Dqn_FixedStack = DQN_FIXED_ARRAY_TEMPLATE_DECL; -template T Dqn_FixedStack_Pop (Dqn_FixedStack *array) { T result = *Dqn_FixedArray_Peek(array); Dqn_FixedArray_Pop(array, 1); return result; } -template T *Dqn_FixedStack_Peek (Dqn_FixedStack *array) { return Dqn_FixedArray_Peek(array); } -template T *Dqn_FixedStack_Push (Dqn_FixedStack *array, T item) { return Dqn_FixedArray_Add(array, item); } -template void Dqn_FixedStack_Clear(Dqn_FixedStack *array) { Dqn_FixedArray_Clear(array); } - -enum struct Dqn_Allocator_Type -{ - Heap, // Malloc, realloc, free - XHeap, // Malloc realloc, free, crash on failure - Arena, - NullAllocator, -}; - -struct Dqn_Allocator -{ - Dqn_Allocator_Type type; - void *data; -}; - -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_Array -// -// ------------------------------------------------------------------------------------------------- -// TODO(doyle): Make this either initialised from memory or dynamically allocating -template struct Dqn_Array -{ - Dqn_Allocator allocator; - T *data; - Dqn_isize len; - Dqn_isize max; - - T const operator[](Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - T operator[](Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - T const *begin () const { return data; } - T const *end () const { return data + len; } - T *begin () { return data; } - T *end () { return data + len; } - T const *operator+(Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } - T *operator+(Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } -}; - -template Dqn_Array Dqn_Array_InitMemory(T *memory, Dqn_isize max, Dqn_isize len = 0); -template bool Dqn_Array_Reserve(Dqn_Array *a, Dqn_isize size); -template void Dqn_Array_Free(Dqn_Array *a); -template T * Dqn_Array_Add(Dqn_Array *a, T const *items, Dqn_isize num); -template T * Dqn_Array_Add(Dqn_Array *a, T const item); -template T * Dqn_Array_Make(Dqn_Array *a, Dqn_isize num); -template void Dqn_Array_Clear(Dqn_Array *a, bool zero_mem = false); -template void Dqn_Array_EraseStable(Dqn_Array *a, Dqn_isize index); -template void Dqn_Array_EraseUnstable(Dqn_Array *a, Dqn_isize index); -template void Dqn_Array_Pop(Dqn_Array *a, Dqn_isize num); -template T * Dqn_Array_Peek(Dqn_Array *a); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_FixedString -// -// ------------------------------------------------------------------------------------------------- -template -struct Dqn_FixedString -{ - union { char data[MAX_]; char str[MAX_]; char buf[MAX_]; }; - Dqn_isize len; - Dqn_isize Max() const { return MAX_; } - - Dqn_FixedString() { data[0] = 0; len = 0; } - Dqn_FixedString(char const *fmt, ...) - { - *this = {}; - va_list va; - va_start(va, fmt); - Dqn_FixedString_AppendVFmt(this, fmt, va); - va_end(va); - } - - char const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - char &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - char const *begin () const { return data; } - char const *end () const { return data + len; } - char *begin () { return data; } - char *end () { return data + len; } -}; - -template void Dqn_FixedString_Clear(Dqn_FixedString *str); -template void Dqn_FixedString_AppendVFmt(Dqn_FixedString *str, char const *fmt, va_list va); -template void Dqn_FixedString_AppendFmt(Dqn_FixedString *str, char const *fmt, ...); -template void Dqn_FixedString_Append(Dqn_FixedString *str, char const *src, Dqn_isize len = -1); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_Dqn_U64Str -// -// ------------------------------------------------------------------------------------------------- -struct Dqn_U64Str -{ - // Points to the start of the str in the buffer, not necessarily buf since - // we write into the buffer in reverse - char *start; - char buf[27]; // NOTE(doyle): 27 is the maximum size of Dqn_u64 including commas - int len; -}; - -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Helpers -// -// ------------------------------------------------------------------------------------------------- -int Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes); -void * Dqn_MemCopy(void *dest, void const *src, size_t num_bytes); -void * Dqn_MemMove(void *dest, void const *src, size_t num_bytes); -void * Dqn_MemSet(void *src, char ch, Dqn_usize num_bytes); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Logging -// -// ------------------------------------------------------------------------------------------------- -void Dqn_LogV(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, va_list va); -void Dqn_Log(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, ...); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_MemArena -// -// ------------------------------------------------------------------------------------------------- -void * Dqn_MemArena_Alloc(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS); -void Dqn_MemArena_Free(Dqn_MemArena *arena DQN_DEBUG_ARGS); -Dqn_b32 Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS); -void Dqn_MemArena_ReserveFrom(Dqn_MemArena *arena, void *memory, Dqn_usize size DQN_DEBUG_ARGS); -void Dqn_MemArena_ClearUsed(Dqn_MemArena *arena DQN_DEBUG_ARGS); -Dqn_MemArenaScopedRegion Dqn_MemArena_MakeScopedRegion(Dqn_MemArena *arena); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_Allocator -// -// ------------------------------------------------------------------------------------------------- -Dqn_Allocator Dqn_Allocator_NullAllocator(); -Dqn_Allocator Dqn_Allocator_HeapAllocator(); -Dqn_Allocator Dqn_Allocator_XHeapAllocator(); -Dqn_Allocator Dqn_Allocator_ArenaAllocator(Dqn_MemArena *arena); -void * Dqn_Allocator_Allocate(Dqn_Allocator *allocator, Dqn_usize size); -void * Dqn_Allocator_Realloc(Dqn_Allocator *allocator, void *old_ptr, Dqn_isize old_size, Dqn_isize new_size); -void Dqn_Allocator_Free(Dqn_Allocator *allocator, void *ptr); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Vectors -// -// ------------------------------------------------------------------------------------------------- -Dqn_V2I Dqn_V2_ToV2I(Dqn_V2 a); -Dqn_V2 Dqn_V2_Max(Dqn_V2 a, Dqn_V2 b); -Dqn_V2 Dqn_V2_Abs(Dqn_V2 a); -Dqn_f32 Dqn_V2_Dot(Dqn_V2 a, Dqn_V2 b); -Dqn_f32 Dqn_V2_LengthSq(Dqn_V2 a, Dqn_V2 b); -Dqn_V2 Dqn_V2_Normalise(Dqn_V2 a); -Dqn_V2 Dqn_V2_Perpendicular(Dqn_V2 a); -Dqn_f32 Dqn_V4_Dot(Dqn_V4 const *a, Dqn_V4 const *b); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Rect -// -// ------------------------------------------------------------------------------------------------- -Dqn_Rect Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size); -Dqn_V2 Dqn_Rect_Center(Dqn_Rect rect); -Dqn_b32 Dqn_Rect_ContainsPoint(Dqn_Rect rect, Dqn_V2 p); -Dqn_b32 Dqn_Rect_ContainsRect(Dqn_Rect a, Dqn_Rect b); -Dqn_V2 Dqn_Rect_Size(Dqn_Rect rect); -Dqn_Rect Dqn_Rect_Move(Dqn_Rect src, Dqn_V2 move_amount); -Dqn_Rect Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b); -Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a); -Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Math Utils -// -// ------------------------------------------------------------------------------------------------- -Dqn_V2 Dqn_LerpV2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Dqn_Mat4 -// -// ------------------------------------------------------------------------------------------------- -Dqn_Mat4 Dqn_Mat4_Identity(); -Dqn_Mat4 Dqn_Mat4_Scale3f(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z); -Dqn_Mat4 Dqn_Mat4_ScaleV3(Dqn_V3 vec); -Dqn_Mat4 Dqn_Mat4_Translate3f(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z); -Dqn_Mat4 Dqn_Mat4_TranslateV3(Dqn_V3 vec); -Dqn_Mat4 operator*(Dqn_Mat4 const &a, Dqn_Mat4 const &b); -Dqn_V4 operator*(Dqn_Mat4 const &mat, Dqn_V4 const &vec); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Helper Functions -// -// ------------------------------------------------------------------------------------------------- -void Dqn_Bit_UnsetInplace(Dqn_u32 *flags, Dqn_u32 bitfield); -void Dqn_Bit_SetInplace(Dqn_u32 *flags, Dqn_u32 bitfield); -Dqn_b32 Dqn_Bit_IsSet(Dqn_u32 flags, Dqn_u32 bitfield); -Dqn_b32 Dqn_Bit_IsNotSet(Dqn_u32 flags, Dqn_u32 bitfield); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Safe Arithmetic -// -// ------------------------------------------------------------------------------------------------- -Dqn_i64 Dqn_Safe_AddI64(Dqn_i64 a, Dqn_i64 b); -Dqn_i64 Dqn_Safe_MulI64(Dqn_i64 a, Dqn_i64 b); -Dqn_u64 Dqn_Safe_AddU64(Dqn_u64 a, Dqn_u64 b); -Dqn_u64 Dqn_Safe_MulU64(Dqn_u64 a, Dqn_u64 b); -int Dqn_Safe_TruncateISizeToInt(Dqn_isize val); -Dqn_i32 Dqn_Safe_TruncateISizeToI32(Dqn_isize val); -Dqn_i8 Dqn_Safe_TruncateISizeToI8(Dqn_isize val); -Dqn_u32 Dqn_Safe_TruncateUSizeToU32(Dqn_u64 val); -int Dqn_Safe_TruncateUSizeToI32(Dqn_usize val); -int Dqn_Safe_TruncateUSizeToInt(Dqn_usize val); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: Char Helpers -// -// ------------------------------------------------------------------------------------------------- -Dqn_b32 Dqn_Char_IsAlpha(char ch); -Dqn_b32 Dqn_Char_IsDigit(char ch); -Dqn_b32 Dqn_Char_IsAlphaNum(char ch); -Dqn_b32 Dqn_Char_IsWhitespace(char ch); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: String Helpers -// -// ------------------------------------------------------------------------------------------------- -Dqn_b32 Dqn_Str_Equals(char const *a, char const *b, Dqn_isize a_len = -1, Dqn_isize b_len = -1); -char const * Dqn_Str_FindMulti(char const *buf, char const *find_list[], Dqn_isize const *find_string_lens, Dqn_isize find_len, Dqn_isize *match_index, Dqn_isize buf_len = -1); -char const * Dqn_Str_Find(char const *buf, char const *find, Dqn_isize buf_len = -1, Dqn_isize find_len = -1); -Dqn_b32 Dqn_Str_Match(char const *src, char const *find, int find_len); -char const * Dqn_Str_SkipToChar(char const *src, char ch); -char const * Dqn_Str_SkipToNextAlphaNum(char const *src); -char const * Dqn_Str_SkipToNextDigit(char const *src); -char const * Dqn_Str_SkipToNextChar(char const *src); -char const * Dqn_Str_SkipToNextWord(char const *src); -char const * Dqn_Str_SkipToNextWhitespace(char const *src); -char const * Dqn_Str_SkipWhitespace(char const *src); -char const * Dqn_Str_SkipToCharInPlace(char const **src, char ch); -char const * Dqn_Str_SkipToNextAlphaNumInPlace(char const **src); -char const * Dqn_Str_SkipToNextCharInPlace(char const **src); -char const * Dqn_Str_SkipToNextWhitespaceInPlace(char const **src); -char const * Dqn_Str_SkipToNextWordInPlace(char const **src); -char const * Dqn_Str_SkipWhitespaceInPlace(char const **src); -Dqn_u64 Dqn_Str_ToU64(char const *buf, int len = -1); -Dqn_i64 Dqn_Str_ToI64(char const *buf, int len = -1); -// ------------------------------------------------------------------------------------------------- -// -// NOTE: File -// -// ------------------------------------------------------------------------------------------------- -char * Dqn_File_ReadWithArena(Dqn_MemArena *arena, char const *file, Dqn_isize *file_size); diff --git a/Project/Msvc/DqnHeader.sln b/Project/Msvc/DqnHeader.sln new file mode 100644 index 0000000..be46136 --- /dev/null +++ b/Project/Msvc/DqnHeader.sln @@ -0,0 +1,33 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.168 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "DqnHeader", "..\..\Bin\DqnHeader.exe", "{6F5D8503-3434-4DD0-8253-1570BD19A135}" + ProjectSection(DebuggerProjectSystem) = preProject + PortSupplier = 00000000-0000-0000-0000-000000000000 + Executable = F:\Home\Code\dqn\Bin\DqnHeader.exe + RemoteMachine = THAI-XPS13 + StartingDirectory = F:\Home\Code\dqn\Bin + Arguments = ..\Code\Dqn.h + Environment = Default + LaunchingEngine = 00000000-0000-0000-0000-000000000000 + UseLegacyDebugEngines = No + LaunchSQLEngine = No + AttachLaunchAction = No + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6F5D8503-3434-4DD0-8253-1570BD19A135}.Release|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4C7A3762-6B3C-4C64-8C7A-DBF5A8956391} + EndGlobalSection +EndGlobal