Adding more core layer stuff. Can now boot.
This commit is contained in:
1 parent
16664c68b5
commit
5d6ca639fd
30 files changed
+1300
-28
No files matched your search
@@ -22,3 +22,11 @@ Struct members: lower_snake_case. Exemple: data, node, next.
|
|||||||
global/static variables: lower_snake_case prefixed. Exemple: g_my_global.
|
global/static variables: lower_snake_case prefixed. Exemple: g_my_global.
|
||||||
const variables: lower_snake_case prefixed. Exemple: k_my_const_var.
|
const variables: lower_snake_case prefixed. Exemple: k_my_const_var.
|
||||||
Defines and Macros: ALL_CAPS_SNAKE. Exemple: MY_MACRO
|
Defines and Macros: ALL_CAPS_SNAKE. Exemple: MY_MACRO
|
||||||
|
|
||||||
|
Modular Architecture & Include Rules:
|
||||||
|
- Juliet uses a single-pass unity build pattern.
|
||||||
|
- Layer aggregators `<layer>_inc.h` and `<layer>_inc.c` dictate header and source inclusion order.
|
||||||
|
- Top-level translation units (e.g. `appbin_main.c`) include the layer `_inc` files in dependency order (`core` -> `render` -> `ui`...).
|
||||||
|
- Sub-files within a module (e.g. `core.h`, `core_arena.c`, `render.c`) must NEVER directly `#include` other module headers, sibling headers, or configuration defines (`core_defines.h`).
|
||||||
|
- Never add `#include` directives to sub-files to satisfy standalone LSP/compiler diagnostics. Tooling (`new_project_gen.c` / `compile_commands.json`) must supply preceding includes dynamically based on the base file include order.
|
||||||
|
- Always explain root causes and confirm with the user before editing project architecture or files.
|
||||||
@@ -3,6 +3,9 @@ CompileFlags:
|
|||||||
- --driver-mode=cl
|
- --driver-mode=cl
|
||||||
- -Wno-unknown-pragmas
|
- -Wno-unknown-pragmas
|
||||||
- -Wno-unused-command-line-argument
|
- -Wno-unused-command-line-argument
|
||||||
|
- -Wno-unused-function
|
||||||
|
- -Wno-undefined-internal
|
||||||
|
- -Wno-initializer-overrides
|
||||||
- /IJuliet
|
- /IJuliet
|
||||||
Remove:
|
Remove:
|
||||||
- /Yu*
|
- /Yu*
|
||||||
@@ -17,8 +20,15 @@ CompileFlags:
|
|||||||
|
|
||||||
Diagnostics:
|
Diagnostics:
|
||||||
UnusedIncludes: None
|
UnusedIncludes: None
|
||||||
|
Suppress:
|
||||||
|
- unused-function
|
||||||
|
- undefined-internal
|
||||||
|
- initializer-overrides
|
||||||
|
|
||||||
InlayHints:
|
InlayHints:
|
||||||
Enabled: Yes
|
Enabled: true
|
||||||
ParameterNames: Yes
|
ParameterNames: true
|
||||||
DeducedTypes: Yes
|
DeducedTypes: true
|
||||||
|
Designators: true
|
||||||
|
BlockEnd: false
|
||||||
|
TypeNameLimit: 24
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
[submodule "External/Imgui"]
|
[submodule "External/Imgui"]
|
||||||
path = External/Imgui
|
path = External/Imgui
|
||||||
url = https://github.com/ocornut/imgui.git
|
url = https://github.com/ocornut/imgui.git
|
||||||
|
[submodule "Juliet/external/stb"]
|
||||||
|
path = Juliet/external/stb
|
||||||
|
url = https://github.com/nothings/stb.git
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Safe Casts
|
||||||
|
|
||||||
|
internal uint16 safe_cast_uint16(uint32 val)
|
||||||
|
{
|
||||||
|
AssertAlways(val <= max_uint16);
|
||||||
|
uint16 result = (uint16)val;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint32 safe_cast_uint32(uint64 val)
|
||||||
|
{
|
||||||
|
AssertAlways(val <= max_uint32);
|
||||||
|
uint32 result = (uint32)val;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int32 safe_cast_int32(int64 val)
|
||||||
|
{
|
||||||
|
AssertAlways(val <= max_int32);
|
||||||
|
int32 result = (int32)val;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Third party includes
|
||||||
|
|
||||||
|
#define STB_SPRINTF_IMPLEMENTATION
|
||||||
|
#define STB_SPRINTF_STATIC
|
||||||
|
#include "external/stb/stb_sprintf.h"
|
||||||
@@ -2,9 +2,34 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Third party includes
|
||||||
|
|
||||||
|
#define STB_SPRINTF_DECORATE(name) juliet_##name
|
||||||
|
#define STB_SPRINTF_STATIC
|
||||||
|
#include "external/stb/stb_sprintf.h"
|
||||||
|
|
||||||
#define internal static
|
#define internal static
|
||||||
#define global static
|
#define global static
|
||||||
|
|
||||||
|
#if (COMPILER_CLANG && OS_WINDOWS) || COMPILER_MSVC
|
||||||
|
# pragma section(".rdata$", read)
|
||||||
|
# define read_only __declspec(allocate(".rdata$"))
|
||||||
|
#elif (COMPILER_CLANG && OS_LINUX)
|
||||||
|
# define read_only __attribute__((section(".rodata")))
|
||||||
|
#else
|
||||||
|
// Note: not possible with GCC
|
||||||
|
# define read_only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if COMPILER_CLANG || COMPILER_GCC
|
||||||
|
# define thread_static __thread
|
||||||
|
#elif COMPILER_MSVC
|
||||||
|
# define thread_static __declspec(thread)
|
||||||
|
#else
|
||||||
|
# error thread_static not defined for this compiler
|
||||||
|
#endif
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Units
|
// Units
|
||||||
|
|
||||||
@@ -12,17 +37,90 @@
|
|||||||
#define MB(d) ((uint64)(d) << 20)
|
#define MB(d) ((uint64)(d) << 20)
|
||||||
#define GB(d) ((uint64)(d) << 30)
|
#define GB(d) ((uint64)(d) << 30)
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Branch predictor hints
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
# define Expect(expr, val) __builtin_expect((expr), (val))
|
||||||
|
#else
|
||||||
|
# define Expect(expr, val) (expr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define Likely(expr) Expect(expr, 1)
|
||||||
|
#define Unlikely(expr) Expect(expr, 0)
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Min Max Clamp
|
||||||
|
|
||||||
|
#define Min(A, B) (((A) < (B) ? (A) : (B)))
|
||||||
|
#define Max(A, B) (((A) > (B) ? (A) : (B)))
|
||||||
|
#define ClampTop(A, X) Min(A, X)
|
||||||
|
#define ClampBottom(X, B) Max(X, B)
|
||||||
|
#define Clamp(A, X, B) (((X) < (A)) ? (A) : ((X) > (B)) ? (B) : (X))
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Alignment
|
||||||
|
#if COMPILER_CLANG || COMPILER_GCC
|
||||||
|
# define AlignOf(Type) __alignof(Type)
|
||||||
|
#elif COMPILER_MSVC
|
||||||
|
# define AlignOf(Type) __alignof(Type)
|
||||||
|
#else
|
||||||
|
# error AlignOf not defined for this compiler
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Memory Helpers
|
||||||
|
|
||||||
|
#define MemoryCopy(dst, src, size) memmove((dst), (src), (size))
|
||||||
|
#define MemorySet(dst, src, size) memset((dst), (src), (size))
|
||||||
|
|
||||||
|
#define MemoryZero(ptr, size) memset((ptr), 0, (size))
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Asserts
|
// Asserts
|
||||||
|
|
||||||
|
#if COMPILER_CLANG || COMPILER_GCC
|
||||||
|
# define Trap() __builtin_trap()
|
||||||
|
#elif COMPILER_MSVC
|
||||||
|
# define Trap() __debugbreak()
|
||||||
|
#else
|
||||||
|
# error Unknown trap intrinsic for this compiler
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AssertAlways(cond) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (!(cond)) \
|
||||||
|
{ \
|
||||||
|
Trap(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
# define Assert(cond) AssertAlways(cond)
|
||||||
|
#else
|
||||||
|
# define Assert(cond) (void)(cond)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define StaticAssert(cond, ID) global uint8 GLUE(ID, __LINE__)[(cond) ? 1 : -1]
|
#define StaticAssert(cond, ID) global uint8 GLUE(ID, __LINE__)[(cond) ? 1 : -1]
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Linked List helpers
|
||||||
|
|
||||||
|
// Single (link & head) lists (= stacks)
|
||||||
|
#define SLL_stack_push_node(first, node, next) ((node)->next = (first), (first) = (node))
|
||||||
|
#define SLL_stack_pop_node(first, next) ((first) = (first)->next);
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
|
#define AlignPow2(x, align) (((x) + (align) - 1) & (~((align) - 1)))
|
||||||
|
|
||||||
#define GLUE_(A, B) A##B
|
#define GLUE_(A, B) A##B
|
||||||
#define GLUE(A, B) GLUE_(A, B)
|
#define GLUE(A, B) GLUE_(A, B)
|
||||||
|
|
||||||
|
#define ArrayCount(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Core Types
|
// Core Types
|
||||||
|
|
||||||
@@ -39,3 +137,89 @@ typedef int8 bool8;
|
|||||||
typedef int16 bool16;
|
typedef int16 bool16;
|
||||||
typedef int32 bool32;
|
typedef int32 bool32;
|
||||||
typedef int64 bool64;
|
typedef int64 bool64;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Core Constants
|
||||||
|
|
||||||
|
global uint8 max_uint8 = 0xFF;
|
||||||
|
global uint16 max_uint16 = 0xFFFF;
|
||||||
|
global uint32 max_uint32 = 0xFFFFFFFF;
|
||||||
|
global uint64 max_uint64 = 0xFFFFFFFFFFFFFFFFll;
|
||||||
|
|
||||||
|
global int8 max_int8 = (int8)0x7F;
|
||||||
|
global int16 max_int16 = (int16)0x7FFF;
|
||||||
|
global int32 max_int32 = (int32)0x7FFFFFFF;
|
||||||
|
global int64 max_int64 = (int64)0x7FFFFFFFFFFFFFFFll;
|
||||||
|
|
||||||
|
global const uint32 bitmask1 = 0x00000001;
|
||||||
|
global const uint32 bitmask2 = 0x00000003;
|
||||||
|
global const uint32 bitmask3 = 0x00000007;
|
||||||
|
global const uint32 bitmask4 = 0x0000000f;
|
||||||
|
global const uint32 bitmask5 = 0x0000001f;
|
||||||
|
global const uint32 bitmask6 = 0x0000003f;
|
||||||
|
global const uint32 bitmask7 = 0x0000007f;
|
||||||
|
global const uint32 bitmask8 = 0x000000ff;
|
||||||
|
global const uint32 bitmask9 = 0x000001ff;
|
||||||
|
global const uint32 bitmask10 = 0x000003ff;
|
||||||
|
global const uint32 bitmask11 = 0x000007ff;
|
||||||
|
global const uint32 bitmask12 = 0x00000fff;
|
||||||
|
global const uint32 bitmask13 = 0x00001fff;
|
||||||
|
global const uint32 bitmask14 = 0x00003fff;
|
||||||
|
global const uint32 bitmask15 = 0x00007fff;
|
||||||
|
global const uint32 bitmask16 = 0x0000ffff;
|
||||||
|
global const uint32 bitmask17 = 0x0001ffff;
|
||||||
|
global const uint32 bitmask18 = 0x0003ffff;
|
||||||
|
global const uint32 bitmask19 = 0x0007ffff;
|
||||||
|
global const uint32 bitmask20 = 0x000fffff;
|
||||||
|
global const uint32 bitmask21 = 0x001fffff;
|
||||||
|
global const uint32 bitmask22 = 0x003fffff;
|
||||||
|
global const uint32 bitmask23 = 0x007fffff;
|
||||||
|
global const uint32 bitmask24 = 0x00ffffff;
|
||||||
|
global const uint32 bitmask25 = 0x01ffffff;
|
||||||
|
global const uint32 bitmask26 = 0x03ffffff;
|
||||||
|
global const uint32 bitmask27 = 0x07ffffff;
|
||||||
|
global const uint32 bitmask28 = 0x0fffffff;
|
||||||
|
global const uint32 bitmask29 = 0x1fffffff;
|
||||||
|
global const uint32 bitmask30 = 0x3fffffff;
|
||||||
|
global const uint32 bitmask31 = 0x7fffffff;
|
||||||
|
global const uint32 bitmask32 = 0xffffffff;
|
||||||
|
|
||||||
|
global const uint32 bit1 = (1 << 0);
|
||||||
|
global const uint32 bit2 = (1 << 1);
|
||||||
|
global const uint32 bit3 = (1 << 2);
|
||||||
|
global const uint32 bit4 = (1 << 3);
|
||||||
|
global const uint32 bit5 = (1 << 4);
|
||||||
|
global const uint32 bit6 = (1 << 5);
|
||||||
|
global const uint32 bit7 = (1 << 6);
|
||||||
|
global const uint32 bit8 = (1 << 7);
|
||||||
|
global const uint32 bit9 = (1 << 8);
|
||||||
|
global const uint32 bit10 = (1 << 9);
|
||||||
|
global const uint32 bit11 = (1 << 10);
|
||||||
|
global const uint32 bit12 = (1 << 11);
|
||||||
|
global const uint32 bit13 = (1 << 12);
|
||||||
|
global const uint32 bit14 = (1 << 13);
|
||||||
|
global const uint32 bit15 = (1 << 14);
|
||||||
|
global const uint32 bit16 = (1 << 15);
|
||||||
|
global const uint32 bit17 = (1 << 16);
|
||||||
|
global const uint32 bit18 = (1 << 17);
|
||||||
|
global const uint32 bit19 = (1 << 18);
|
||||||
|
global const uint32 bit20 = (1 << 19);
|
||||||
|
global const uint32 bit21 = (1 << 20);
|
||||||
|
global const uint32 bit22 = (1 << 21);
|
||||||
|
global const uint32 bit23 = (1 << 22);
|
||||||
|
global const uint32 bit24 = (1 << 23);
|
||||||
|
global const uint32 bit25 = (1 << 24);
|
||||||
|
global const uint32 bit26 = (1 << 25);
|
||||||
|
global const uint32 bit27 = (1 << 26);
|
||||||
|
global const uint32 bit28 = (1 << 27);
|
||||||
|
global const uint32 bit29 = (1 << 28);
|
||||||
|
global const uint32 bit30 = (1 << 29);
|
||||||
|
global const uint32 bit31 = (1 << 30);
|
||||||
|
global const uint32 bit32 = (1 << 31);
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Safe Casts
|
||||||
|
|
||||||
|
internal uint16 safe_cast_uint16(uint32 val);
|
||||||
|
internal uint32 safe_cast_uint32(uint64 val);
|
||||||
|
internal int32 safe_cast_int32(int64 val);
|
||||||
+186
-3
@@ -1,10 +1,193 @@
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Arena Functions
|
// Arena Functions
|
||||||
|
|
||||||
internal Arena* arena_alloc_internal()
|
#include "core/core.h"
|
||||||
|
internal Arena* arena_alloc_internal(ArenaParams* params)
|
||||||
{
|
{
|
||||||
Arena* arena = NULL;
|
uint64 committed = params->commit_size;
|
||||||
|
uint64 reserved = params->reserve_size;
|
||||||
|
|
||||||
|
// Initial block
|
||||||
|
void* base = NULL;
|
||||||
|
if (params->flags & ArenaFlag_LargePages)
|
||||||
|
{
|
||||||
|
uint64 page_size = get_system_info()->large_page_size;
|
||||||
|
reserved = AlignPow2(reserved, page_size);
|
||||||
|
committed = AlignPow2(committed, page_size);
|
||||||
|
|
||||||
|
base = reserve_memory_large(reserved);
|
||||||
|
commit_memory_large(base, committed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint64 page_size = get_system_info()->page_size;
|
||||||
|
reserved = AlignPow2(reserved, page_size);
|
||||||
|
committed = AlignPow2(committed, page_size);
|
||||||
|
|
||||||
|
base = reserve_memory(reserved);
|
||||||
|
commit_memory(base, committed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Unlikely(base == 0))
|
||||||
|
{
|
||||||
|
abort_self(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Arena* arena = base;
|
||||||
|
arena->current = arena;
|
||||||
|
arena->commit_size = params->commit_size;
|
||||||
|
arena->reserve_size = params->reserve_size;
|
||||||
|
arena->base_position = 0;
|
||||||
|
arena->position = ARENA_HEADER_SIZE;
|
||||||
|
arena->committed = committed;
|
||||||
|
arena->reserved = reserved;
|
||||||
|
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
arena->alloc_file = params->alloc_file;
|
||||||
|
arena->alloc_line = params->alloc_line;
|
||||||
|
arena->name = params->name;
|
||||||
|
#endif
|
||||||
|
|
||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void arena_release(Arena* arena) {}
|
internal void arena_release(Arena* arena)
|
||||||
|
{
|
||||||
|
for (Arena *p = arena->current, *prev = 0; p != 0; p = prev)
|
||||||
|
{
|
||||||
|
prev = p->previous;
|
||||||
|
release_memory(p, p->reserved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Arena Push/Pop core Functions
|
||||||
|
|
||||||
|
internal void* arena_push(Arena* arena, uint64 size, uint64 align, bool32 zero)
|
||||||
|
{
|
||||||
|
Arena* current = arena->current;
|
||||||
|
uint64 pos_pre = AlignPow2(current->position, align);
|
||||||
|
uint64 pos_post = pos_pre + size;
|
||||||
|
|
||||||
|
uint64 size_to_zero = 0;
|
||||||
|
if (zero)
|
||||||
|
{
|
||||||
|
size_to_zero = Min(current->committed, pos_post) - pos_pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current->reserved < pos_post && !(arena->flags & ArenaFlag_NoChain))
|
||||||
|
{
|
||||||
|
Arena* new_block = 0;
|
||||||
|
if (new_block == 0)
|
||||||
|
{
|
||||||
|
uint64 reserved_size = arena->reserve_size;
|
||||||
|
uint64 committed_size = arena->commit_size;
|
||||||
|
if (size + ARENA_HEADER_SIZE > reserved_size)
|
||||||
|
{
|
||||||
|
reserved_size = AlignPow2(size + ARENA_HEADER_SIZE, align);
|
||||||
|
committed_size = AlignPow2(size + ARENA_HEADER_SIZE, align);
|
||||||
|
}
|
||||||
|
new_block = arena_alloc(.reserve_size = reserved_size, .commit_size = committed_size, .flags = arena->flags,
|
||||||
|
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
.alloc_file = arena->alloc_file, .alloc_line = arena->alloc_line
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
size_to_zero = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_to_zero = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_block->base_position = current->base_position + current->reserved;
|
||||||
|
SLL_stack_push_node(arena->current, new_block, previous);
|
||||||
|
|
||||||
|
current = new_block;
|
||||||
|
pos_pre = AlignPow2(current->position, align);
|
||||||
|
pos_post = pos_pre + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// commit new pages if needed
|
||||||
|
if (current->committed < pos_post)
|
||||||
|
{
|
||||||
|
uint64 committed_past_aligned = pos_post + current->commit_size - 1;
|
||||||
|
committed_past_aligned -= committed_past_aligned % current->commit_size;
|
||||||
|
uint64 committed_past_clamped = ClampTop(committed_past_aligned, current->reserved);
|
||||||
|
uint64 committed_size = committed_past_clamped - current->committed;
|
||||||
|
uint8* committed_ptr = (uint8*)current + current->committed;
|
||||||
|
if (current->flags & ArenaFlag_LargePages)
|
||||||
|
{
|
||||||
|
commit_memory_large(committed_ptr, committed_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
commit_memory(committed_ptr, committed_size);
|
||||||
|
}
|
||||||
|
current->committed = committed_past_clamped;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* result = 0;
|
||||||
|
if (current->committed >= pos_post)
|
||||||
|
{
|
||||||
|
result = (uint8*)current + pos_pre;
|
||||||
|
current->position = pos_post;
|
||||||
|
MemoryZero(result, size_to_zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Unlikely(result == 0))
|
||||||
|
{
|
||||||
|
abort_self(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint64 arena_pos(Arena* arena)
|
||||||
|
{
|
||||||
|
Arena* current = arena->current;
|
||||||
|
uint64 position = current->base_position + current->position;
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void arena_pop_to(Arena* arena, uint64 position)
|
||||||
|
{
|
||||||
|
uint64 clamped_pos = ClampBottom(ARENA_HEADER_SIZE, position);
|
||||||
|
Arena* current = arena->current;
|
||||||
|
|
||||||
|
for (Arena* previous = 0; current->base_position >= clamped_pos; current = previous)
|
||||||
|
{
|
||||||
|
previous = current->previous;
|
||||||
|
release_memory(current, current->reserved);
|
||||||
|
}
|
||||||
|
arena->current = current;
|
||||||
|
uint64 new_position = clamped_pos - current->base_position;
|
||||||
|
AssertAlways(new_position <= current->position);
|
||||||
|
current->position = new_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void arena_clear(Arena* arena)
|
||||||
|
{
|
||||||
|
arena_pop_to(arena, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void arena_pop(Arena* arena, uint64 amount)
|
||||||
|
{
|
||||||
|
uint64 pos_old = arena_pos(arena);
|
||||||
|
Assert(pos_old > amount);
|
||||||
|
uint64 pos_new = pos_old - amount;
|
||||||
|
arena_pop_to(arena, pos_new);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temp arena
|
||||||
|
internal TempArena temp_begin(Arena* arena)
|
||||||
|
{
|
||||||
|
uint64 position = arena_pos(arena);
|
||||||
|
TempArena temp = { arena, position };
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void temp_end(TempArena temp)
|
||||||
|
{
|
||||||
|
arena_pop_to(temp.arena, temp.position);
|
||||||
|
}
|
||||||
@@ -5,11 +5,30 @@
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Arena Types
|
// Arena Types
|
||||||
|
|
||||||
|
typedef uint64 ArenaFlags;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ArenaFlag_NoChain = (1 << 0),
|
||||||
|
ArenaFlag_LargePages = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ArenaParams ArenaParams;
|
||||||
|
struct ArenaParams
|
||||||
|
{
|
||||||
|
ArenaFlags flags;
|
||||||
|
uint64 commit_size;
|
||||||
|
uint64 reserve_size;
|
||||||
|
char* alloc_file;
|
||||||
|
int alloc_line;
|
||||||
|
char* name;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct Arena Arena;
|
typedef struct Arena Arena;
|
||||||
struct Arena
|
struct Arena
|
||||||
{
|
{
|
||||||
Arena* previous;
|
Arena* previous;
|
||||||
Arena* current;
|
Arena* current;
|
||||||
|
ArenaFlags flags;
|
||||||
uint64 base_position;
|
uint64 base_position;
|
||||||
uint64 position;
|
uint64 position;
|
||||||
uint64 commit_size;
|
uint64 commit_size;
|
||||||
@@ -26,7 +45,7 @@ struct Arena
|
|||||||
StaticAssert(sizeof(Arena) <= ARENA_HEADER_SIZE, arena_header_size_check);
|
StaticAssert(sizeof(Arena) <= ARENA_HEADER_SIZE, arena_header_size_check);
|
||||||
|
|
||||||
typedef struct TempArena TempArena;
|
typedef struct TempArena TempArena;
|
||||||
struct TempAren
|
struct TempArena
|
||||||
{
|
{
|
||||||
Arena* arena;
|
Arena* arena;
|
||||||
uint64 position;
|
uint64 position;
|
||||||
@@ -37,3 +56,33 @@ struct TempAren
|
|||||||
|
|
||||||
global uint64 arena_default_reserve_size = MB(64);
|
global uint64 arena_default_reserve_size = MB(64);
|
||||||
global uint64 arena_default_commit_size = KB(64);
|
global uint64 arena_default_commit_size = KB(64);
|
||||||
|
|
||||||
|
internal Arena* arena_alloc_internal(ArenaParams* params);
|
||||||
|
#define arena_alloc(...) \
|
||||||
|
arena_alloc_internal(&(ArenaParams){ .commit_size = arena_default_commit_size, \
|
||||||
|
.reserve_size = arena_default_reserve_size, \
|
||||||
|
.alloc_file = __FILE__, \
|
||||||
|
.alloc_line = __LINE__, \
|
||||||
|
__VA_ARGS__ })
|
||||||
|
internal void arena_release(Arena* arena);
|
||||||
|
|
||||||
|
// Arena Push/Pop core Functions
|
||||||
|
|
||||||
|
internal void* arena_push(Arena* arena, uint64 size, uint64 align, bool32 zero);
|
||||||
|
internal uint64 arena_pos(Arena* arena);
|
||||||
|
internal void arena_pop_to(Arena* arena, uint64 position);
|
||||||
|
internal void arena_clear(Arena* arena);
|
||||||
|
internal void arena_pop(Arena* arena, uint64 amount);
|
||||||
|
|
||||||
|
// Temp arena
|
||||||
|
internal TempArena temp_begin(Arena* arena);
|
||||||
|
internal void temp_end(TempArena temp);
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Push Helper Macros
|
||||||
|
|
||||||
|
#define push_array_no_zero_aligned(arr, Type, count, align) \
|
||||||
|
(Type*)arena_push((arr), sizeof(Type) * (count), (align), (0))
|
||||||
|
#define push_array_aligned(arr, Type, count, align) (Type*)arena_push((arr), sizeof(Type) * (count), (align), (1))
|
||||||
|
#define push_array_no_zero(arr, Type, count) push_array_no_zero_aligned(arr, Type, count, Max(8, AlignOf(Type)))
|
||||||
|
#define push_array(arr, Type, count) push_array_aligned(arr, Type, count, Max(8, AlignOf(Type)))
|
||||||
@@ -2,5 +2,6 @@ internal void entry_point();
|
|||||||
|
|
||||||
internal void main_thread_core_entry_point(int argc, char** argv)
|
internal void main_thread_core_entry_point(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
ThreadNameF("main_thread");
|
||||||
entry_point();
|
entry_point();
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
#include "core_string.c"
|
#include "core.c"
|
||||||
|
#include "core_memory.c"
|
||||||
#include "core_arena.c"
|
#include "core_arena.c"
|
||||||
|
#include "core_string.c"
|
||||||
|
#include "core_system.c"
|
||||||
|
#include "core_threads.c"
|
||||||
|
#include "core_thread_context.c"
|
||||||
|
#include "core_processes.c"
|
||||||
|
#include "core_markup.c"
|
||||||
#include "core_entry_point.c"
|
#include "core_entry_point.c"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,14 @@
|
|||||||
#include "core_defines.h"
|
#include "core_defines.h"
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include "core_memory.h"
|
||||||
|
#include "core_processes.h"
|
||||||
#include "core_arena.h"
|
#include "core_arena.h"
|
||||||
#include "core_string.h"
|
#include "core_string.h"
|
||||||
|
#include "core_system.h"
|
||||||
|
#include "core_threads.h"
|
||||||
|
#include "core_thread_context.h"
|
||||||
|
#include "core_markup.h"
|
||||||
#include "core_entry_point.h"
|
#include "core_entry_point.h"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|||||||
Whitespace-only changes.
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ThreadNameF(...) (set_thread_namef(__VAR_ARGS__))
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
// OS DEPEND see os/core/os_core.c
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
internal void* reserve_memory(uint64 size);
|
||||||
|
internal bool32 commit_memory(void* ptr, uint64 size);
|
||||||
|
internal void* reserve_memory_large(uint64 size);
|
||||||
|
internal bool32 commit_memory_large(void* ptr, uint64 size);
|
||||||
|
internal void decommit_memory(void* ptr, uint64 size);
|
||||||
|
internal void release_memory(void* ptr, uint64 size);
|
||||||
Whitespace-only changes.
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Aborting (os dependent see os/core/os_core.c)
|
||||||
|
|
||||||
|
internal void abort_self(uint64 exit_code);
|
||||||
+192
-1
@@ -1,5 +1,6 @@
|
|||||||
// ========================================================================== //
|
// ========================================================================== //
|
||||||
// String Length
|
// String Length
|
||||||
|
#include "core/core_arena.h"
|
||||||
internal uint64 cstring8_length(uint8* cstring)
|
internal uint64 cstring8_length(uint8* cstring)
|
||||||
{
|
{
|
||||||
uint64 length = 0;
|
uint64 length = 0;
|
||||||
@@ -42,7 +43,19 @@ internal uint64 cstring32_length(uint32* cstring)
|
|||||||
// ========================================================================== //
|
// ========================================================================== //
|
||||||
// String Constructor
|
// String Constructor
|
||||||
|
|
||||||
internal String8 str8_cstring(uint8* cstring)
|
internal String8 str8(uint8* str, uint64 size)
|
||||||
|
{
|
||||||
|
String8 result = { str, size };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal String8 str8_zero()
|
||||||
|
{
|
||||||
|
String8 result = { 0 };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal String8 str8_cstring(const char* cstring)
|
||||||
{
|
{
|
||||||
String8 result = { (uint8*)cstring, cstring8_length((uint8*)cstring) };
|
String8 result = { (uint8*)cstring, cstring8_length((uint8*)cstring) };
|
||||||
return result;
|
return result;
|
||||||
@@ -59,3 +72,181 @@ internal String32 str32_cstring(uint32* cstring)
|
|||||||
String32 result = { (uint32*)cstring, cstring32_length((uint32*)cstring) };
|
String32 result = { (uint32*)cstring, cstring32_length((uint32*)cstring) };
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========================================================================== //
|
||||||
|
// String Formatting & Copying
|
||||||
|
|
||||||
|
internal String8 str8_copy(Arena* arena, String8 in)
|
||||||
|
{
|
||||||
|
String8 str;
|
||||||
|
str.size = in.size;
|
||||||
|
str.str = push_array_no_zero(arena, uint8, str.size + 1);
|
||||||
|
MemoryCopy(str.str, in.str, in.size);
|
||||||
|
str.str[str.size] = '\0';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Unicode String Encode/Decode
|
||||||
|
|
||||||
|
read_only global uint8 utf8_class[32] = {
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
internal UnicodeDecode utf8_decode(uint8* str, uint64 max)
|
||||||
|
{
|
||||||
|
UnicodeDecode result = { 1, max_uint32 };
|
||||||
|
uint8 byte = str[0];
|
||||||
|
uint8 byte_class = utf8_class[byte >> 3];
|
||||||
|
switch (byte_class)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
result.codepoint = byte;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
if (1 < max)
|
||||||
|
{
|
||||||
|
uint8 cont_byte = str[1];
|
||||||
|
if (utf8_class[cont_byte >> 3] == 0)
|
||||||
|
{
|
||||||
|
result.codepoint = (byte & bitmask5) << 6;
|
||||||
|
result.codepoint |= (cont_byte & bitmask6);
|
||||||
|
result.increment = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
if (2 < max)
|
||||||
|
{
|
||||||
|
uint8 cont_byte[2] = { str[1], str[2] };
|
||||||
|
if (utf8_class[cont_byte[0] >> 3] == 0 && utf8_class[cont_byte[1] >> 3] == 0)
|
||||||
|
{
|
||||||
|
result.codepoint = (byte & bitmask4) << 12;
|
||||||
|
result.codepoint |= ((cont_byte[0] & bitmask6) << 6);
|
||||||
|
result.codepoint |= (cont_byte[1] & bitmask6);
|
||||||
|
result.increment = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
if (3 < max)
|
||||||
|
{
|
||||||
|
uint8 cont_byte[3] = { str[1], str[2], str[3] };
|
||||||
|
if (utf8_class[cont_byte[0] >> 3] == 0 && utf8_class[cont_byte[1] >> 3] == 0 && utf8_class[cont_byte[2] >> 3] == 0)
|
||||||
|
{
|
||||||
|
result.codepoint = (byte & bitmask3) << 18;
|
||||||
|
result.codepoint |= ((cont_byte[0] & bitmask6 << 12));
|
||||||
|
result.codepoint |= ((cont_byte[1] & bitmask6) << 6);
|
||||||
|
result.codepoint |= (cont_byte[2] & bitmask6);
|
||||||
|
result.increment = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal UnicodeDecode utf16_decode(uint16* str, uint64 max)
|
||||||
|
{
|
||||||
|
UnicodeDecode result = { 1, max_uint32 };
|
||||||
|
result.codepoint = str[0];
|
||||||
|
result.increment = 1;
|
||||||
|
if (max > 1 && 0xD800 <= str[0] && str[0] < 0xDC00 && 0xDC00 <= str[1] && str[1] < 0xE000)
|
||||||
|
{
|
||||||
|
result.codepoint = ((str[0] - 0xD800) << 10) | ((str[1] - 0xDC00) + 0x10000);
|
||||||
|
result.increment = 2;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint32 utf8_encode(uint8* str, uint32 codepoint)
|
||||||
|
{
|
||||||
|
uint32 increment = 0;
|
||||||
|
if (codepoint <= 0x7f)
|
||||||
|
{
|
||||||
|
str[0] = (uint8)codepoint;
|
||||||
|
increment = 1;
|
||||||
|
}
|
||||||
|
else if (codepoint <= 0x7FF)
|
||||||
|
{
|
||||||
|
str[0] = (bitmask2 << 6) | ((codepoint >> 6) & bitmask5);
|
||||||
|
str[1] = bit8 | (codepoint & bitmask6);
|
||||||
|
increment = 2;
|
||||||
|
}
|
||||||
|
else if (codepoint <= 0xFFFF)
|
||||||
|
{
|
||||||
|
str[0] = (bitmask3 << 5) | ((codepoint >> 12) & bitmask4);
|
||||||
|
str[1] = bit8 | ((codepoint >> 6) & bitmask6);
|
||||||
|
str[2] = bit8 | (codepoint & bitmask6);
|
||||||
|
increment = 3;
|
||||||
|
}
|
||||||
|
else if (codepoint <= 0x10FFFF)
|
||||||
|
{
|
||||||
|
str[0] = (bitmask4 << 4) | ((codepoint >> 18) & bitmask3);
|
||||||
|
str[1] = bit8 | ((codepoint >> 12) & bitmask6);
|
||||||
|
str[2] = bit8 | (codepoint >> 6 & bitmask6);
|
||||||
|
str[3] = bit8 | (codepoint & bitmask6);
|
||||||
|
increment = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str[0] = '?';
|
||||||
|
increment = 1;
|
||||||
|
}
|
||||||
|
return increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint32 utf16_encode(uint16* str, uint32 codepoint)
|
||||||
|
{
|
||||||
|
uint32 increment = 1;
|
||||||
|
if (codepoint == max_uint32)
|
||||||
|
{
|
||||||
|
str[0] = (uint16)'?';
|
||||||
|
}
|
||||||
|
else if (codepoint < 0x10000)
|
||||||
|
{
|
||||||
|
str[0] = (uint16)codepoint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 v = codepoint - 0x10000;
|
||||||
|
str[0] = safe_cast_uint16(0xD800 + (v >> 10));
|
||||||
|
str[1] = safe_cast_uint16(0xDC00 + (v & bitmask10));
|
||||||
|
increment = 2;
|
||||||
|
}
|
||||||
|
return increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Unicode String Conversions
|
||||||
|
|
||||||
|
internal String8 str8_from_16(Arena* arena, String16 in)
|
||||||
|
{
|
||||||
|
String8 result = str8_zero();
|
||||||
|
if (in.size)
|
||||||
|
{
|
||||||
|
uint64 capacity = in.size * 3;
|
||||||
|
uint8* str = push_array_no_zero(arena, uint8, capacity + 1);
|
||||||
|
uint16* ptr = in.str;
|
||||||
|
uint16* op1 = ptr + in.size;
|
||||||
|
uint64 size = 0;
|
||||||
|
UnicodeDecode consume;
|
||||||
|
for (; ptr < op1; ptr += consume.increment)
|
||||||
|
{
|
||||||
|
consume = utf16_decode(ptr, op1 - ptr);
|
||||||
|
size += utf8_encode(str + size, consume.codepoint);
|
||||||
|
}
|
||||||
|
str[size] = '\0';
|
||||||
|
arena_pop(arena, (capacity - size));
|
||||||
|
result = str8(str, size);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -24,6 +24,16 @@ struct String32
|
|||||||
uint64 size;
|
uint64 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ========================================================================== //
|
||||||
|
// Unicode decoding Types
|
||||||
|
|
||||||
|
typedef struct UnicodeDecode UnicodeDecode;
|
||||||
|
struct UnicodeDecode
|
||||||
|
{
|
||||||
|
uint32 increment;
|
||||||
|
uint32 codepoint;
|
||||||
|
};
|
||||||
|
|
||||||
// ========================================================================== //
|
// ========================================================================== //
|
||||||
// String Length
|
// String Length
|
||||||
internal uint64 cstring8_length(uint8* cstring);
|
internal uint64 cstring8_length(uint8* cstring);
|
||||||
@@ -33,4 +43,26 @@ internal uint64 cstring32_length(uint32* cstring);
|
|||||||
// ========================================================================== //
|
// ========================================================================== //
|
||||||
// String Constructor
|
// String Constructor
|
||||||
|
|
||||||
|
internal String8 str8(uint8* str, uint64 size);
|
||||||
|
internal String8 str8_zero();
|
||||||
|
internal String8 str8_cstring(const char* cstring);
|
||||||
internal String16 str16_cstring(uint16* cstring);
|
internal String16 str16_cstring(uint16* cstring);
|
||||||
|
internal String32 str32_cstring(uint32* cstring);
|
||||||
|
|
||||||
|
// ========================================================================== //
|
||||||
|
// String Formatting & Copying
|
||||||
|
|
||||||
|
internal String8 str8_copy(Arena* arena, String8 in);
|
||||||
|
|
||||||
|
// ========================================================================== //
|
||||||
|
// Unicode String Encode/Decode
|
||||||
|
|
||||||
|
internal UnicodeDecode utf8_decode(uint8* str, uint64 max);
|
||||||
|
internal UnicodeDecode utf16_decode(uint16* str, uint64 max);
|
||||||
|
internal uint32 utf8_encode(uint8* str, uint32 codepoint);
|
||||||
|
internal uint32 utf16_encode(uint16* str, uint32 codepoint);
|
||||||
|
|
||||||
|
// ========================================================================== //
|
||||||
|
// Unicode String Conversions
|
||||||
|
|
||||||
|
internal String8 str8_from_16(Arena* arena, String16 in);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
// OS DEPEND see os/core/os_core.c
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct SystemInfo SystemInfo;
|
||||||
|
struct SystemInfo
|
||||||
|
{
|
||||||
|
uint64 page_size;
|
||||||
|
uint64 large_page_size;
|
||||||
|
String8 machine_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal SystemInfo* get_system_info();
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Globals
|
||||||
|
|
||||||
|
thread_static TCTX* tctx_thread_local;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Thread Context Functions
|
||||||
|
|
||||||
|
// Thread Context allocation
|
||||||
|
internal TCTX* tctx_alloc()
|
||||||
|
{
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
thread_static static char name[2][1024];
|
||||||
|
juliet_snprintf(name[0], sizeof(name[0]), "Scratch/0[TID:%u]", tid());
|
||||||
|
juliet_snprintf(name[1], sizeof(name[1]), "Scratch/1[TID:%u]", tid());
|
||||||
|
Arena* arena_0 = arena_alloc(.name = name[0]);
|
||||||
|
Arena* arena_1 = arena_alloc(.name = name[1]);
|
||||||
|
#else
|
||||||
|
Arena* arena_0 = arena_alloc();
|
||||||
|
Arena* arena_1 = arena_alloc();
|
||||||
|
#endif
|
||||||
|
TCTX* tctx = push_array(arena_0, TCTX, 1);
|
||||||
|
tctx->arenas[0] = arena_0;
|
||||||
|
tctx->arenas[1] = arena_1;
|
||||||
|
return tctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void tctx_release(TCTX* tctx)
|
||||||
|
{
|
||||||
|
arena_release(tctx->arenas[0]);
|
||||||
|
arena_release(tctx->arenas[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void tctx_select(TCTX* tctx)
|
||||||
|
{
|
||||||
|
tctx_thread_local = tctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal TCTX* tctx_selected()
|
||||||
|
{
|
||||||
|
return tctx_thread_local;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Arena* tctx_get_scratch(Arena** conflicts, uint64 count)
|
||||||
|
{
|
||||||
|
TCTX* tctx = tctx_selected();
|
||||||
|
Arena* result = 0;
|
||||||
|
Arena** arena_ptr = tctx->arenas;
|
||||||
|
for (uint64 i = 0; i < ArrayCount(tctx->arenas); ++i, ++arena_ptr)
|
||||||
|
{
|
||||||
|
Arena** conflict_ptr = conflicts;
|
||||||
|
bool32 has_conflict = 0;
|
||||||
|
for (uint64 j = 0; j < count; ++j, ++conflict_ptr)
|
||||||
|
{
|
||||||
|
if (*arena_ptr == *conflict_ptr)
|
||||||
|
{
|
||||||
|
has_conflict = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!has_conflict)
|
||||||
|
{
|
||||||
|
result = *arena_ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define scratch_begin(conflicts, count) temp_begin(tctx_get_scratch((conflicts), (count)))
|
||||||
|
#define scratch_end(scratch) temp_end(scratch)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct TCTX TCTX;
|
||||||
|
struct TCTX
|
||||||
|
{
|
||||||
|
// Scratch arenas
|
||||||
|
Arena* arenas[2];
|
||||||
|
|
||||||
|
uint8 thread_name[32];
|
||||||
|
uint64 thread_name_size;
|
||||||
|
|
||||||
|
char* file_name;
|
||||||
|
uint64 line_number;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern thread_static TCTX* tctx_thread_local;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Thread Context Functions
|
||||||
|
|
||||||
|
// Thread Context allocation
|
||||||
|
internal TCTX* tctx_alloc();
|
||||||
|
internal void tctx_release(TCTX* tctx);
|
||||||
|
internal void tctx_select(TCTX* tctx);
|
||||||
|
internal TCTX* tctx_selected();
|
||||||
|
|
||||||
|
internal Arena* tctx_get_scratch(Arena** conflicts, uint64 count);
|
||||||
|
#define scratch_begin(conflicts, count) temp_begin(tctx_get_scratch((conflicts), (count)))
|
||||||
|
#define scratch_end(scratch) temp_end(scratch)
|
||||||
Whitespace-only changes.
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Thread Info Helpers
|
||||||
|
internal void set_thread_name(String8 name);
|
||||||
|
internal void set_thread_namef(char* fmt, ...);
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Thread Info
|
||||||
|
|
||||||
|
internal uint32 tid();
|
||||||
|
internal void set_platform_thread_name(String8 name);
|
||||||
+1
Submodule Juliet/external/stb added at 2c980bb598.
@@ -1,17 +1,127 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// System
|
||||||
|
|
||||||
|
#include "core/core_thread_context.h"
|
||||||
|
internal SystemInfo* get_system_info()
|
||||||
|
{
|
||||||
|
return &w32_state.system_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Thread Info
|
||||||
|
|
||||||
|
internal uint32 tid()
|
||||||
|
{
|
||||||
|
DWORD id = GetCurrentThreadId();
|
||||||
|
return (uint32)id;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void set_platform_thread_name(String8 name)
|
||||||
|
{
|
||||||
|
TempArena scratch = scratch_begin(0, 0);
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Memory
|
||||||
|
|
||||||
|
internal void* reserve_memory(uint64 size)
|
||||||
|
{
|
||||||
|
void* result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool32 commit_memory(void* ptr, uint64 size)
|
||||||
|
{
|
||||||
|
bool32 result = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void* reserve_memory_large(uint64 size)
|
||||||
|
{
|
||||||
|
// Windows do not allow commiting large pages
|
||||||
|
void* result = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool32 commit_memory_large(void* ptr, uint64 size)
|
||||||
|
{
|
||||||
|
(void)ptr;
|
||||||
|
(void)size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void decommit_memory(void* ptr, uint64 size)
|
||||||
|
{
|
||||||
|
VirtualFree(ptr, size, MEM_DECOMMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void release_memory(void* ptr, uint64 size)
|
||||||
|
{
|
||||||
|
(void)size; // Unused on windows
|
||||||
|
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Aborting
|
||||||
|
|
||||||
|
internal void abort_self(uint64 exit_code)
|
||||||
|
{
|
||||||
|
ExitProcess((int)exit_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Entry points
|
||||||
|
|
||||||
internal void w32_entry_point(int argc, WCHAR** wargv)
|
internal void w32_entry_point(int argc, WCHAR** wargv)
|
||||||
{
|
{
|
||||||
char* argv[10];
|
SYSTEM_INFO sys_info = { 0 };
|
||||||
|
GetSystemInfo(&sys_info);
|
||||||
|
|
||||||
|
SystemInfo* info = &w32_state.system_info;
|
||||||
|
info->page_size = sys_info.dwPageSize;
|
||||||
|
info->large_page_size = GetLargePageMinimum();
|
||||||
|
|
||||||
|
Arena* args_arena = arena_alloc(.reserve_size = MB(1), .commit_size = KB(32));
|
||||||
|
char** argv = push_array(args_arena, char*, argc);
|
||||||
for (int i = 0; i < argc; ++i)
|
for (int i = 0; i < argc; ++i)
|
||||||
{
|
{
|
||||||
String16 arg16 = str16_cstring((uint16*)wargv[i]);
|
String16 arg16 = str16_cstring((uint16*)wargv[i]);
|
||||||
String8 arg8 = str8_from_16(args_arena, arg16);
|
String8 arg8 = str8_from_16(args_arena, arg16);
|
||||||
argv[i] = (char*)arg8.str;
|
argv[i] = (char*)arg8.str;
|
||||||
}
|
}
|
||||||
main_thread_core_entry_point(argc, &argv);
|
|
||||||
|
// Thread context
|
||||||
|
TCTX* tctx = tctx_alloc();
|
||||||
|
tctx_select(tctx);
|
||||||
|
|
||||||
|
// setup w32 state
|
||||||
|
Arena* arena = arena_alloc();
|
||||||
|
{
|
||||||
|
w32_state.arena = arena;
|
||||||
|
{
|
||||||
|
SystemInfo* info = &w32_state.system_info;
|
||||||
|
DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
|
||||||
|
uint8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = { 0 };
|
||||||
|
if (GetComputerNameA((char*)buffer, &size))
|
||||||
|
{
|
||||||
|
info->machine_name = str8_copy(arena, str8(buffer, size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main_thread_core_entry_point(argc, argv);
|
||||||
|
|
||||||
|
tctx_release(tctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
|
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
|
||||||
{
|
{
|
||||||
|
(void)hInstance;
|
||||||
|
(void)hPrevInstance;
|
||||||
|
(void)lpCmdLine;
|
||||||
|
(void)nShowCmd;
|
||||||
w32_entry_point(__argc, __wargv);
|
w32_entry_point(__argc, __wargv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2,3 +2,12 @@
|
|||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#pragma comment(lib, "user32")
|
#pragma comment(lib, "user32")
|
||||||
|
|
||||||
|
typedef struct W32_State W32_State;
|
||||||
|
struct W32_State
|
||||||
|
{
|
||||||
|
Arena* arena;
|
||||||
|
SystemInfo system_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
global W32_State w32_state = { 0 };
|
||||||
+1
-1
@@ -4,7 +4,7 @@ cd /D "%~dp0"
|
|||||||
|
|
||||||
:: --- Usage Notes -------------------------------------------------------------
|
:: --- Usage Notes -------------------------------------------------------------
|
||||||
::
|
::
|
||||||
:: Central build script for Juliet new module architecture (inspired by raddbg).
|
:: Central build script for Juliet modular architecture.
|
||||||
:: Takes alphanumeric arguments to control target, compiler, and build configuration.
|
:: Takes alphanumeric arguments to control target, compiler, and build configuration.
|
||||||
::
|
::
|
||||||
:: Examples:
|
:: Examples:
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Modular Architecture & Tooling TODO
|
||||||
|
|
||||||
|
This document tracks upcoming tasks for Juliet's modular architecture (`core`, `appbin`, future `render`, `ui`, etc.) and the build/LSP generation tooling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Tooling & Project Generator (`tools/new_project_gen.c`)
|
||||||
|
- [x] **Dynamic Preceding Include Parser**:
|
||||||
|
- Implemented dynamic parser `get_preceding_includes_from_inc_h(layer_name, target_file_path)` in `tools/new_project_gen.c`.
|
||||||
|
- Reads `<layer>_inc.h` line-by-line and collects all `#include "..."` statements that appear strictly **above** the target header being analyzed.
|
||||||
|
- Automatically injects those preceding includes via `/FI` so that any header opened in Neovim/clangd has its exact required preprocessor context with zero hardcoding.
|
||||||
|
- [x] **Multi-Layer Cascade**:
|
||||||
|
- Deduces layer hierarchy from `appbin_main.c` and supplies lower layer includes (`/FIcore/core_inc.h`, etc.) to upper layers automatically.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Core Module Implementation (`Juliet/core/`)
|
||||||
|
- [ ] **Fill `core.c`**:
|
||||||
|
- Implement base core routines (OS helpers, string utilities, arena allocation implementations, math helpers).
|
||||||
|
- [ ] **Win32 Core Cleanup**:
|
||||||
|
- Fix argument passing in `win32_core.c:55` (`main_thread_core_entry_point(argc, &argv)` vs `char** argv`).
|
||||||
|
- Implement proper command line argument parsing into `String8`/`String16` arenas.
|
||||||
|
- [ ] **Unit Tests for Core**:
|
||||||
|
- Create standalone test executable or test entry point validating arena allocation, commit/decommit, and string routines.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Future Layers
|
||||||
|
- [ ] **Render Layer (`Juliet/render/`)**:
|
||||||
|
- Create `render_inc.h`, `render_inc.c`.
|
||||||
|
- Implement D3D12 device initialization, command queues, swap chain, and memory allocators.
|
||||||
|
- Add `#include "render/render_inc.h"` and `#include "render/render_inc.c"` to `appbin_main.c`.
|
||||||
|
- [ ] **UI Layer (`Juliet/ui/`)**:
|
||||||
|
- Create `ui_inc.h`, `ui_inc.c`.
|
||||||
|
- Implement UI hierarchy, layout, text rendering, and input handling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Build System & LSP Maintenance
|
||||||
|
- [ ] Run `new_generate.bat` after adding new layers or changing layer include order in `appbin_main.c`.
|
||||||
|
- [ ] Keep `new_build.bat` as the single-pass unity compiler command for lightning-fast build times.
|
||||||
+281
-16
@@ -248,6 +248,241 @@ static void get_normalized_cwd(char* out_cwd, size_t out_cwd_size, char* out_rea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32 get_layer_order_from_main(char layers[32][64])
|
||||||
|
{
|
||||||
|
int32 count = 0;
|
||||||
|
FILE* file = fopen("Juliet/appbin/appbin_main.c", "rb");
|
||||||
|
if (file != NULL)
|
||||||
|
{
|
||||||
|
char line[512];
|
||||||
|
while (fgets(line, sizeof(line), file) != NULL)
|
||||||
|
{
|
||||||
|
char* inc_pos = strstr(line, "#include");
|
||||||
|
if (inc_pos != NULL)
|
||||||
|
{
|
||||||
|
char* quote_start = strchr(inc_pos, '"');
|
||||||
|
if (quote_start != NULL)
|
||||||
|
{
|
||||||
|
quote_start++;
|
||||||
|
char* slash = strchr(quote_start, '/');
|
||||||
|
if (slash == NULL)
|
||||||
|
{
|
||||||
|
slash = strchr(quote_start, '\\');
|
||||||
|
}
|
||||||
|
if (slash != NULL)
|
||||||
|
{
|
||||||
|
size_t layer_len = (size_t)(slash - quote_start);
|
||||||
|
if (layer_len > 0 && layer_len < 64)
|
||||||
|
{
|
||||||
|
char layer_name[64];
|
||||||
|
memcpy(layer_name, quote_start, layer_len);
|
||||||
|
layer_name[layer_len] = '\0';
|
||||||
|
|
||||||
|
char* quote_end = strchr(slash, '"');
|
||||||
|
if (quote_end != NULL && strstr(slash, "_inc.h") != NULL)
|
||||||
|
{
|
||||||
|
bool already_added = false;
|
||||||
|
for (int32 i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (_stricmp(layers[i], layer_name) == 0)
|
||||||
|
{
|
||||||
|
already_added = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!already_added && count < 32)
|
||||||
|
{
|
||||||
|
strncpy_s(layers[count], sizeof(layers[count]), layer_name, _TRUNCATE);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always ensure "core" is present
|
||||||
|
bool has_core = false;
|
||||||
|
for (int32 i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (_stricmp(layers[i], "core") == 0)
|
||||||
|
{
|
||||||
|
has_core = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!has_core && count < 32)
|
||||||
|
{
|
||||||
|
for (int32 i = count; i > 0; --i)
|
||||||
|
{
|
||||||
|
strncpy_s(layers[i], sizeof(layers[i]), layers[i - 1], _TRUNCATE);
|
||||||
|
}
|
||||||
|
strncpy_s(layers[0], sizeof(layers[0]), "core", _TRUNCATE);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Discover any other directories in Juliet/ that have <dir>_inc.h but weren't in appbin_main.c yet
|
||||||
|
WIN32_FIND_DATAA find_data;
|
||||||
|
HANDLE find_handle = FindFirstFileA("Juliet\\*", &find_data);
|
||||||
|
if (find_handle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (strcmp(find_data.cFileName, ".") == 0 || strcmp(find_data.cFileName, "..") == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
if (_stricmp(find_data.cFileName, "src") == 0 ||
|
||||||
|
_stricmp(find_data.cFileName, "include") == 0 ||
|
||||||
|
_stricmp(find_data.cFileName, "appbin") == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool already = false;
|
||||||
|
for (int32 i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (_stricmp(layers[i], find_data.cFileName) == 0)
|
||||||
|
{
|
||||||
|
already = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!already && count < 32)
|
||||||
|
{
|
||||||
|
strncpy_s(layers[count], sizeof(layers[count]), find_data.cFileName, _TRUNCATE);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFileA(find_handle, &find_data));
|
||||||
|
FindClose(find_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 find_layer_index_for_file(const char* file_path, char layers[32][64], int32 layer_count)
|
||||||
|
{
|
||||||
|
Assert(file_path != NULL);
|
||||||
|
|
||||||
|
if (strstr(file_path, "win32/core") != NULL || strstr(file_path, "win32\\core") != NULL)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < layer_count; ++i)
|
||||||
|
{
|
||||||
|
if (_stricmp(layers[i], "core") == 0)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 i = 0; i < layer_count; ++i)
|
||||||
|
{
|
||||||
|
char prefix1[128];
|
||||||
|
char prefix2[128];
|
||||||
|
snprintf(prefix1, sizeof(prefix1), "Juliet/%s/", layers[i]);
|
||||||
|
snprintf(prefix2, sizeof(prefix2), "Juliet\\%s\\", layers[i]);
|
||||||
|
if (_strnicmp(file_path, prefix1, strlen(prefix1)) == 0 ||
|
||||||
|
_strnicmp(file_path, prefix2, strlen(prefix2)) == 0)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_preceding_includes_from_inc_h(const char* layer_name, const char* target_file_path, char* out_flags, size_t out_flags_size)
|
||||||
|
{
|
||||||
|
Assert(layer_name != NULL);
|
||||||
|
Assert(target_file_path != NULL);
|
||||||
|
Assert(out_flags != NULL);
|
||||||
|
|
||||||
|
char inc_h_path[512];
|
||||||
|
snprintf(inc_h_path, sizeof(inc_h_path), "Juliet/%s/%s_inc.h", layer_name, layer_name);
|
||||||
|
|
||||||
|
FILE* file = fopen(inc_h_path, "rb");
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char line[512];
|
||||||
|
while (fgets(line, sizeof(line), file) != NULL)
|
||||||
|
{
|
||||||
|
char* hash = strchr(line, '#');
|
||||||
|
if (hash == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char* inc_pos = strstr(hash, "include");
|
||||||
|
if (inc_pos == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* quote_start = strchr(inc_pos, '"');
|
||||||
|
if (quote_start == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
quote_start++;
|
||||||
|
char* quote_end = strchr(quote_start, '"');
|
||||||
|
if (quote_end == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t inc_file_len = (size_t)(quote_end - quote_start);
|
||||||
|
if (inc_file_len == 0 || inc_file_len >= 256)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char inc_file[256];
|
||||||
|
memcpy(inc_file, quote_start, inc_file_len);
|
||||||
|
inc_file[inc_file_len] = '\0';
|
||||||
|
normalize_path_slashes_forward(inc_file);
|
||||||
|
|
||||||
|
char full_inc_path[512];
|
||||||
|
if (strstr(inc_file, "/") != NULL)
|
||||||
|
{
|
||||||
|
snprintf(full_inc_path, sizeof(full_inc_path), "Juliet/%s", inc_file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(full_inc_path, sizeof(full_inc_path), "Juliet/%s/%s", layer_name, inc_file);
|
||||||
|
}
|
||||||
|
normalize_path_slashes_forward(full_inc_path);
|
||||||
|
|
||||||
|
char expected_suffix[256];
|
||||||
|
snprintf(expected_suffix, sizeof(expected_suffix), "/%s", inc_file);
|
||||||
|
|
||||||
|
if (_stricmp(full_inc_path, target_file_path) == 0 ||
|
||||||
|
str_ends_with_no_case(target_file_path, expected_suffix))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char flag[512];
|
||||||
|
if (strstr(inc_file, "/") != NULL)
|
||||||
|
{
|
||||||
|
snprintf(flag, sizeof(flag), " \"/FI%s\",\n", inc_file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(flag, sizeof(flag), " \"/FI%s/%s\",\n", layer_name, inc_file);
|
||||||
|
}
|
||||||
|
strncat_s(out_flags, out_flags_size, flag, _TRUNCATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
static void generate_compile_commands(void)
|
static void generate_compile_commands(void)
|
||||||
{
|
{
|
||||||
char cwd[512];
|
char cwd[512];
|
||||||
@@ -263,8 +498,10 @@ static void generate_compile_commands(void)
|
|||||||
|
|
||||||
bool is_first = true;
|
bool is_first = true;
|
||||||
|
|
||||||
// 1. Scan new Juliet modules (core, appbin, etc.)
|
char layers[32][64];
|
||||||
// We scan folders directly inside Juliet/, ignoring legacy 'src' and 'include'
|
int32 layer_count = get_layer_order_from_main(layers);
|
||||||
|
|
||||||
|
// 1. Scan new Juliet modules (core, render, ui, appbin, etc.)
|
||||||
WIN32_FIND_DATAA find_data;
|
WIN32_FIND_DATAA find_data;
|
||||||
HANDLE find_handle = FindFirstFileA("Juliet\\*", &find_data);
|
HANDLE find_handle = FindFirstFileA("Juliet\\*", &find_data);
|
||||||
if (find_handle != INVALID_HANDLE_VALUE)
|
if (find_handle != INVALID_HANDLE_VALUE)
|
||||||
@@ -287,21 +524,49 @@ static void generate_compile_commands(void)
|
|||||||
snprintf(module_dir, sizeof(module_dir), "Juliet\\%s", find_data.cFileName);
|
snprintf(module_dir, sizeof(module_dir), "Juliet\\%s", find_data.cFileName);
|
||||||
|
|
||||||
FileList module_files = {0};
|
FileList module_files = {0};
|
||||||
find_files_recursive(module_dir, &module_files, false);
|
find_files_recursive(module_dir, &module_files, true);
|
||||||
|
|
||||||
char module_name[64];
|
|
||||||
strncpy_s(module_name, sizeof(module_name), find_data.cFileName, _TRUNCATE);
|
|
||||||
|
|
||||||
char module_inc_flag[128] = "";
|
|
||||||
char module_inc_disk_path[512];
|
|
||||||
snprintf(module_inc_disk_path, sizeof(module_inc_disk_path), "Juliet\\%s\\%s_inc.h", module_name, module_name);
|
|
||||||
if (_stricmp(module_name, "core") != 0 && GetFileAttributesA(module_inc_disk_path) != INVALID_FILE_ATTRIBUTES)
|
|
||||||
{
|
|
||||||
snprintf(module_inc_flag, sizeof(module_inc_flag), " \"/FI%s/%s_inc.h\",\n", module_name, module_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (FileNode* node = module_files.first; node != NULL; node = node->next)
|
for (FileNode* node = module_files.first; node != NULL; node = node->next)
|
||||||
{
|
{
|
||||||
|
char forced_inc_flags[1024] = "";
|
||||||
|
int32 file_layer_idx = find_layer_index_for_file(node->path, layers, layer_count);
|
||||||
|
|
||||||
|
if (file_layer_idx >= 0 && _stricmp(layers[file_layer_idx], "appbin") != 0)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i <= file_layer_idx; ++i)
|
||||||
|
{
|
||||||
|
if (i < file_layer_idx)
|
||||||
|
{
|
||||||
|
char inc_disk_path[512];
|
||||||
|
snprintf(inc_disk_path, sizeof(inc_disk_path), "Juliet\\%s\\%s_inc.h", layers[i], layers[i]);
|
||||||
|
if (GetFileAttributesA(inc_disk_path) != INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
char flag[128];
|
||||||
|
snprintf(flag, sizeof(flag), " \"/FI%s/%s_inc.h\",\n", layers[i], layers[i]);
|
||||||
|
strncat_s(forced_inc_flags, sizeof(forced_inc_flags), flag, _TRUNCATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (is_c_source_file(node->path))
|
||||||
|
{
|
||||||
|
char inc_disk_path[512];
|
||||||
|
snprintf(inc_disk_path, sizeof(inc_disk_path), "Juliet\\%s\\%s_inc.h", layers[i], layers[i]);
|
||||||
|
if (GetFileAttributesA(inc_disk_path) != INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
char flag[128];
|
||||||
|
snprintf(flag, sizeof(flag), " \"/FI%s/%s_inc.h\",\n", layers[i], layers[i]);
|
||||||
|
strncat_s(forced_inc_flags, sizeof(forced_inc_flags), flag, _TRUNCATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!str_ends_with_no_case(node->path, "_inc.h"))
|
||||||
|
{
|
||||||
|
get_preceding_includes_from_inc_h(layers[i], node->path, forced_inc_flags, sizeof(forced_inc_flags));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* dirs_to_emit[2] = { cwd, (real_cwd[0] && _stricmp(cwd, real_cwd) != 0) ? real_cwd : NULL };
|
const char* dirs_to_emit[2] = { cwd, (real_cwd[0] && _stricmp(cwd, real_cwd) != 0) ? real_cwd : NULL };
|
||||||
|
|
||||||
for (int32 d = 0; d < 2; d++)
|
for (int32 d = 0; d < 2; d++)
|
||||||
@@ -331,16 +596,16 @@ static void generate_compile_commands(void)
|
|||||||
" \"/clang:-std=c11\",\n"
|
" \"/clang:-std=c11\",\n"
|
||||||
" \"/W4\",\n"
|
" \"/W4\",\n"
|
||||||
" \"/Wno-unused-function\",\n"
|
" \"/Wno-unused-function\",\n"
|
||||||
|
" \"/clang:-Wno-initializer-overrides\",\n"
|
||||||
" \"/utf-8\",\n"
|
" \"/utf-8\",\n"
|
||||||
" \"/DBUILD_DEBUG=1\",\n"
|
" \"/DBUILD_DEBUG=1\",\n"
|
||||||
" \"/IJuliet\",\n"
|
" \"/IJuliet\",\n"
|
||||||
" \"/FIcore/core_inc.h\",\n"
|
|
||||||
"%s"
|
"%s"
|
||||||
" \"-c\",\n"
|
" \"-c\",\n"
|
||||||
" \"%s\"\n"
|
" \"%s\"\n"
|
||||||
" ]\n"
|
" ]\n"
|
||||||
" }",
|
" }",
|
||||||
dirs_to_emit[d], full_file_path, module_inc_flag, full_file_path);
|
dirs_to_emit[d], full_file_path, forced_inc_flags, full_file_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user