diff --git a/build.c b/build.c index 06164255..f2ce89d8 100644 --- a/build.c +++ b/build.c @@ -547,7 +547,7 @@ void OnBuild(StringList cli_args) "-Wno-switch-enum -Wno-assign-enum -Wno-switch-default " "-Wno-reserved-identifier -Wno-reserved-macro-identifier " "-Wno-missing-designated-field-initializers " - "-Wno-unsafe-buffer-usage " + "-Wno-unsafe-buffer-usage -Wno-visibility " "-Wno-c11-extensions -Wno-gnu-anonymous-struct -Wno-nested-anon-types "); /* -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-parameter */ diff --git a/src/app/app_core.c b/src/app/app_core.c index 27bbaa8a..3cf4dfd2 100644 --- a/src/app/app_core.c +++ b/src/app/app_core.c @@ -200,13 +200,13 @@ void P_AppStartup(String args_str) String logfile_path = string_cat(temp.arena, logfile_dir, logfile_name); P_MkDir(logfile_dir); - log_startup(logfile_path); - logf_info("Start of logs"); + P_LogStartup(logfile_path); + P_LogInfoF("Start of logs"); arena_temp_end(temp); } - logf_info("App started with args \"%F\" (%F parsed)", FMT_STR(args_str), FMT_UINT(args.count)); + P_LogInfoF("App started with args \"%F\" (%F parsed)", FMT_STR(args_str), FMT_UINT(args.count)); for (struct app_arg *arg = args.first; arg; arg = arg->next) { - logf_info("Parsed arg: key = \"%F\", value = \"%F\"", FMT_STR(arg->key), FMT_STR(arg->value)); + P_LogInfoF("Parsed arg: key = \"%F\", value = \"%F\"", FMT_STR(arg->key), FMT_STR(arg->value)); } #if 0 @@ -216,17 +216,17 @@ void P_AppStartup(String args_str) P_WindowSettings window_settings = ZI; String settings_path = app_write_path_cat(temp.arena, settings_file_name); - logf_info("Looking for settings file \"%F\"", FMT_STR(settings_path)); + P_LogInfoF("Looking for settings file \"%F\"", FMT_STR(settings_path)); if (P_IsFile(settings_path)) { - logf_info("Settings file found"); + P_LogInfoF("Settings file found"); P_File settings_file = P_OpenFileRead(settings_path); String file_data = P_ReadFile(temp.arena, settings_file); P_CloseFIle(settings_file); - logf_info("Deserializing settings file data: %F", FMT_STR(file_data)); + P_LogInfoF("Deserializing settings file data: %F", FMT_STR(file_data)); String error = ZI; P_WindowSettings *res = settings_deserialize(temp.arena, file_data, &error); if (error.len > 0) { - logf_info("Failed to load settings file with error - %F", FMT_STR(error)); + P_LogInfoF("Failed to load settings file with error - %F", FMT_STR(error)); String msg = string_format(temp.arena, LIT( "Failed to loading settings file \"%F\":\n" @@ -239,10 +239,10 @@ void P_AppStartup(String args_str) FMT_STR(error)); P_Panic(msg); } - logf_info("Settings file loaded successfully"); + P_LogInfoF("Settings file loaded successfully"); window_settings = *res; } else { - logf_info("Settings file not found, loading default"); + P_LogInfoF("Settings file not found, loading default"); window_settings = default_window_settings(window); } string_copy_to_string(STRING_FROM_ARRAY(window_settings.title), LIT(WINDOW_TITLE)); @@ -285,13 +285,13 @@ void P_AppStartup(String args_str) P_WindowSettings settings = P_GetWindowSettings(window); String str = settings_serialize(temp.arena, &settings); - logf_info("Serialized window settings: %F", FMT_STR(str)); + P_LogInfoF("Serialized window settings: %F", FMT_STR(str)); - logf_info("Writing settings file to path \"%F\"", FMT_STR(window_settings_path)); + P_LogInfoF("Writing settings file to path \"%F\"", FMT_STR(window_settings_path)); P_File settings_file = P_OpenFileWrite(window_settings_path); P_WriteFile(settings_file, str); P_CloseFIle(settings_file); - logf_info("Finished writing settings file"); + P_LogInfoF("Finished writing settings file"); arena_temp_end(temp); } @@ -301,6 +301,6 @@ void P_AppStartup(String args_str) P_ReleaseWindow(window); #endif - //logf_info("Program exited normally"); + //P_LogInfoF("Program exited normally"); scratch_end(scratch); } diff --git a/src/ase/ase_core.h b/src/ase/ase_core.h index 54eb607d..f0051dee 100644 --- a/src/ase/ase_core.h +++ b/src/ase/ase_core.h @@ -1,18 +1,15 @@ -typedef struct Ase_Error Ase_Error; -struct Ase_Error { +Struct(Ase_Error) { String msg; Ase_Error *next; }; -typedef struct Ase_ErrorList Ase_ErrorList; -struct Ase_ErrorList { +Struct(Ase_ErrorList) { u64 count; Ase_Error *first; Ase_Error *last; }; -typedef struct Ase_Slice Ase_Slice; -struct Ase_Slice { +Struct(Ase_Slice) { u32 start; i32 x1; i32 y1; @@ -21,24 +18,21 @@ struct Ase_Slice { Ase_Slice *next; }; -typedef struct Ase_SliceKey Ase_SliceKey; -struct Ase_SliceKey { +Struct(Ase_SliceKey) { String name; u32 num_slices; Ase_Slice *slice_head; Ase_SliceKey *next; }; -typedef struct Ase_Span Ase_Span; -struct Ase_Span { +Struct(Ase_Span) { String name; u32 start; u32 end; Ase_Span *next; }; -typedef struct Ase_Frame Ase_Frame; -struct Ase_Frame { +Struct(Ase_Frame) { u32 index; u32 x1; u32 y1; @@ -48,15 +42,13 @@ struct Ase_Frame { Ase_Frame *next; }; -typedef struct Ase_DecodedImage Ase_DecodedImage; -struct Ase_DecodedImage { +Struct(Ase_DecodedImage) { ImageDataRgba image; Ase_ErrorList errors; b32 success; }; -typedef struct Ase_DecodedSheet Ase_DecodedSheet; -struct Ase_DecodedSheet { +Struct(Ase_DecodedSheet) { V2 image_size; V2 frame_size; u32 num_frames; diff --git a/src/asset_cache/asset_cache_core.c b/src/asset_cache/asset_cache_core.c index 66ebcfc7..33703213 100644 --- a/src/asset_cache/asset_cache_core.c +++ b/src/asset_cache/asset_cache_core.c @@ -40,7 +40,7 @@ AC_StartupReceipt asset_cache_startup(void) INTERNAL void refresh_dbg_table(void) { #if RTC - P_Lock lock = snc_lock_e(&G.dbg_table_mutex); + P_Lock lock = P_LockE(&G.dbg_table_mutex); MEMZERO_ARRAY(G.dbg_table); G.dbg_table_count = 0; for (u64 i = 0; i < countof(G.lookup); ++i) { @@ -49,7 +49,7 @@ INTERNAL void refresh_dbg_table(void) G.dbg_table[G.dbg_table_count++] = asset; } } - snc_unlock(&lock); + P_Unlock(&lock); #endif } @@ -57,7 +57,7 @@ INTERNAL void refresh_dbg_table(void) * Check returned slot->hash != 0 for presence. */ INTERNAL AC_Asset *asset_cache_get_slot_locked(P_Lock *lock, String key, u64 hash) { - snc_assert_locked_e_or_s(lock, &G.lookup_mutex); + P_AssertLockedES(lock, &G.lookup_mutex); (UNUSED)lock; u64 index = hash % countof(G.lookup); @@ -101,9 +101,9 @@ AC_Asset *asset_cache_touch(String key, u64 hash, b32 *is_first_touch) /* Lookup */ { - P_Lock lock = snc_lock_s(&G.lookup_mutex); + P_Lock lock = P_LockS(&G.lookup_mutex); asset = asset_cache_get_slot_locked(&lock, key, hash); - snc_unlock(&lock); + P_Unlock(&lock); } /* Insert if not found */ @@ -112,7 +112,7 @@ AC_Asset *asset_cache_touch(String key, u64 hash, b32 *is_first_touch) *is_first_touch = 0; } } else { - P_Lock lock = snc_lock_e(&G.lookup_mutex); + P_Lock lock = P_LockE(&G.lookup_mutex); /* Re-check asset presence in case it was inserted since lock */ asset = asset_cache_get_slot_locked(&lock, key, hash); @@ -129,13 +129,13 @@ AC_Asset *asset_cache_touch(String key, u64 hash, b32 *is_first_touch) asset_cache_store_close(&store); } /* Initialize asset data */ - logf_info("Inserting asset cache entry for \"%F\"", FMT_STR(key)); + P_LogInfoF("Inserting asset cache entry for \"%F\"", FMT_STR(key)); *asset = (AC_Asset) { .status = ASSET_STATUS_UNINITIALIZED, .hash = hash, .key = key_stored }; - snc_counter_add(&asset->counter, 1); + P_CounterAdd(&asset->counter, 1); if (is_first_touch) { *is_first_touch = 1; } @@ -144,7 +144,7 @@ AC_Asset *asset_cache_touch(String key, u64 hash, b32 *is_first_touch) refresh_dbg_table(); } - snc_unlock(&lock); + P_Unlock(&lock); } return asset; @@ -165,7 +165,7 @@ void asset_cache_mark_ready(AC_Asset *asset, void *store_data) { asset->store_data = store_data; asset->status = ASSET_STATUS_READY; - snc_counter_add(&asset->counter, -1); + P_CounterAdd(&asset->counter, -1); } /* ========================== * @@ -174,7 +174,7 @@ void asset_cache_mark_ready(AC_Asset *asset, void *store_data) void asset_cache_wait(AC_Asset *asset) { - snc_counter_wait(&asset->counter); + P_WaitOnCounter(&asset->counter); } /* ========================== * @@ -196,7 +196,7 @@ void *asset_cache_get_store_data(AC_Asset *asset) /* Asset store should be opened to allocate memory to the store arena */ AC_Store asset_cache_store_open(void) { - P_Lock lock = snc_lock_e(&G.store_mutex); + P_Lock lock = P_LockE(&G.store_mutex); AC_Store store = { .lock = lock, .arena = G.store_arena @@ -206,5 +206,5 @@ AC_Store asset_cache_store_open(void) void asset_cache_store_close(AC_Store *store) { - snc_unlock(&store->lock); + P_Unlock(&store->lock); } diff --git a/src/asset_cache/asset_cache_core.h b/src/asset_cache/asset_cache_core.h index b94a9217..f21f9a46 100644 --- a/src/asset_cache/asset_cache_core.h +++ b/src/asset_cache/asset_cache_core.h @@ -1,14 +1,13 @@ -typedef enum AC_Status { +typedef i32 AC_Status; enum { ASSET_STATUS_NONE, ASSET_STATUS_UNINITIALIZED, /* TODO: ASSET_STATUS_QUEUED? */ ASSET_STATUS_LOADING, ASSET_STATUS_READY -} AC_Status; +}; -typedef struct AC_Asset AC_Asset; -struct AC_Asset { +Struct(AC_Asset) { /* Managed via asset_cache_touch */ u64 hash; String key; @@ -22,16 +21,14 @@ struct AC_Asset { void *store_data; }; -typedef struct AC_Store AC_Store; -struct AC_Store { +Struct(AC_Store) { Arena *arena; /* Internal */ P_Lock lock; }; -typedef struct AC_StartupReceipt AC_StartupReceipt; -struct AC_StartupReceipt { i32 _; }; +Struct(AC_StartupReceipt) { i32 _; }; AC_StartupReceipt asset_cache_startup(void); AC_Asset *asset_cache_touch(String key, u64 hash, b32 *is_first_touch); diff --git a/src/base/base_arena.h b/src/base/base_arena.h index 008ac4c2..78b3d3d3 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -18,8 +18,7 @@ * Equivalent to arena_push but without actually allocating anything or modifying the arena. */ #define arena_push_dry(a, type) (type *)(_arena_push_dry((a), alignof(type))) -typedef struct Arena Arena; -struct Arena { +Struct(Arena) { u64 pos; u64 committed; u64 reserved; @@ -28,8 +27,7 @@ struct Arena { #endif }; -typedef struct TempArena TempArena; -struct TempArena { +Struct(TempArena) { Arena *arena; u64 start_pos; @@ -131,13 +129,11 @@ INLINE void *_arena_push_dry(Arena *arena, u64 align) #define SCRATCH_ARENAS_PER_CTX 2 -typedef struct ScratchCtx ScratchCtx; -struct ScratchCtx { +Struct(ScratchCtx) { Arena *arenas[SCRATCH_ARENAS_PER_CTX]; }; -typedef struct SharedScratchCtx SharedScratchCtx; -struct SharedScratchCtx { +Struct(SharedScratchCtx) { ScratchCtx scratch_contexts[MAX_FIBERS]; }; diff --git a/src/base/base_atomic.h b/src/base/base_atomic.h index 298e11ca..3e218fc4 100644 --- a/src/base/base_atomic.h +++ b/src/base/base_atomic.h @@ -3,24 +3,20 @@ * ========================== */ /* NOTE: Must be aligned to 32 bit boundary by user */ -typedef struct Atomic8 Atomic8; -struct Atomic8 { +Struct(Atomic8) { volatile i8 _v; }; /* NOTE: Must be aligned to 32 bit boundary by user */ -typedef struct Atomic16 Atomic16; -struct Atomic16 { +Struct(Atomic16) { volatile i16 _v; }; -typedef struct Atomic32 Atomic32; -struct Atomic32 { +Struct(Atomic32) { volatile i32 _v; }; -typedef struct Atomic64 Atomic64; -struct Atomic64 { +Struct(Atomic64) { volatile i64 _v; }; @@ -28,29 +24,25 @@ struct Atomic64 { * Cache-line isolated atomic types * ========================== */ -typedef struct Atomic8Padded Atomic8Padded; -struct alignas(64) Atomic8Padded { +AlignedStruct(Atomic8Padded, 64) { Atomic8 v; u8 _pad[60]; }; STATIC_ASSERT(sizeof(Atomic8Padded) == 64 && alignof(Atomic8Padded) == 64); -typedef struct Atomic16Padded Atomic16Padded; -struct alignas(64) Atomic16Padded { +AlignedStruct(Atomic16Padded, 64) { Atomic16 v; u8 _pad[60]; }; STATIC_ASSERT(sizeof(Atomic16Padded) == 64 && alignof(Atomic16Padded) == 64); -typedef struct Atomic32Padded Atomic32Padded; -struct alignas(64) Atomic32Padded { +AlignedStruct(Atomic32Padded, 64) { Atomic32 v; u8 _pad[60]; }; STATIC_ASSERT(sizeof(Atomic32Padded) == 64 && alignof(Atomic32Padded) == 64); -typedef struct Atomic64Padded Atomic64Padded; -struct alignas(64) Atomic64Padded { +AlignedStruct(Atomic64Padded, 64) { Atomic64 v; u8 _pad[56]; }; diff --git a/src/base/base_bitbuff.h b/src/base/base_bitbuff.h index ceb4cbd8..658a4670 100644 --- a/src/base/base_bitbuff.h +++ b/src/base/base_bitbuff.h @@ -2,8 +2,7 @@ * Bitbuff * ========================== */ -typedef struct Bitbuff Bitbuff; -struct Bitbuff { +Struct(Bitbuff) { b32 is_backed_by_arena; /* If `is_arena_bitbuff` is 1, this dynamically-sized arena will be used for reading & writing (meaning writing cannot overflow) */ @@ -23,8 +22,7 @@ Bitbuff bitbuff_from_string(String s); * ========================== */ /* NOTE: base_len is not stored in writer (as it is in the reader) since a dynamic arena-backed bitbuff could grow meaning len needs to be re-checked */ -typedef struct BitbuffWriter BitbuffWriter; -struct BitbuffWriter { +Struct(BitbuffWriter) { b32 overflowed; Bitbuff *bb; u8 *base; @@ -72,8 +70,7 @@ void bw_write_dbg_marker(BitbuffWriter *bw, String name); * Reader * ========================== */ -typedef struct BitbuffReader BitbuffReader; -struct BitbuffReader { +Struct(BitbuffReader) { b32 overflowed; u64 base_len; u8 *base; diff --git a/src/base/base_buddy.h b/src/base/base_buddy.h index d9206238..a8496dbe 100644 --- a/src/base/base_buddy.h +++ b/src/base/base_buddy.h @@ -1,8 +1,6 @@ -typedef struct BuddyLevel BuddyLevel; -typedef struct BuddyBlock BuddyBlock; -struct BuddyBlock { +Struct(BuddyBlock) { b32 is_used; - BuddyLevel *level; + struct BuddyLevel *level; BuddyBlock *parent; BuddyBlock *sibling; @@ -13,18 +11,15 @@ struct BuddyBlock { u8 *memory; }; -typedef struct BuddyCtx BuddyCtx; -typedef struct BuddyLevel BuddyLevel; -struct BuddyLevel { - BuddyCtx *ctx; +Struct(BuddyLevel) { + struct BuddyCtx *ctx; b32 backed; /* Signals whether this level is backed by memory in the ctx arena */ u32 tier; u64 size; BuddyBlock *first_unused_block; }; -typedef struct BuddyCtx BuddyCtx; -struct BuddyCtx { +Struct(BuddyCtx) { Arena *meta_arena; Arena *data_arena; BuddyLevel *levels; diff --git a/src/base/base_core.h b/src/base/base_core.h index 27218ed8..279459fb 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -365,19 +365,22 @@ GLOBAL const f64 *_f64_nan = (f64 *)&_f64_nan_u64; #define F32_IS_NAN(x) (x != x) #define F64_IS_NAN(x) (x != x) +#define Struct(name) typedef struct name name; struct name +#define AlignedStruct(name, n) typedef struct name name; struct alignas(n) name + /* ========================== * * Common structs * ========================== */ -typedef struct ImageDataRgba ImageDataRgba; -struct ImageDataRgba { +Struct(ImageDataRgba) +{ u32 width; u32 height; u32 *pixels; /* Array of [width * height] pixels */ }; -typedef struct PcmData PcmData; -struct PcmData { +Struct(PcmData) +{ u64 count; i16 *samples; }; diff --git a/src/base/base_incbin.h b/src/base/base_incbin.h index 74479b5d..38fd22eb 100644 --- a/src/base/base_incbin.h +++ b/src/base/base_incbin.h @@ -18,8 +18,7 @@ enum _incbin_state { INCBIN_STATE_SEARCHED }; -typedef struct _IncbinRcResource _IncbinRcResource; -struct _IncbinRcResource { +Struct(_IncbinRcResource) { Atomic32 state; String rc_name; String data; diff --git a/src/base/base_math.h b/src/base/base_math.h index 4db71023..a5a9f303 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -9,62 +9,52 @@ #define V2FromXY(x, y) CPPCOMPAT_INITLIST_TYPE(V2) { (x), (y) } #define V2FromV2i32(v) V2FromXY((v).x, (v).y) -typedef struct V2 V2; -struct V2 { +Struct(V2) { f32 x, y; }; -typedef struct V2Array V2Array; -struct V2Array { +Struct(V2Array) { V2 *points; u64 count; }; #define V3FromXYZ(x, y, z) ((V3) { (x), (y), (z) }) -typedef struct V3 V3; -struct V3 { +Struct(V3) { f32 x, y, z; }; -typedef struct V3Array V3Array; -struct V3Array { +Struct(V3Array) { V3 *points; u64 count; }; #define V4FromXYZW(x, y, z, w) ((V4) { (x), (y), (z), (w) }) -typedef struct V4 V4; -struct V4 { +Struct(V4) { f32 x, y, z, w; }; -typedef struct V4Array V4Array; -struct V4Array { +Struct(V4Array) { V4 *points; u64 count; }; #define V2i32FromXY(x, y) CPPCOMPAT_INITLIST_TYPE(V2i32) { (x), (y) } -typedef struct V2i32 V2i32; -struct V2i32 { +Struct(V2i32) { i32 x, y; }; #define V3i32FromXYZ(x, y, z) CPPCOMPAT_INITLIST_TYPE(V3i32) { (x), (y), (z) } -typedef struct V3i32 V3i32; -struct V3i32 { +Struct(V3i32) { i32 x, y, z; }; -typedef struct Xform Xform; -struct Xform { +Struct(Xform) { V2 bx; /* X basis vector (x axis) */ V2 by; /* Y basis vector (y axis)*/ V2 og; /* Translation vector (origin) */ }; -typedef struct Mat4x4 Mat4x4; -struct Mat4x4 { +Struct(Mat4x4) { union { struct { V4 bx, by, bz, bw; }; f32 e[4][4]; @@ -73,8 +63,7 @@ struct Mat4x4 { #define RECT(_x, _y, _width, _height) (Rect) { .x = (_x), .y = (_y), .width = (_width), .height = (_height) } #define RECT_FROM_V2(_pos, _size) (Rect) { .pos = (_pos), .size = (_size) } -typedef struct Rect Rect; -struct Rect { +Struct(Rect) { union { struct { f32 x, y, width, height; }; struct { V2 pos, size; }; @@ -83,22 +72,19 @@ struct Rect { INLINE b32 rect_eq(Rect r1, Rect r2) { return r1.x == r2.x && r1.y == r2.y && r1.width == r2.width && r1.height == r2.height; } -typedef struct Aabb Aabb; -struct Aabb { +Struct(Aabb) { V2 p0, p1; }; /* Values expected to be normalized 0.0 -> 1.0 */ #define CLIP_ALL ((ClipRect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } }) -typedef struct ClipRect ClipRect; -struct ClipRect { +Struct(ClipRect) { V2 p0, p1; }; #define QUAD_UNIT_SQUARE (Quad) { .p0 = V2FromXY(0, 0), .p1 = V2FromXY(0, 1), .p2 = V2FromXY(1, 1), .p3 = V2FromXY(1, 0) } #define QUAD_UNIT_SQUARE_CENTERED (Quad) { .p0 = V2FromXY(-0.5f, -0.5f), .p1 = V2FromXY(0.5f, -0.5f), .p2 = V2FromXY(0.5f, 0.5f), .p3 = V2FromXY(-0.5f, 0.5f) } -typedef struct Quad Quad; -struct Quad { +Struct(Quad) { union { struct { V2 p0, p1, p2, p3; }; struct { V2 e[4]; }; @@ -107,8 +93,7 @@ struct Quad { /* (T)ranslation, (R)otation, (S)cale */ #define MakeTrs(...) ((Trs) { .t = V2FromXY(0,0), .s = V2FromXY(1, 1), .r = 0, __VA_ARGS__ }) -typedef struct Trs Trs; -struct Trs { +Struct(Trs) { V2 t; V2 s; f32 r; @@ -1397,8 +1382,7 @@ INLINE V2 math_poly_center(V2Array a) * ========================== */ /* https://box2d.org/files/ErinCatto_SoftConstraints_GDC2011.pdf */ -typedef struct SoftSpring SoftSpring; -struct SoftSpring { +Struct(SoftSpring) { f32 bias_rate; f32 mass_scale; f32 impulse_scale; diff --git a/src/base/base_rand.h b/src/base/base_rand.h index ae52ae91..29b4e5d2 100644 --- a/src/base/base_rand.h +++ b/src/base/base_rand.h @@ -1,5 +1,4 @@ -typedef struct RandState RandState; -struct RandState { +Struct(RandState) { /* If a state's seed == 0 upon a call to a related function, it will be initialized using platform's true rng source */ u64 seed; u64 counter; diff --git a/src/base/base_string.h b/src/base/base_string.h index 9b18378d..25cc0147 100644 --- a/src/base/base_string.h +++ b/src/base/base_string.h @@ -1,23 +1,19 @@ -typedef struct String String; -struct String { +Struct(String) { u64 len; u8 *text; }; -typedef struct String16 String16; -struct String16 { +Struct(String16) { u64 len; u16 *text; }; -typedef struct String32 String32; -struct String32 { +Struct(String32) { u64 len; u32 *text; }; -typedef struct StringArray StringArray; -struct StringArray { +Struct(StringArray) { u64 count; String *strings; }; diff --git a/src/base/base_uid.h b/src/base/base_uid.h index 59ec67af..b0c4d507 100644 --- a/src/base/base_uid.h +++ b/src/base/base_uid.h @@ -1,6 +1,5 @@ #define MakeUID(hi64, lo64) ((UID) { .hi = (hi64), .lo = (lo64) }) -typedef struct UID UID; -struct UID { +Struct(UID) { u64 hi; u64 lo; }; diff --git a/src/base/base_uni.h b/src/base/base_uni.h index 1fd17cf6..3b7baf66 100644 --- a/src/base/base_uni.h +++ b/src/base/base_uni.h @@ -2,14 +2,12 @@ * utf8 * ========================== */ -typedef struct Utf8DecodeResult Utf8DecodeResult; -struct Utf8DecodeResult { +Struct(Utf8DecodeResult) { u32 advance8; u32 codepoint; }; -typedef struct Utf8EncodeResult Utf8EncodeResult; -struct Utf8EncodeResult { +Struct(Utf8EncodeResult) { u32 count8; u8 chars8[4]; }; @@ -21,14 +19,12 @@ Utf8EncodeResult uni_encode_utf8(u32 codepoint); * utf16 * ========================== */ -typedef struct Utf16DecodeResult Utf16DecodeResult; -struct Utf16DecodeResult { +Struct(Utf16DecodeResult) { u32 advance16; u32 codepoint; }; -typedef struct Utf16EncodeResult Utf16EncodeResult; -struct Utf16EncodeResult { +Struct(Utf16EncodeResult) { u32 count16; u16 chars16[2]; }; @@ -42,14 +38,12 @@ b32 uni_is_utf16_low_surrogate(u16 c); * utf32 * ========================== */ -typedef struct Utf32DecodeResult Utf32DecodeResult; -struct Utf32DecodeResult { +Struct(Utf32DecodeResult) { u32 advance32; u32 codepoint; }; -typedef struct Utf32EncodeResult Utf32EncodeResult; -struct Utf32EncodeResult { +Struct(Utf32EncodeResult) { u32 chars32; }; diff --git a/src/base/base_util.h b/src/base/base_util.h index 2ca3a926..a3a798b9 100644 --- a/src/base/base_util.h +++ b/src/base/base_util.h @@ -94,8 +94,7 @@ INLINE void merge_sort(void *items, u64 item_count, u64 item_size, sort_compare_ * Simple chaining hash -> 64 bit value table for generic use * ========================== */ -typedef struct DictEntry DictEntry; -struct DictEntry { +Struct(DictEntry) { u64 hash; u64 value; DictEntry *prev_in_bin; @@ -104,14 +103,12 @@ struct DictEntry { DictEntry *next; }; -typedef struct DictBin DictBin; -struct DictBin { +Struct(DictBin) { DictEntry *first; DictEntry *last; }; -typedef struct Dict Dict; -struct Dict { +Struct(Dict) { u64 bins_count; DictBin *bins; DictEntry *first_free; diff --git a/src/collider/collider_core.h b/src/collider/collider_core.h index d3bd29a2..5901a90d 100644 --- a/src/collider/collider_core.h +++ b/src/collider/collider_core.h @@ -1,50 +1,42 @@ -typedef struct CLD_Shape CLD_Shape; -struct CLD_Shape { +Struct(CLD_Shape) { V2 points[8]; u32 count; f32 radius; }; -typedef struct CLD_SupportPoint CLD_SupportPoint; -struct CLD_SupportPoint { +Struct(CLD_SupportPoint) { V2 p; u32 i; /* Index of original point in shape */ }; -typedef struct CLD_MenkowskiPoint CLD_MenkowskiPoint; -struct CLD_MenkowskiPoint { +Struct(CLD_MenkowskiPoint) { V2 p; /* Menkowski difference point */ CLD_SupportPoint s0; /* Support point of first shape in dir */ CLD_SupportPoint s1; /* Support point of second shape in -dir */ }; -typedef struct CLD_MenkowskiSimplex CLD_MenkowskiSimplex; -struct CLD_MenkowskiSimplex { +Struct(CLD_MenkowskiSimplex) { u32 len; CLD_MenkowskiPoint a, b, c; }; -typedef struct CLD_MenkowskiFeature CLD_MenkowskiFeature; -struct CLD_MenkowskiFeature { +Struct(CLD_MenkowskiFeature) { u32 len; CLD_MenkowskiPoint a, b; }; -typedef struct CLD_CollisionPoint CLD_CollisionPoint; -struct CLD_CollisionPoint { +Struct(CLD_CollisionPoint) { V2 point; f32 separation; u32 id; /* Based on polygon edge-to-edge */ }; -typedef struct CLD_Prototype CLD_Prototype; -struct CLD_Prototype { +Struct(CLD_Prototype) { V2 points[64]; u32 len; }; -typedef struct CLD_CollisionResult CLD_CollisionResult; -struct CLD_CollisionResult { +Struct(CLD_CollisionResult) { V2 normal; CLD_CollisionPoint points[2]; u32 num_points; @@ -59,8 +51,7 @@ struct CLD_CollisionResult { V2 a0_clipped, b0_clipped, a1_clipped, b1_clipped; }; -typedef struct CLD_ClosestResult CLD_ClosestResult; -struct CLD_ClosestResult { +Struct(CLD_ClosestResult) { V2 p0, p1; b32 colliding; diff --git a/src/draw/draw_core.h b/src/draw/draw_core.h index e21692c4..8c04ae51 100644 --- a/src/draw/draw_core.h +++ b/src/draw/draw_core.h @@ -1,5 +1,4 @@ -typedef struct D_StartupReceipt D_StartupReceipt; -struct D_StartupReceipt { i32 _; }; +Struct(D_StartupReceipt) { i32 _; }; D_StartupReceipt draw_startup(F_StartupReceipt *font_sr); /* ========================== * @@ -12,8 +11,7 @@ D_StartupReceipt draw_startup(F_StartupReceipt *font_sr); __VA_ARGS__ \ }) -typedef struct D_MaterialParams D_MaterialParams; -struct D_MaterialParams { +Struct(D_MaterialParams) { Xform xf; G_Resource *texture; ClipRect clip; @@ -74,8 +72,7 @@ void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 lin __VA_ARGS__ \ }) -typedef struct D_UiRectParams D_UiRectParams; -struct D_UiRectParams { +Struct(D_UiRectParams) { Xform xf; G_Resource *texture; ClipRect clip; @@ -98,29 +95,28 @@ void draw_ui_rect(G_RenderSig *sig, D_UiRectParams params); }) /* How is text aligned within its area */ -typedef enum D_TextAlignment { +typedef i32 D_TextAlignment; enum { DRAW_TEXT_ALIGNMENT_LEFT, /* Default */ DRAW_TEXT_ALIGNMENT_CENTER, DRAW_TEXT_ALIGNMENT_RIGHT -} D_TextAlignment; +}; /* How does the specified text position relate to the text area. * E.g. BOTTOM & RIGHT means the bottom-right of the text area will snap to * the specified position. */ -typedef enum D_TextOffsetX { +typedef i32 D_TextOffsetX; enum { DRAW_TEXT_OFFSET_X_LEFT, /* Default */ DRAW_TEXT_OFFSET_X_CENTER, DRAW_TEXT_OFFSET_X_RIGHT -} D_TextOffsetX; +}; -typedef enum D_TextOffsetY { +typedef i32 D_TextOffsetY; enum { DRAW_TEXT_OFFSET_Y_TOP, /* Default */ DRAW_TEXT_OFFSET_Y_CENTER, DRAW_TEXT_OFFSET_Y_BOTTOM -} D_TextOffsetY; +}; -typedef struct D_TextParams D_TextParams; -struct D_TextParams { +Struct(D_TextParams) { F_Font *font; V2 pos; f32 scale; diff --git a/src/dxc/dxc_core.h b/src/dxc/dxc_core.h index 34069852..83290237 100644 --- a/src/dxc/dxc_core.h +++ b/src/dxc/dxc_core.h @@ -1,5 +1,4 @@ -typedef struct DXC_Result DXC_Result; -struct DXC_Result { +Struct(DXC_Result) { String dxc; String errors; b32 success; diff --git a/src/dxc/dxc_core_win32.cpp b/src/dxc/dxc_core_win32.cpp index 45b37357..478481ca 100644 --- a/src/dxc/dxc_core_win32.cpp +++ b/src/dxc/dxc_core_win32.cpp @@ -21,8 +21,6 @@ DXC_Result dxc_compile(Arena *arena, String shader_source, i32 num_args, String #pragma warning(push, 0) # define WIN32_LEAN_AND_MEAN # define UNICODE -# define NTDDI_WIN11_DT 0x0C0A0000 -# define NTDDI_VERSION 0x0A000000 # include # include # include diff --git a/src/editor_include.h b/src/editor_include.h new file mode 100644 index 00000000..d4479c1b --- /dev/null +++ b/src/editor_include.h @@ -0,0 +1,29 @@ +// This is an auto generated file containing all includes necessary to assist in editor parsing + +#include "app/app.h" +#include "ase/ase.h" +#include "asset_cache/asset_cache.h" +#include "base/base.h" +#include "collider/collider.h" +#include "draw/draw.h" +#include "dxc/dxc.h" +#include "font/font.h" +#include "gp/gp.h" +#include "inc/inc.h" +#include "json/json.h" +#include "kernel/kernel.h" +#include "mixer/mixer.h" +#include "mp3/mp3.h" +#include "net/net.h" +#include "platform/platform.h" +#include "playback/playback.h" +#include "prof/prof.h" +#include "resource/resource.h" +#include "settings/settings.h" +#include "sim/sim.h" +#include "sound/sound.h" +#include "sprite/sprite.h" +#include "tar/tar.h" +#include "ttf/ttf.h" +#include "user/user.h" +#include "watch/watch.h" \ No newline at end of file diff --git a/src/font/font_core.c b/src/font/font_core.c index 3440196c..98055d97 100644 --- a/src/font/font_core.c +++ b/src/font/font_core.c @@ -48,24 +48,24 @@ INTERNAL struct font_task_params *font_task_params_alloc(void) { struct font_task_params *p = 0; { - P_Lock lock = snc_lock_e(&G.params.mutex); + P_Lock lock = P_LockE(&G.params.mutex); if (G.params.head_free) { p = G.params.head_free; G.params.head_free = p->next_free; } else { p = arena_push(G.params.arena, struct font_task_params); } - snc_unlock(&lock); + P_Unlock(&lock); } return p; } INTERNAL void font_task_params_release(struct font_task_params *p) { - P_Lock lock = snc_lock_e(&G.params.mutex); + P_Lock lock = P_LockE(&G.params.mutex); p->next_free = G.params.head_free; G.params.head_free = p; - snc_unlock(&lock); + P_Unlock(&lock); } /* ========================== * @@ -82,7 +82,7 @@ INTERNAL P_JobDef(font_load_asset_job, job) f32 point_size = params->point_size; AC_Asset *asset = params->asset; - logf_info("Loading font \"%F\" (point size %F)", FMT_STR(path), FMT_FLOAT((f64)point_size)); + P_LogInfoF("Loading font \"%F\" (point size %F)", FMT_STR(path), FMT_FLOAT((f64)point_size)); i64 start_ns = P_TimeNs(); ASSERT(string_ends_with(path, LIT(".ttf"))); @@ -138,7 +138,7 @@ INTERNAL P_JobDef(font_load_asset_job, job) font_task_params_release(params); - logf_success("Loaded font \"%F\" (point size %F) in %F seconds", FMT_STR(path), FMT_FLOAT((f64)point_size), FMT_FLOAT(SECONDS_FROM_NS(P_TimeNs() - start_ns))); + P_LogSuccessF("Loaded font \"%F\" (point size %F) in %F seconds", FMT_STR(path), FMT_FLOAT((f64)point_size), FMT_FLOAT(SECONDS_FROM_NS(P_TimeNs() - start_ns))); asset_cache_mark_ready(asset, font); scratch_end(scratch); diff --git a/src/font/font_core.h b/src/font/font_core.h index 7920e8d3..3b77f3e9 100644 --- a/src/font/font_core.h +++ b/src/font/font_core.h @@ -1,5 +1,4 @@ -typedef struct F_Glyph F_Glyph; -struct F_Glyph { +Struct(F_Glyph) { f32 off_x; f32 off_y; i32 advance; @@ -8,8 +7,7 @@ struct F_Glyph { Rect atlas_rect; }; -typedef struct F_Font F_Font; -struct F_Font { +Struct(F_Font) { G_Resource *texture; u32 image_width; u32 image_height; @@ -19,8 +17,7 @@ struct F_Font { u16 *lookup; }; -typedef struct F_StartupReceipt F_StartupReceipt; -struct F_StartupReceipt { i32 _; }; +Struct(F_StartupReceipt) { i32 _; }; F_StartupReceipt font_startup(AC_StartupReceipt *asset_cache_sr, TTF_StartupReceipt *ttf_sr); AC_Asset *font_load_asset(String path, f32 point_size, b32 wait); diff --git a/src/gp/gp_core.h b/src/gp/gp_core.h index 0cc7f222..edbac3ea 100644 --- a/src/gp/gp_core.h +++ b/src/gp/gp_core.h @@ -1,56 +1,21 @@ -typedef struct G_Indices G_Indices; -struct G_Indices { +//////////////////////////////// +//~ Opaque types + +Struct(G_Resource); +Struct(G_RenderSig); +Struct(G_Swapchain); + +//////////////////////////////// +//~ Render + +Struct(G_Indices) +{ u32 count; u32 *indices; }; -/* ========================== * - * Startup - * ========================== */ - -void gp_startup(void); - -/* ========================== * - * Resource - * ========================== */ - -typedef struct G_Resource G_Resource; - -/* NOTE: Internally, the layer will make sure to not release any resources - * until after any in-flight GPU runs finish using them. However, it is up to - * the caller to make sure the released resources aren't then referenced in - * any runs - */ -void gp_resource_release(G_Resource *resource); - -/* ========================== * - * Texture - * ========================== */ - -typedef enum G_TextureFormat { - GP_TEXTURE_FORMAT_NONE, - GP_TEXTURE_FORMAT_R8_UNORM, - GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, - GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, - GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT, - - NUM_GP_TEXTURE_FORMATS -} G_TextureFormat; - -typedef enum G_TextureFlag { - GP_TEXTURE_FLAG_NONE = (0), - GP_TEXTURE_FLAG_TARGETABLE = (1 << 0) -} G_TextureFlag; - -G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, V2i32 size, void *initial_data); - -V2i32 gp_texture_get_size(G_Resource *texture); - -/* ========================== * - * Render - * ========================== */ - -typedef enum G_RenderCmdKind { +typedef i32 G_RenderCmdKind; enum +{ GP_RENDER_CMD_KIND_NONE, GP_RENDER_CMD_KIND_DRAW_MATERIAL, GP_RENDER_CMD_KIND_DRAW_UI_RECT, @@ -58,13 +23,15 @@ typedef enum G_RenderCmdKind { GP_RENDER_CMD_KIND_PUSH_GRID, NUM_GP_RENDER_CMD_KINDS -} G_RenderCmdKind; +}; -typedef struct G_RenderCmdDesc G_RenderCmdDesc; -struct G_RenderCmdDesc { +Struct(G_RenderCmdDesc) +{ G_RenderCmdKind kind; - union { - struct { + union + { + struct + { Xform xf; G_Resource *texture; ClipRect clip; @@ -73,18 +40,21 @@ struct G_RenderCmdDesc { V3 light_emittance; u32 grid_cmd_id; } material; - struct { + struct + { Xform xf; G_Resource *texture; ClipRect clip; u32 tint; } ui_rect; - struct { + struct + { V2Array vertices; G_Indices indices; u32 color; } ui_shape; - struct { + struct + { f32 line_thickness; f32 line_spacing; V2 offset; @@ -97,8 +67,8 @@ struct G_RenderCmdDesc { }; }; -typedef struct G_RenderParams G_RenderParams; -struct G_RenderParams { +Struct(G_RenderParams) +{ V2i32 ui_size; V2i32 render_size; Xform world_to_render_xf; @@ -106,7 +76,61 @@ struct G_RenderParams { b32 effects_disabled; }; -typedef struct G_RenderSig G_RenderSig; +//////////////////////////////// +//~ Texture + +typedef i32 G_TextureFormat; enum +{ + GP_TEXTURE_FORMAT_NONE, + GP_TEXTURE_FORMAT_R8_UNORM, + GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, + GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, + GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT, + + NUM_GP_TEXTURE_FORMATS +}; + +typedef i32 G_TextureFlag; enum +{ + GP_TEXTURE_FLAG_NONE = (0), + GP_TEXTURE_FLAG_TARGETABLE = (1 << 0) +}; + +//////////////////////////////// +//~ Memory info + +Struct(G_MemoryInfo) +{ + u64 local_used; + u64 local_budget; + u64 non_local_used; + u64 non_local_budget; +}; + +//////////////////////////////// +//~ Startup + +void gp_startup(void); + +//////////////////////////////// +//~ Resource operations + +/* NOTE: Internally, the layer will make sure to not release any resources + * until after any in-flight GPU runs finish using them. However, it is up to + * the caller to make sure the released resources aren't then referenced in + * any runs + */ +void gp_resource_release(G_Resource *resource); + +//////////////////////////////// +//~ Texture operations + +G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, V2i32 size, void *initial_data); + +V2i32 gp_texture_get_size(G_Resource *texture); + +//////////////////////////////// +//~ Render operations G_RenderSig *gp_render_sig_alloc(void); @@ -115,25 +139,13 @@ u32 gp_push_render_cmd(G_RenderSig *render_sig, G_RenderCmdDesc *desc); G_Resource *gp_run_render(G_RenderSig *gp_render_sig, G_RenderParams render_params); -/* ========================== * - * Memory info - * ========================== */ - -typedef struct G_MemoryInfo G_MemoryInfo; -struct G_MemoryInfo { - u64 local_used; - u64 local_budget; - u64 non_local_used; - u64 non_local_budget; -}; +//////////////////////////////// +//~ Memory query G_MemoryInfo gp_query_memory_info(void); -/* ========================== * - * Swapchain - * ========================== */ - -typedef struct G_Swapchain G_Swapchain; +//////////////////////////////// +//~ Swapchain G_Swapchain *gp_swapchain_alloc(P_Window *window, V2i32 resolution); @@ -143,9 +155,8 @@ void gp_swapchain_release(G_Swapchain *gp_swapchain); * This should be called before rendering for minimum latency. */ void gp_swapchain_wait(G_Swapchain *gp_swapchain); -/* ========================== * - * Present - * ========================== */ +//////////////////////////////// +//~ Present /* 1. Clears the backbuffer and ensures it's at size `backbuffer_resolution` * 2. Blits `texture` to the backbuffer using `texture_xf` diff --git a/src/gp/gp_core_dx12.c b/src/gp/gp_core_dx12.c index 5ba3992f..d3a4f551 100644 --- a/src/gp/gp_core_dx12.c +++ b/src/gp/gp_core_dx12.c @@ -448,12 +448,12 @@ INTERNAL P_ExitFuncDef(gp_shutdown) #endif { - P_Lock lock = snc_lock_e(&G.evictor_wake_mutex); + P_Lock lock = P_LockE(&G.evictor_wake_mutex); G.evictor_shutdown = 1; - snc_cv_signal(&G.evictor_wake_cv, I32_MAX); - snc_unlock(&lock); + P_SignalCv(&G.evictor_wake_cv, I32_MAX); + P_Unlock(&lock); } - snc_counter_wait(&G.evictor_job_counter); + P_WaitOnCounter(&G.evictor_job_counter); } /* ========================== * @@ -601,21 +601,21 @@ INTERNAL void dx12_init_device(void) success = value != 0; } } - logf_info("D3D12 profiling is enabled, attempting to set stable power state (this will increase GPU timing stability at the cost of performance)"); + P_LogInfoF("D3D12 profiling is enabled, attempting to set stable power state (this will increase GPU timing stability at the cost of performance)"); if (success) { - logf_info("Machine is in developer mode, calling ID3D12Device::SetStablePowerState"); + P_LogInfoF("Machine is in developer mode, calling ID3D12Device::SetStablePowerState"); hr = ID3D12Device_SetStablePowerState(G.device, 1); if (SUCCEEDED(hr)) { - logf_info("ID3D12Device::SetStablePowerState succeeded"); + P_LogInfoF("ID3D12Device::SetStablePowerState succeeded"); } else { success = 0; - logf_error("ID3D12Device::SetStablePowerState failed"); + P_LogErrorF("ID3D12Device::SetStablePowerState failed"); } } else { - logf_warning("Machine is not in developer mode, cannot call ID3D12Device::SetStablePowerState"); + P_LogWarningF("Machine is not in developer mode, cannot call ID3D12Device::SetStablePowerState"); } if (!success) { - logf_warning("Profiling is enabled, but ID3D12Device::SetStablePowerState could not be called. This means that GPU timing may be unreliable."); + P_LogWarningF("Profiling is enabled, but ID3D12Device::SetStablePowerState could not be called. This means that GPU timing may be unreliable."); } } #endif @@ -660,7 +660,7 @@ INTERNAL void dx12_init_objects(void) { P_Counter counter = ZI; P_Run(DX12_NUM_QUEUES, command_queue_alloc_job, &sig, P_Pool_Inherit, P_Priority_Inherit, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } #if PROFILING { @@ -754,20 +754,20 @@ INTERNAL void dx12_init_pipelines(void) sig.pipelines_out = pipelines; P_Counter counter = ZI; P_Run(num_pipelines, pipeline_alloc_job, &sig, P_Pool_Inherit, P_Priority_Inherit, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } for (u32 i = 0; i < num_pipelines; ++i) { struct pipeline *pipeline = pipelines[i]; if (pipeline->success) { - logf_success("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SECONDS_FROM_NS(pipeline->compilation_time_ns))); + P_LogSuccessF("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SECONDS_FROM_NS(pipeline->compilation_time_ns))); if (pipeline->error.len) { String msg = string_format(scratch.arena, LIT("Warning while compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(pipeline->error)); - log_warning(msg); + P_LogWarning(msg); } } else { String error = pipeline->error.len > 0 ? pipeline->error : LIT("Unknown error"); String msg = string_format(scratch.arena, LIT("Error initializing pipeline \"%F\":\n\n%F"), FMT_STR(pipeline->name), FMT_STR(error)); - log_error(msg); + P_LogError(msg); P_MessageBox(P_MessageBoxKind_Warning, msg); } } @@ -829,7 +829,7 @@ INTERNAL void dx12_init_noise(void) sig.resource = r; sig.data = data.text; P_Run(1, dx12_upload_job, &sig, P_Pool_Inherit, P_Priority_Inherit, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } } } else { @@ -881,7 +881,7 @@ INTERNAL P_JobDef(shader_compile_job, job) DXC_Result dxc_result = ZI; { __profn("Compile shader"); - logf_info("Compiling shader \"%F:%F\"", FMT_STR(desc->friendly_name), FMT_STR(desc->entry)); + P_LogInfoF("Compiling shader \"%F:%F\"", FMT_STR(desc->friendly_name), FMT_STR(desc->entry)); /* NOTE: `DXC_ARGS` is supplied by build system at compile time */ char *dxc_args_cstr = STRINGIZE(DXC_ARGS); String dxc_args_str = string_from_cstr_no_limit(dxc_args_cstr); @@ -925,14 +925,14 @@ INTERNAL P_JobDef(pipeline_alloc_job, job) struct pipeline *pipeline = 0; { - P_Lock lock = snc_lock_e(&G.pipelines_mutex); + P_Lock lock = P_LockE(&G.pipelines_mutex); if (G.first_free_pipeline) { pipeline = G.first_free_pipeline; G.first_free_pipeline = pipeline->next; } else { pipeline = arena_push_no_zero(G.pipelines_arena, struct pipeline); } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(pipeline); pipelines_out[job.id] = pipeline; @@ -944,7 +944,7 @@ INTERNAL P_JobDef(pipeline_alloc_job, job) { i64 start_ns = P_TimeNs(); String pipeline_name = pipeline->name; - logf_info("Loading pipeline \"%F\"", FMT_STR(pipeline_name)); + P_LogInfoF("Loading pipeline \"%F\"", FMT_STR(pipeline_name)); b32 success = 1; HRESULT hr = 0; @@ -1192,12 +1192,12 @@ INTERNAL void pipeline_release_now(struct pipeline *pipeline) if (pipeline->pso) { ID3D12PipelineState_Release(pipeline->pso); } - P_Lock lock = snc_lock_e(&G.pipelines_mutex); + P_Lock lock = P_LockE(&G.pipelines_mutex); { pipeline->next = G.first_free_pipeline; G.first_free_pipeline = pipeline; } - snc_unlock(&lock); + P_Unlock(&lock); } /* ========================== * @@ -1209,12 +1209,12 @@ INTERNAL struct pipeline_scope *pipeline_scope_begin(void) __prof; struct pipeline_scope *scope = 0; { - P_Lock lock = snc_lock_e(&G.pipelines_mutex); + P_Lock lock = P_LockE(&G.pipelines_mutex); if (G.first_free_pipeline_scope) { scope = G.first_free_pipeline_scope; G.first_free_pipeline_scope = scope->next_free; } - snc_unlock(&lock); + P_Unlock(&lock); } Arena *arena = 0; if (scope) { @@ -1232,7 +1232,7 @@ INTERNAL struct pipeline_scope *pipeline_scope_begin(void) INTERNAL void pipeline_scope_end(struct pipeline_scope *scope) { __prof; - P_Lock lock = snc_lock_e(&G.pipelines_mutex); + P_Lock lock = P_LockE(&G.pipelines_mutex); { for (DictEntry *entry = scope->refs->first; entry; entry = entry->next) { struct pipeline *pipeline = (struct pipeline *)entry->value; @@ -1243,7 +1243,7 @@ INTERNAL void pipeline_scope_end(struct pipeline_scope *scope) scope->next_free = G.first_free_pipeline_scope; G.first_free_pipeline_scope = scope; } - snc_unlock(&lock); + P_Unlock(&lock); } INTERNAL READONLY struct pipeline g_nil_pipeline = ZI; @@ -1258,12 +1258,12 @@ INTERNAL struct pipeline *pipeline_from_name(struct pipeline_scope *scope, Strin res = tmp; } else { { - P_Lock lock = snc_lock_e(&G.pipelines_mutex); + P_Lock lock = P_LockE(&G.pipelines_mutex); tmp = (struct pipeline *)dict_get(G.top_successful_pipelines, hash); if (tmp) { ++tmp->refcount; } - snc_unlock(&lock); + P_Unlock(&lock); } if (tmp) { dict_set(scope->arena, scope->refs, hash, (u64)tmp); @@ -1277,7 +1277,7 @@ INTERNAL struct pipeline *pipeline_from_name(struct pipeline_scope *scope, Strin INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines) { __prof; - P_Lock lock = snc_lock_e(&G.pipelines_mutex); + P_Lock lock = P_LockE(&G.pipelines_mutex); { for (u64 i = 0; i < num_pipelines; ++i) { struct pipeline *pipeline = pipelines[i]; @@ -1302,7 +1302,7 @@ INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines) } } } - snc_unlock(&lock); + P_Unlock(&lock); } #if RESOURCE_RELOADING @@ -1326,7 +1326,7 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name) struct shader_compile_desc *shader_descs = 0; struct shader_compile_result *shader_results = 0; if (is_rs || is_cs) { - logf_debug("Change detected in shader source file \"%F\", recompiling...", FMT_STR(name)); + P_LogDebugF("Change detected in shader source file \"%F\", recompiling...", FMT_STR(name)); success = 1; P_File file = P_OpenFileReadWait(name); String data = P_ReadFile(scratch.arena, file); @@ -1373,7 +1373,7 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name) { P_Counter counter = ZI; P_Run(num_shaders, shader_compile_job, &sig, P_Pool_Inherit, P_Priority_Inherit, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } } P_CloseFIle(file); @@ -1384,14 +1384,14 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name) struct shader_compile_desc *desc = &shader_descs[i]; struct shader_compile_result *result = &shader_results[i]; if (result->success) { - logf_success("Finished compiling shader \"%F:%F\" in %F seconds", FMT_STR(desc->friendly_name), FMT_STR(desc->entry), FMT_FLOAT(SECONDS_FROM_NS(result->elapsed_ns))); + P_LogSuccessF("Finished compiling shader \"%F:%F\" in %F seconds", FMT_STR(desc->friendly_name), FMT_STR(desc->entry), FMT_FLOAT(SECONDS_FROM_NS(result->elapsed_ns))); if (result->errors.len > 0) { String msg = result->errors; - log_warning(msg); + P_LogWarning(msg); } } else { String msg = result->errors; - log_error(msg); + P_LogError(msg); success = 0; } } @@ -1425,23 +1425,23 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name) sig.pipelines_out = pipelines; P_Counter counter = ZI; P_Run(num_pipelines, pipeline_alloc_job, &sig, P_Pool_Inherit, P_Priority_Inherit, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } { - P_Lock lock = snc_lock_s(&G.pipelines_mutex); + P_Lock lock = P_LockS(&G.pipelines_mutex); for (u32 i = 0; i < num_pipelines; ++i) { struct pipeline *pipeline = pipelines[i]; if (pipeline->success) { - logf_success("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SECONDS_FROM_NS(pipeline->compilation_time_ns))); + P_LogSuccessF("Successfully compiled pipeline \"%F\" in %F seconds", FMT_STR(pipeline->name), FMT_FLOAT(SECONDS_FROM_NS(pipeline->compilation_time_ns))); if (pipeline->error.len > 0) { String msg = string_format(scratch.arena, LIT("Warning while compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(pipeline->error)); - log_warning(msg); + P_LogWarning(msg); } } else { { String error = pipeline->error.len > 0 ? pipeline->error : LIT("Unknown error"); String msg = string_format(scratch.arena, LIT("Error compiling pipeline \"%F\":\n%F"), FMT_STR(pipeline->name), FMT_STR(error)); - log_error(msg); + P_LogError(msg); } struct pipeline *old_pipeline = (struct pipeline *)dict_get(G.top_successful_pipelines, pipeline->hash); if (!old_pipeline) { @@ -1453,7 +1453,7 @@ INTERNAL WATCH_CALLBACK_FUNC_DEF(pipeline_watch_callback, name) } } - snc_unlock(&lock); + P_Unlock(&lock); } pipeline_register(num_pipelines, pipelines); } @@ -1474,7 +1474,7 @@ INTERNAL struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh) u32 index = 0; D3D12_CPU_DESCRIPTOR_HANDLE handle = ZI; { - P_Lock lock = snc_lock_e(&dh->mutex); + P_Lock lock = P_LockE(&dh->mutex); if (dh->first_free_descriptor) { d = dh->first_free_descriptor; dh->first_free_descriptor = d->next_free; @@ -1488,7 +1488,7 @@ INTERNAL struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh) index = dh->num_descriptors_reserved++; handle.ptr = dh->handle.ptr + (index * dh->descriptor_size); } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(d); d->heap = dh; @@ -1500,12 +1500,12 @@ INTERNAL struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh) INTERNAL void descriptor_release(struct descriptor *descriptor) { struct cpu_descriptor_heap *dh = descriptor->heap; - P_Lock lock = snc_lock_e(&dh->mutex); + P_Lock lock = P_LockE(&dh->mutex); { descriptor->next_free = dh->first_free_descriptor; dh->first_free_descriptor = descriptor; } - snc_unlock(&lock); + P_Unlock(&lock); } /* ========================== * @@ -1569,31 +1569,31 @@ INTERNAL void fenced_release(void *data, enum fenced_release_kind kind) /* Read current fence target values from command queues */ for (u32 i = 0; i < countof(G.command_queues); ++i) { struct command_queue *cq = G.command_queues[i]; - P_Lock lock = snc_lock_s(&cq->submit_fence_mutex); + P_Lock lock = P_LockS(&cq->submit_fence_mutex); { fr_targets[i] = cq->submit_fence_target; } - snc_unlock(&lock); + P_Unlock(&lock); } /* Push data to release queue */ { - P_Lock lock = snc_lock_e(&G.fenced_releases_mutex); + P_Lock lock = P_LockE(&G.fenced_releases_mutex); { *arena_push(G.fenced_releases_arena, struct fenced_release_data) = fr; MEMCPY(G.fenced_release_targets, fr_targets, sizeof(fr_targets)); } - snc_unlock(&lock); + P_Unlock(&lock); } /* Wake evictor */ { - P_Lock lock = snc_lock_e(&G.evictor_wake_mutex); + P_Lock lock = P_LockE(&G.evictor_wake_mutex); { ++G.evictor_wake_gen; - snc_cv_signal(&G.evictor_wake_cv, I32_MAX); + P_SignalCv(&G.evictor_wake_cv, I32_MAX); } - snc_unlock(&lock); + P_Unlock(&lock); } } @@ -1606,14 +1606,14 @@ INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_pr __prof; struct dx12_resource *r = 0; { - P_Lock lock = snc_lock_e(&G.resources_mutex); + P_Lock lock = P_LockE(&G.resources_mutex); if (G.first_free_resource) { r = G.first_free_resource; G.first_free_resource = r->next_free; } else { r = arena_push_no_zero(G.resources_arena, struct dx12_resource); } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(r); @@ -1657,10 +1657,10 @@ INTERNAL void dx12_resource_release_now(struct dx12_resource *t) ID3D12Resource_Release(t->resource); /* Add to free list */ - P_Lock lock = snc_lock_e(&G.resources_mutex); + P_Lock lock = P_LockE(&G.resources_mutex); t->next_free = G.first_free_resource; G.first_free_resource = t; - snc_unlock(&lock); + P_Unlock(&lock); } void gp_resource_release(G_Resource *resource) @@ -1797,7 +1797,7 @@ INTERNAL struct command_list *command_list_open(struct command_list_pool *pool) struct ID3D12GraphicsCommandList *old_cl = 0; struct ID3D12CommandAllocator *old_ca = 0; { - P_Lock lock = snc_lock_e(&pool->mutex); + P_Lock lock = P_LockE(&pool->mutex); /* Find first command list ready for reuse */ for (struct command_list *tmp = pool->first_submitted_command_list; tmp; tmp = tmp->next_submitted) { if (completed_fence_value >= tmp->submitted_fence_target) { @@ -1824,12 +1824,12 @@ INTERNAL struct command_list *command_list_open(struct command_list_pool *pool) } else { cl = arena_push_no_zero(pool->arena, struct command_list); } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(cl); cl->cq = cq; cl->pool = pool; - cl->global_record_lock = snc_lock_s(&G.global_command_list_record_mutex); + cl->global_record_lock = P_LockS(&G.global_command_list_record_mutex); HRESULT hr = 0; if (old_cl) { @@ -1887,20 +1887,20 @@ INTERNAL u64 command_list_close(struct command_list *cl) u64 submit_fence_target = 0; { __profn("Execute"); - P_Lock submit_lock = snc_lock_s(&G.global_submit_mutex); - P_Lock fence_lock = snc_lock_e(&cq->submit_fence_mutex); + P_Lock submit_lock = P_LockS(&G.global_submit_mutex); + P_Lock fence_lock = P_LockE(&cq->submit_fence_mutex); { submit_fence_target = ++cq->submit_fence_target; ID3D12CommandQueue_ExecuteCommandLists(cq->cq, 1, (ID3D12CommandList **)&cl->cl); ID3D12CommandQueue_Signal(cq->cq, cq->submit_fence, submit_fence_target); } - snc_unlock(&fence_lock); - snc_unlock(&submit_lock); + P_Unlock(&fence_lock); + P_Unlock(&submit_lock); } /* Add descriptor heaps to submitted list */ { - P_Lock lock = snc_lock_e(&G.command_descriptor_heaps_mutex); + P_Lock lock = P_LockE(&G.command_descriptor_heaps_mutex); for (struct command_descriptor_heap *cdh = cl->first_command_descriptor_heap; cdh; cdh = cdh->next_in_command_list) { cdh->submitted_cq = cq; cdh->submitted_fence_target = submit_fence_target; @@ -1911,12 +1911,12 @@ INTERNAL u64 command_list_close(struct command_list *cl) } G.last_submitted_command_descriptor_heap = cdh; } - snc_unlock(&lock); + P_Unlock(&lock); } /* Add command buffers to submitted list */ { - P_Lock lock = snc_lock_e(&G.command_buffers_mutex); + P_Lock lock = P_LockE(&G.command_buffers_mutex); for (struct command_buffer *cb = cl->first_command_buffer; cb; cb = cb->next_in_command_list) { struct command_buffer_group *group = cb->group; cb->submitted_cq = cq; @@ -1928,21 +1928,21 @@ INTERNAL u64 command_list_close(struct command_list *cl) } group->last_submitted = cb; } - snc_unlock(&lock); + P_Unlock(&lock); } /* Add command list to pool submitted list */ - snc_unlock(&cl->global_record_lock); + P_Unlock(&cl->global_record_lock); cl->submitted_fence_target = submit_fence_target; { - P_Lock lock = snc_lock_e(&pool->mutex); + P_Lock lock = P_LockE(&pool->mutex); if (pool->last_submitted_command_list) { pool->last_submitted_command_list->next_submitted = cl; } else { pool->first_submitted_command_list = cl; } pool->last_submitted_command_list = cl; - snc_unlock(&lock); + P_Unlock(&lock); } return submit_fence_target; @@ -1963,7 +1963,7 @@ INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struc D3D12_CPU_DESCRIPTOR_HANDLE old_start_cpu_handle = ZI; D3D12_GPU_DESCRIPTOR_HANDLE old_start_gpu_handle = ZI; { - P_Lock lock = snc_lock_e(&G.command_descriptor_heaps_mutex); + P_Lock lock = P_LockE(&G.command_descriptor_heaps_mutex); /* Find first heap ready for reuse */ for (struct command_descriptor_heap *tmp = G.first_submitted_command_descriptor_heap; tmp; tmp = tmp->next_submitted) { /* TODO: Cache completed fence values */ @@ -1994,7 +1994,7 @@ INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struc /* No available heap available for reuse, allocate new */ cdh = arena_push_no_zero(G.command_descriptor_heaps_arena, struct command_descriptor_heap); } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(cdh); @@ -2017,9 +2017,9 @@ INTERNAL struct command_descriptor_heap *command_list_push_descriptor_heap(struc /* Copy CPU heap */ { - P_Lock lock = snc_lock_s(&dh_cpu->mutex); + P_Lock lock = P_LockS(&dh_cpu->mutex); ID3D12Device_CopyDescriptorsSimple(G.device, dh_cpu->num_descriptors_reserved, cdh->start_cpu_handle, dh_cpu->handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - snc_unlock(&lock); + P_Unlock(&lock); } /* Insert into command list */ @@ -2071,7 +2071,7 @@ INTERNAL struct command_buffer *_command_list_push_buffer(struct command_list *c struct command_buffer *cb = 0; struct dx12_resource *r = 0; { - P_Lock lock = snc_lock_e(&G.command_buffers_mutex); + P_Lock lock = P_LockE(&G.command_buffers_mutex); { u64 group_hash = command_buffer_hash_from_size(size); @@ -2111,7 +2111,7 @@ INTERNAL struct command_buffer *_command_list_push_buffer(struct command_list *c /* Allocate new */ cb = arena_push_no_zero(G.command_buffers_arena, struct command_buffer); } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(cb); cb->group = cb_group; @@ -2265,7 +2265,7 @@ G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, V2i32 size, void sig.resource = r; sig.data = initial_data; P_Run(1, dx12_upload_job, &sig, P_Pool_Inherit, P_Priority_Inherit, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } return (G_Resource *)r; @@ -2377,7 +2377,7 @@ INTERNAL P_JobDef(dx12_upload_job, job) wait_sig.target = fence_target; P_Counter counter = ZI; P_Run(1, dx12_wait_fence_job, &wait_sig, P_Pool_Floating, P_Priority_Low, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } /* Release upload heap now */ @@ -3209,14 +3209,14 @@ G_Swapchain *gp_swapchain_alloc(P_Window *window, V2i32 resolution) struct swapchain *swapchain = 0; { - P_Lock lock = snc_lock_e(&G.swapchains_mutex); + P_Lock lock = P_LockE(&G.swapchains_mutex); if (G.first_free_swapchain) { swapchain = G.first_free_swapchain; G.first_free_swapchain = swapchain->next_free; } else { swapchain = arena_push(G.swapchains_arena, struct swapchain); } - snc_unlock(&lock); + P_Unlock(&lock); } /* Create swapchain1 */ @@ -3293,9 +3293,9 @@ INTERNAL struct swapchain_buffer *update_swapchain(struct swapchain *swapchain, struct command_queue *cq = G.command_queues[DX12_QUEUE_DIRECT]; /* Lock direct queue submissions (in case any write to backbuffer) */ /* TODO: Less overkill approach - Only flush present_blit since we know it's the only operation targeting backbuffer */ - P_Lock lock = snc_lock_e(&cq->submit_fence_mutex); + P_Lock lock = P_LockE(&cq->submit_fence_mutex); //DEBUGBREAKABLE; - //P_Lock lock = snc_lock_e(&G.global_command_list_record_mutex); + //P_Lock lock = P_LockE(&G.global_command_list_record_mutex); { /* Flush direct queue */ //ID3D12CommandQueue_Signal(cq->cq, cq->submit_fence, ++cq->submit_fence_target); @@ -3320,7 +3320,7 @@ INTERNAL struct swapchain_buffer *update_swapchain(struct swapchain *swapchain, P_Panic(LIT("Failed to resize swapchain")); } } - snc_unlock(&lock); + P_Unlock(&lock); swapchain_init_resources(swapchain); @@ -3464,14 +3464,14 @@ void gp_present(G_Swapchain *gp_swapchain, V2i32 backbuffer_resolution, G_Resour __profn("Mark queue frames"); /* Lock because frame marks shouldn't occur while command lists are recording */ - P_Lock lock = snc_lock_e(&G.global_command_list_record_mutex); + P_Lock lock = P_LockE(&G.global_command_list_record_mutex); for (u32 i = 0; i < countof(G.command_queues); ++i) { { struct command_queue *cq = G.command_queues[i]; __prof_dx12_new_frame(cq->prof); } } - snc_unlock(&lock); + P_Unlock(&lock); } { __profn("Collect queues"); @@ -3505,13 +3505,13 @@ INTERNAL P_JobDef(dx12_evictor_job, _) struct fenced_release_data *fenced_releases = 0; { __profn("Copy queued releases"); - P_Lock lock = snc_lock_e(&G.fenced_releases_mutex); + P_Lock lock = P_LockE(&G.fenced_releases_mutex); num_fenced_releases = G.fenced_releases_arena->pos / sizeof(struct fenced_release_data); fenced_releases = arena_push_array_no_zero(scratch.arena, struct fenced_release_data, num_fenced_releases); MEMCPY(fenced_releases, arena_base(G.fenced_releases_arena), G.fenced_releases_arena->pos); arena_reset(G.fenced_releases_arena); MEMCPY(targets, G.fenced_release_targets, sizeof(targets)); - snc_unlock(&lock); + P_Unlock(&lock); } /* Wait until fences reach target */ @@ -3530,7 +3530,7 @@ INTERNAL P_JobDef(dx12_evictor_job, _) { P_Counter counter = ZI; P_Run(1, dx12_wait_fence_job, &sig, P_Pool_Floating, P_Priority_Low, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } } } @@ -3563,14 +3563,14 @@ INTERNAL P_JobDef(dx12_evictor_job, _) } scratch_end(scratch); } - P_Lock lock = snc_lock_e(&G.evictor_wake_mutex); + P_Lock lock = P_LockE(&G.evictor_wake_mutex); { while (!G.evictor_shutdown && G.evictor_wake_gen == 0) { - snc_cv_wait(&G.evictor_wake_cv, &lock); + P_WaitOnCv(&G.evictor_wake_cv, &lock); } shutdown = G.evictor_shutdown; G.evictor_wake_gen = 0; } - snc_unlock(&lock); + P_Unlock(&lock); } } diff --git a/src/json/json_core.h b/src/json/json_core.h index f63922e4..fd09d2f0 100644 --- a/src/json/json_core.h +++ b/src/json/json_core.h @@ -1,15 +1,14 @@ -typedef enum JSON_Type { +typedef i32 JSON_Type; enum { JSON_TYPE_NULL, JSON_TYPE_BOOL, JSON_TYPE_NUMBER, JSON_TYPE_STRING, JSON_TYPE_ARRAY, JSON_TYPE_OBJECT -} JSON_Type; +}; -typedef struct JSON_Blob JSON_Blob; -struct JSON_Blob { +Struct(JSON_Blob) { JSON_Type type; String key; @@ -25,23 +24,20 @@ struct JSON_Blob { } value; }; -typedef struct JSON_Error JSON_Error; -struct JSON_Error { +Struct(JSON_Error) { String msg; u64 start; u64 end; JSON_Error *next; }; -typedef struct JSON_ErrorList JSON_ErrorList; -struct JSON_ErrorList { +Struct(JSON_ErrorList) { u64 count; JSON_Error *first; JSON_Error *last; }; -typedef struct JSON_Result JSON_Result; -struct JSON_Result { +Struct(JSON_Result) { JSON_Blob *root; JSON_ErrorList errors; }; diff --git a/src/mixer/mixer_core.c b/src/mixer/mixer_core.c index 1e2bd34a..cdf6cd29 100644 --- a/src/mixer/mixer_core.c +++ b/src/mixer/mixer_core.c @@ -96,7 +96,7 @@ INTERNAL struct track *track_from_handle(M_Handle handle) INTERNAL struct track *track_alloc_locked(P_Lock *lock, SND_Sound *sound) { - snc_assert_locked_e(lock, &G.mutex); + P_AssertLockedE(lock, &G.mutex); (UNUSED)lock; struct track *track = 0; @@ -135,7 +135,7 @@ INTERNAL struct track *track_alloc_locked(P_Lock *lock, SND_Sound *sound) INTERNAL void track_release_locked(P_Lock *lock, struct track *track) { - snc_assert_locked_e(lock, &G.mutex); + P_AssertLockedE(lock, &G.mutex); (UNUSED)lock; /* Remove from playing list */ @@ -181,12 +181,12 @@ M_Handle mixer_play_ex(SND_Sound *sound, M_TrackDesc desc) { struct track *track; { - P_Lock lock = snc_lock_e(&G.mutex); + P_Lock lock = P_LockE(&G.mutex); { track = track_alloc_locked(&lock, sound); track->desc = desc; } - snc_unlock(&lock); + P_Unlock(&lock); } return track_to_handle(track); } @@ -199,7 +199,7 @@ M_TrackDesc mixer_track_get(M_Handle handle) struct track *track = track_from_handle(handle); if (track) { /* TODO: Only lock mutex on track itself or something */ - P_Lock lock = snc_lock_e(&G.mutex); + P_Lock lock = P_LockE(&G.mutex); { /* Confirm handle is still valid now that we're locked */ track = track_from_handle(handle); @@ -207,7 +207,7 @@ M_TrackDesc mixer_track_get(M_Handle handle) res = track->desc; } } - snc_unlock(&lock); + P_Unlock(&lock); } return res; @@ -219,7 +219,7 @@ void mixer_track_set(M_Handle handle, M_TrackDesc desc) struct track *track = track_from_handle(handle); if (track) { /* TODO: Only lock mutex on track itself or something */ - P_Lock lock = snc_lock_e(&G.mutex); + P_Lock lock = P_LockE(&G.mutex); { /* Confirm handle is still valid now that we're locked */ track = track_from_handle(handle); @@ -227,18 +227,18 @@ void mixer_track_set(M_Handle handle, M_TrackDesc desc) track->desc = desc; } } - snc_unlock(&lock); + P_Unlock(&lock); } } void mixer_set_listener(V2 pos, V2 dir) { - P_Lock lock = snc_lock_e(&G.mutex); + P_Lock lock = P_LockE(&G.mutex); { G.listener_pos = pos; G.listener_dir = v2_norm(dir); } - snc_unlock(&lock); + P_Unlock(&lock); } /* ========================== * @@ -274,7 +274,7 @@ M_PcmF32 mixer_update(Arena *arena, u64 frame_count) struct mix **mixes = 0; u64 mixes_count = 0; { - P_Lock lock = snc_lock_e(&G.mutex); + P_Lock lock = P_LockE(&G.mutex); /* Read listener info */ listener_pos = G.listener_pos; @@ -289,7 +289,7 @@ M_PcmF32 mixer_update(Arena *arena, u64 frame_count) mixes[mixes_count++] = mix; } - snc_unlock(&lock); + P_Unlock(&lock); } for (u64 mix_index = 0; mix_index < mixes_count; ++mix_index) { @@ -462,7 +462,7 @@ M_PcmF32 mixer_update(Arena *arena, u64 frame_count) { __profn("Update track effect data"); - P_Lock lock = snc_lock_e(&G.mutex); + P_Lock lock = P_LockE(&G.mutex); for (u64 i = 0; i < mixes_count; ++i) { struct mix *mix = mixes[i]; struct track *track = track_from_handle(mix->track_handle); @@ -473,7 +473,7 @@ M_PcmF32 mixer_update(Arena *arena, u64 frame_count) } } } - snc_unlock(&lock); + P_Unlock(&lock); } scratch_end(scratch); diff --git a/src/mixer/mixer_core.h b/src/mixer/mixer_core.h index 68be8eeb..35a67f25 100644 --- a/src/mixer/mixer_core.h +++ b/src/mixer/mixer_core.h @@ -13,8 +13,7 @@ __VA_ARGS__ \ }) -typedef struct M_TrackDesc M_TrackDesc; -struct M_TrackDesc { +Struct(M_TrackDesc) { u32 flags; f32 volume; /* 0 -> 1.0+ */ f32 speed; /* 0 -> 1.0+ */ @@ -24,21 +23,18 @@ struct M_TrackDesc { V2 pos; }; -typedef struct M_Handle M_Handle; -struct M_Handle { +Struct(M_Handle) { u64 gen; void *data; }; /* Stereo mix of 32 bit float samples */ -typedef struct M_PcmF32 M_PcmF32; -struct M_PcmF32 { +Struct(M_PcmF32) { u64 count; f32 *samples; }; -typedef struct M_StartupReceipt M_StartupReceipt; -struct M_StartupReceipt { i32 _; }; +Struct(M_StartupReceipt) { i32 _; }; M_StartupReceipt mixer_startup(void); /* Interface */ diff --git a/src/mp3/mp3_core.h b/src/mp3/mp3_core.h index eaf2e4e0..ed386f1a 100644 --- a/src/mp3/mp3_core.h +++ b/src/mp3/mp3_core.h @@ -1,8 +1,7 @@ #define MP3_DECODE_FLAG_NONE 0x00 #define MP3_DECODE_FLAG_STEREO 0x01 -typedef struct MP3_Result MP3_Result; -struct MP3_Result { +Struct(MP3_Result) { PcmData pcm; b32 success; }; diff --git a/src/net/net_core.c b/src/net/net_core.c index 8643b813..6759798c 100644 --- a/src/net/net_core.c +++ b/src/net/net_core.c @@ -672,7 +672,7 @@ N_EventList host_update_begin(Arena *arena, N_Host *host) { /* A foreign host is trying to connect to us */ if (!channel->valid) { - logf_info("Host received conection attempt from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); + P_LogInfoF("Host received conection attempt from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); /* TODO: Verify that some per-host uuid isn't present in a rolling window to prevent reconnects right after a disconnect? */ channel = host_channel_alloc(host, address); } @@ -685,7 +685,7 @@ N_EventList host_update_begin(Arena *arena, N_Host *host) { /* We successfully connected to a foreign host and they are ready to receive messages */ if (channel->valid && !channel->connected) { - logf_info("Host received connection from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); + P_LogInfoF("Host received connection from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); N_Event *event = push_event(arena, &events); event->kind = HOST_EVENT_KIND_CHANNEL_OPENED; event->channel_id = channel->id; @@ -697,7 +697,7 @@ N_EventList host_update_begin(Arena *arena, N_Host *host) { /* A foreign host disconnected from us */ if (channel->valid) { - logf_info("Host received disconnection from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); + P_LogInfoF("Host received disconnection from %F", FMT_STR(P_StringFromAddress(scratch.arena, address))); N_Event *event = push_event(arena, &events); event->kind = HOST_EVENT_KIND_CHANNEL_CLOSED; event->channel_id = channel->id; diff --git a/src/net/net_core.h b/src/net/net_core.h index 0c59a6d4..8d1858f8 100644 --- a/src/net/net_core.h +++ b/src/net/net_core.h @@ -8,7 +8,7 @@ #define N_NumChannelLookupBins 512 #define N_NumMsgAssemblerLookupBins 16384 -typedef enum N_CmdKind { +typedef i32 N_CmdKind; enum { HOST_CMD_KIND_NONE, HOST_CMD_KIND_TRY_CONNECT, @@ -16,30 +16,28 @@ typedef enum N_CmdKind { HOST_CMD_KIND_DISCONNECT, HOST_CMD_KIND_HEARTBEAT, HOST_CMD_KIND_WRITE -} N_CmdKind; +}; -typedef enum N_EventKind { +typedef i32 N_EventKind; enum { HOST_EVENT_KIND_NONE, HOST_EVENT_KIND_CHANNEL_OPENED, HOST_EVENT_KIND_CHANNEL_CLOSED, HOST_EVENT_KIND_MSG -} N_EventKind; +}; -typedef enum N_WriteFlag { +typedef i32 N_WriteFlag; enum { HOST_WRITE_FLAG_NONE = 0, HOST_WRITE_FLAG_RELIABLE = (1 << 0) -} N_WriteFlag; +}; -typedef struct N_ChannelId N_ChannelId; -struct N_ChannelId { +Struct(N_ChannelId) { u32 gen; u32 idx; }; -typedef struct N_Cmd N_Cmd; -struct N_Cmd { +Struct(N_Cmd) { N_CmdKind kind; N_ChannelId channel_id; @@ -53,8 +51,7 @@ struct N_Cmd { N_Cmd *next; }; -typedef struct N_Event N_Event; -struct N_Event { +Struct(N_Event) { N_EventKind kind; N_ChannelId channel_id; String msg; @@ -62,27 +59,23 @@ struct N_Event { N_Event *next; }; -typedef struct N_EventList N_EventList; -struct N_EventList { +Struct(N_EventList) { N_Event *first; N_Event *last; }; -typedef struct N_ChannelLookupBin N_ChannelLookupBin; -struct N_ChannelLookupBin { +Struct(N_ChannelLookupBin) { struct host_channel *first; struct host_channel *last; }; -typedef struct N_RcvBuffer N_RcvBuffer; -struct N_RcvBuffer { +Struct(N_RcvBuffer) { Arena *arena; struct host_rcv_packet *first_packet; struct host_rcv_packet *last_packet; }; -typedef struct N_SndPacket N_SndPacket; -struct N_SndPacket { +Struct(N_SndPacket) { N_SndPacket *next; u64 seq; @@ -90,8 +83,7 @@ struct N_SndPacket { u8 data[N_MaxPacketLen]; }; -typedef struct N_Host N_Host; -struct N_Host { +Struct(N_Host) { Arena *arena; P_Sock *sock; @@ -130,8 +122,7 @@ struct N_Host { * Startup * ========================== */ -typedef struct N_StartupReceipt N_StartupReceipt; -struct N_StartupReceipt { i32 _; }; +Struct(N_StartupReceipt) { i32 _; }; N_StartupReceipt host_startup(void); /* ========================== * diff --git a/src/platform/platform.c b/src/platform/platform.c index 0c713800..801e06fc 100644 --- a/src/platform/platform.c +++ b/src/platform/platform.c @@ -1,7 +1,6 @@ #include "platform.h" #include "platform_snc.c" -#include "platform_sleep.c" #include "platform_log.c" #if PLATFORM_WINDOWS diff --git a/src/platform/platform.h b/src/platform/platform.h index 0e8d0c2c..8c5d42d6 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -4,11 +4,28 @@ #include "../base/base.h" #include "platform_snc.h" -#include "platform_sleep.h" #include "platform_core.h" #include "platform_log.h" #if PLATFORM_WINDOWS +#pragma warning(push, 0) +# define UNICODE +# define WIN32_LEAN_AND_MEAN +/* FIXME: Remove this */ +# define NTDDI_WIN11_DT 0x0C0A0000 +# define NTDDI_VERSION 0x0A000000 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#pragma warning(pop) # include "platform_win32.h" #endif diff --git a/src/platform/platform_core.h b/src/platform/platform_core.h index abf593b6..b48006e0 100644 --- a/src/platform/platform_core.h +++ b/src/platform/platform_core.h @@ -1,19 +1,24 @@ -/* ========================== * - * Wait - * ========================== */ +//////////////////////////////// +//~ Opaque types + +Struct(P_Watch); +Struct(P_Window); +Struct(P_Sock); + +//////////////////////////////// +//~ Wait /* Futex-like wait & wake */ void P_Wait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns); - void P_Wake(void *addr, i32 count); -/* ========================== * - * Job - * ========================== */ +//////////////////////////////// +//~ Job - /* Work pools contain their own worker threads with their own thread priority/affinity based on the intended context of the pool. */ -typedef enum P_Pool { +/* Work pools contain their own worker threads with their own thread priority/affinity based on the intended context of the pool. */ +typedef i32 P_Pool; enum +{ P_Pool_Inherit = -1, /* The floating pool contains a large number of lower priority threads that have affinity over the entire CPU. @@ -26,20 +31,21 @@ typedef enum P_Pool { P_Pool_Sim = 4, P_Pool_Count -} P_Pool; +}; /* Job execution order within a pool is based on priority. */ -typedef enum P_Priority { +typedef i32 P_Priority; enum +{ P_Priority_Inherit = -1, P_Priority_High = 0, P_Priority_Normal = 1, P_Priority_Low = 2, P_Priority_Count -} P_Priority; +}; -typedef struct P_JobData P_JobData; -struct P_JobData { +Struct(P_JobData) +{ i32 id; void *sig; }; @@ -47,14 +53,11 @@ struct P_JobData { #define P_JobDef(job_name, arg_name) void job_name(P_JobData arg_name) typedef P_JobDef(P_JobFunc, job_data); -void P_Run(i32 count, P_JobFunc *func, void *sig, P_Pool pool_kind, P_Priority priority, P_Counter *counter); +//////////////////////////////// +//~ Time -/* ========================== * - * Time - * ========================== */ - -typedef struct P_DateTime P_DateTime; -struct P_DateTime { +Struct(P_DateTime) +{ u32 year; u32 month; u32 day_of_week; @@ -65,117 +68,62 @@ struct P_DateTime { u32 milliseconds; }; -P_DateTime P_LocalTime(void); +//////////////////////////////// +//~ File -i64 P_TimeNs(void); - -/* ========================== * - * File system - * - * NOTE: File paths use forward slash '/' as delimiter - * ========================== */ - -typedef struct P_File P_File; -struct P_File { +Struct(P_File) +{ u64 handle; b32 valid; }; -typedef struct P_FileTime P_FileTime; -struct P_FileTime { +Struct(P_FileTime) +{ P_DateTime created; P_DateTime accessed; P_DateTime modified; }; -String P_GetWritePath(Arena *arena); - -b32 P_IsFile(String path); - -b32 P_IsDir(String path); - -void P_MkDir(String path); - -P_File P_OpenFileRead(String path); - -P_File P_OpenFileReadWait(String path); /* Waits until file is not being used by another program */ - -P_File P_OpenFileWrite(String path); - -P_File P_OpenFileAppend(String path); - -void P_CloseFIle(P_File file); - -String P_ReadFile(Arena *arena, P_File file); - -void P_WriteFile(P_File file, String data); - -u64 P_GetFileSize(P_File file); - -P_FileTime P_GetFileTime(P_File file); - -/* ========================== * - * File map - * ========================== */ - -typedef struct P_FileMap P_FileMap; -struct P_FileMap { +Struct(P_FileMap) +{ String mapped_memory; u64 handle; b32 valid; }; -P_FileMap P_OpenFileMap(P_File file); +//////////////////////////////// +//~ Watch -void P_CloseFileMap(P_FileMap map); - -String P_GetFileMapData(P_FileMap map); - -/* ========================== * - * Watch - * ========================== */ - -typedef enum P_WatchInfoKind { +typedef i32 P_WatchInfoKind; enum +{ P_WatchInfoKind_Unknown, P_WatchInfoKind_Added, P_WatchInfoKind_Removed, P_WatchInfoKind_Modified, P_WatchInfoKind_RenamedOld, P_WatchInfoKind_RenamedNew -} P_WatchInfoKind; +}; -typedef struct P_WatchInfo P_WatchInfo; -struct P_WatchInfo { +Struct(P_WatchInfo) +{ P_WatchInfoKind kind; String name; P_WatchInfo *next; P_WatchInfo *prev; }; -typedef struct P_WatchInfoList P_WatchInfoList; -struct P_WatchInfoList { +Struct(P_WatchInfoList) +{ P_WatchInfo *first; P_WatchInfo *last; u64 count; }; -typedef struct P_Watch P_Watch; +//////////////////////////////// +//~ Window events -P_Watch *P_AllocWatch(String path); - -void P_ReleaseWatch(P_Watch *dw); - -P_WatchInfoList P_ReadWatchWait(Arena *arena, P_Watch *dw); - -void P_WakeWatch(P_Watch *dw); - -/* ========================== * - * Window - * ========================== */ - -typedef struct P_Window P_Window; - -typedef enum P_Btn { +typedef i32 P_Btn; enum +{ P_Btn_None, P_Btn_M1, @@ -277,9 +225,10 @@ typedef enum P_Btn { P_Btn_Semicolon, P_Btn_Count -} P_Btn; +}; -typedef enum P_WindowEventKind { +typedef i32 P_WindowEventKind; enum +{ P_WindowEventKind_None, P_WindowEventKind_ButtonDown, @@ -290,10 +239,10 @@ typedef enum P_WindowEventKind { P_WindowEventKind_Quit, P_WindowEventKind_Count -} P_WindowEventKind; +}; -typedef struct P_WindowEvent P_WindowEvent; -struct P_WindowEvent { +Struct(P_WindowEvent) +{ P_WindowEventKind kind; /* P_WindowEventKind_BUTTON_DOWN */ @@ -311,18 +260,22 @@ struct P_WindowEvent { V2 mouse_delta; }; -typedef struct P_WindowEventArray P_WindowEventArray; -struct P_WindowEventArray { +Struct(P_WindowEventArray) +{ u64 count; P_WindowEvent *events; }; +//////////////////////////////// +//~ Window settings + /* NOTE: * A window object can only be interacted with by the thread that created it. * This restriction is in place because of how Win32 works, IE you cannot * create a Win32 window in one thread and process its messages on another. */ -typedef enum P_WindowSettingsFlag { +typedef i32 P_WindowSettingsFlag; enum +{ P_WindowSettingsFlag_None = 0x00, P_WindowSettingsFlag_Fullscreen = 0x01, @@ -331,16 +284,17 @@ typedef enum P_WindowSettingsFlag { * restore to being maximized once it's un-minimized. */ P_WindowSettingsFlag_Maximized = 0x02, P_WindowSettingsFlag_Minimized = 0x04 -} P_WindowSettingsFlag; +}; -typedef enum P_WindowFlag { +typedef i32 P_WindowFlag; enum +{ P_WindowFlag_None = 0x00, P_WindowFlag_Showing = 0x02 -} P_WindowFlag; +}; /* P_UpdateWindowSettings should be used when altering settings values */ -typedef struct P_WindowSettings P_WindowSettings; -struct P_WindowSettings { +Struct(P_WindowSettings) +{ char title[256]; u32 flags; @@ -354,48 +308,17 @@ struct P_WindowSettings { i32 floating_height; }; -P_Window *P_AllocWindow(void); +//////////////////////////////// +//~ Address -void P_ReleaseWindow(P_Window *window); - -P_WindowEventArray P_PopWindowEvents(Arena *arena, P_Window *window); - -void P_UpdateWindowSettings(P_Window *window, P_WindowSettings *settings); - -P_WindowSettings P_GetWindowSettings(P_Window *window); - -void P_ShowWindow(P_Window *window); - -V2 P_GetWindowSize(P_Window *window); - -V2 P_GetWindowMonitorSize(P_Window *window); - -/* Returns a platform specific representation of the window. E.g. `hwnd` on win32. */ -u64 P_GetInternalWindowHandle(P_Window *window); - -void P_SetWindowCursorPos(P_Window *window, V2 pos); - -void P_ShowWindowCursor(P_Window *window); - -void P_HideWindowCursor(P_Window *window); - -void P_EnableWindoweCursorClip(P_Window *window, Rect bounds); - -void P_DisableWindoweCursorClip(P_Window *window); - -void P_ToggleWindowTopmost(P_Window *window); - -/* ========================== * - * Address - * ========================== */ - -typedef enum P_AddressFamily { +typedef i32 P_AddressFamily; enum +{ P_AddressFamily_Ipv4, P_AddressFamily_Ipv6 -} P_AddressFamily; +}; -typedef struct P_Address P_Address; -struct P_Address { +Struct(P_Address) +{ b32 valid; P_AddressFamily family; /* NOTE: ipnb & portnb are stored in network byte order */ @@ -403,80 +326,154 @@ struct P_Address { u16 portnb; }; -P_Address P_AddressFromString(String str); +//////////////////////////////// +//~ Sock -P_Address P_AddressFromIpPortCstr(char *ip_cstr, char *port_cstr); - -P_Address P_AddressFromPort(u16 port); - -String P_StringFromAddress(Arena *arena, P_Address address); - -b32 P_AddressIsEqual(P_Address a, P_Address b); - -/* ========================== * - * Sock - * ========================== */ - -typedef struct P_SockReadResult P_SockReadResult; -struct P_SockReadResult { +Struct(P_SockReadResult) +{ b32 valid; /* Since data.len = 0 can be valid */ P_Address address; String data; }; -typedef struct P_Sock P_Sock; +//////////////////////////////// +//~ Message box -P_Sock *P_AllocSock(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size); - -void P_ReleaseSock(P_Sock *sock); - -P_SockReadResult P_ReadSock(Arena *arena, P_Sock *sock); - -void P_WriteSock(P_Sock *sock, P_Address address, String data); - -/* ========================== * - * Util - * ========================== */ - -typedef enum P_MessageBoxKind { +typedef i32 P_MessageBoxKind; enum +{ P_MessageBoxKind_Ok, P_MessageBoxKind_Warning, P_MessageBoxKind_Error, P_MessageBoxKind_Fatal -} P_MessageBoxKind; - -void P_MessageBox(P_MessageBoxKind kind, String message); - -void P_SetClipboardText(String str); - -String P_GetClipboardText(Arena *arena); - -u32 P_GetLogicalProcessorCount(void); - -u32 P_GetThreadId(void); - -i64 P_GetCurrentSchedulerPeriodNs(void); - -/* ========================== * - * Exit - * ========================== */ +}; +//////////////////////////////// +//~ Exit callback function #define P_ExitFuncDef(name) void name(void) typedef P_ExitFuncDef(P_ExitFunc); -/* Registers a function to be called during graceful shutdown (in reverse order) */ -void P_OnExit(P_ExitFunc *func); +//////////////////////////////// +//~ Job helpers -/* Signals the program to shut down gracefully and run exit callbacks */ -void P_Exit(void); +void P_Run(i32 count, P_JobFunc *func, void *sig, P_Pool pool_kind, P_Priority priority, P_Counter *counter); -/* Forcefully exits the program and displays `msg` to the user */ -void P_Panic(String msg); +//////////////////////////////// +//~ Time helpers -/* ========================== * - * App entry point - * ========================== */ +P_DateTime P_LocalTime(void); +i64 P_TimeNs(void); - /* Must be defined by app */ +//////////////////////////////// +//~ File system operations + +/* NOTE: File paths use forward slash '/' as delimiter */ + +//- File system helpers +String P_GetWritePath(Arena *arena); +b32 P_IsFile(String path); +b32 P_IsDir(String path); +void P_MkDir(String path); + +//- File creation +P_File P_OpenFileRead(String path); +P_File P_OpenFileReadWait(String path); /* Waits until file is not being used by another program */ +P_File P_OpenFileWrite(String path); +P_File P_OpenFileAppend(String path); +void P_CloseFIle(P_File file); + +//- File data operations +String P_ReadFile(Arena *arena, P_File file); +void P_WriteFile(P_File file, String data); + +//- File info +u64 P_GetFileSize(P_File file); +P_FileTime P_GetFileTime(P_File file); + +//////////////////////////////// +//~ File map operations + +P_FileMap P_OpenFileMap(P_File file); +void P_CloseFileMap(P_FileMap map); +String P_GetFileMapData(P_FileMap map); + +//////////////////////////////// +//~ Watch operations + +/* A watch object allows the caller to watch for changes in a directory */ + +P_Watch *P_AllocWatch(String path); +void P_ReleaseWatch(P_Watch *dw); +P_WatchInfoList P_ReadWatchWait(Arena *arena, P_Watch *dw); +void P_WakeWatch(P_Watch *dw); + +//////////////////////////////// +//~ Window operations + +P_Window *P_AllocWindow(void); +void P_ReleaseWindow(P_Window *window); + +//- Window events +P_WindowEventArray P_PopWindowEvents(Arena *arena, P_Window *window); + +//- Window settings +void P_UpdateWindowSettings(P_Window *window, P_WindowSettings *settings); +P_WindowSettings P_GetWindowSettings(P_Window *window); +void P_ShowWindow(P_Window *window); +void P_SetWindowCursorPos(P_Window *window, V2 pos); +void P_ShowWindowCursor(P_Window *window); +void P_HideWindowCursor(P_Window *window); +void P_EnableWindoweCursorClip(P_Window *window, Rect bounds); +void P_DisableWindoweCursorClip(P_Window *window); +void P_ToggleWindowTopmost(P_Window *window); + +//- Window info +V2 P_GetWindowSize(P_Window *window); +V2 P_GetWindowMonitorSize(P_Window *window); +u64 P_GetInternalWindowHandle(P_Window *window); + +//////////////////////////////// +//~ Address helpers + +P_Address P_AddressFromString(String str); +P_Address P_AddressFromIpPortCstr(char *ip_cstr, char *port_cstr); +P_Address P_AddressFromPort(u16 port); +String P_StringFromAddress(Arena *arena, P_Address address); +b32 P_AddressIsEqual(P_Address a, P_Address b); + +//////////////////////////////// +//~ Sock operations + +P_Sock *P_AllocSock(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size); +void P_ReleaseSock(P_Sock *sock); +P_SockReadResult P_ReadSock(Arena *arena, P_Sock *sock); +void P_WriteSock(P_Sock *sock, P_Address address, String data); + +//////////////////////////////// +//~ Utils + +void P_MessageBox(P_MessageBoxKind kind, String message); +void P_SetClipboardText(String str); +String P_GetClipboardText(Arena *arena); +u32 P_GetLogicalProcessorCount(void); +u32 P_GetThreadId(void); +i64 P_GetCurrentSchedulerPeriodNs(void); + +//////////////////////////////// +//~ Sleep + +void P_SleepPrecise(i64 sleep_time_ns); +void P_SleepFrame(i64 last_frame_time_ns, i64 target_dt_ns); + +//////////////////////////////// +//~ Program exit + +void P_OnExit(P_ExitFunc *func); /* Registers a function to be called during graceful shutdown (in reverse order) */ +void P_Exit(void); /* Signals the program to shut down gracefully and run exit callbacks */ +void P_Panic(String msg); /* Forcefully exits the program and displays `msg` to the user */ + +//////////////////////////////// +//~ Entry point + +/* Must be defined by app */ void P_AppStartup(String args_str); diff --git a/src/platform/platform_log.c b/src/platform/platform_log.c index 2400753d..7663812e 100644 --- a/src/platform/platform_log.c +++ b/src/platform/platform_log.c @@ -1,72 +1,55 @@ -struct log_event_callback { - log_event_callback_func *func; - struct log_event_callback *next; - i32 level; -}; +//////////////////////////////// +//~ Global state -/* ========================== * - * Global state - * ========================== */ +P_SharedLogCtx P_shared_log_ctx = ZI; -struct shared_log_ctx { - Atomic32 initialized; - - P_Mutex callbacks_mutex; - Arena *callbacks_arena; - struct log_event_callback *first_callback; - struct log_event_callback *last_callback; - - P_File file; - b32 file_valid; -}; - -GLOBAL struct shared_log_ctx g_shared_log_ctx = ZI; -GLOBAL READONLY P_LogLevelSettings g_log_settings[LOG_LEVEL_COUNT] = { - [LOG_LEVEL_CRITICAL] = { +READONLY P_LogLevelSettings P_log_settings[P_LogLevel_Count] = { + [P_LogLevel_Critical] = { LIT_NOCAST("CRITICAL"), COLOR_PURPLE }, - [LOG_LEVEL_ERROR] = { + [P_LogLevel_Error] = { LIT_NOCAST("ERROR"), COLOR_RED }, - [LOG_LEVEL_WARNING] = { + [P_LogLevel_Warning] = { LIT_NOCAST("WARNING"), COLOR_YELLOW }, - [LOG_LEVEL_SUCCESS] = { + [P_LogLevel_Success] = { LIT_NOCAST("SUCCESS"), COLOR_GREEN }, - [LOG_LEVEL_INFO] = { + [P_LogLevel_Info] = { LIT_NOCAST("INFO"), COLOR_WHITE }, - [LOG_LEVEL_DEBUG] = { + [P_LogLevel_Debug] = { LIT_NOCAST("DEBUG"), COLOR_BLUE } }; -/* ========================== * - * Startup - * ========================== */ +//////////////////////////////// +//~ Startup -void log_startup(String logfile_path) +void P_LogStartup(String logfile_path) { __prof; - struct shared_log_ctx *ctx = &g_shared_log_ctx; + P_SharedLogCtx *ctx = &P_shared_log_ctx; ctx->callbacks_arena = arena_alloc(MEBI(8)); - if (logfile_path.len > 0) { + if (logfile_path.len > 0) + { /* Create / wipe log file */ P_CloseFIle(P_OpenFileWrite(logfile_path)); /* Keep log file open for appending */ - if (P_IsFile(logfile_path)) { + if (P_IsFile(logfile_path)) + { ctx->file = P_OpenFileAppend(logfile_path); ctx->file_valid = 1; } @@ -74,40 +57,42 @@ void log_startup(String logfile_path) atomic32_fetch_set(&ctx->initialized, 1); } -/* ========================== * - * Callback - * ========================== */ +//////////////////////////////// +//~ Callback registration -void log_register_callback(log_event_callback_func *func, i32 level) +void P_RegisterLogCallback(P_LogEventCallbackFunc *func, i32 level) { - struct shared_log_ctx *ctx = &g_shared_log_ctx; + P_SharedLogCtx *ctx = &P_shared_log_ctx; if (!atomic32_fetch(&ctx->initialized)) { return; } - P_Lock lock = snc_lock_e(&ctx->callbacks_mutex); + P_Lock lock = P_LockE(&ctx->callbacks_mutex); { - struct log_event_callback *callback = arena_push(ctx->callbacks_arena, struct log_event_callback); + LogEventCallback *callback = arena_push(ctx->callbacks_arena, LogEventCallback); callback->func = func; callback->level = level; - if (ctx->last_callback) { + if (ctx->last_callback) + { ctx->last_callback->next = callback; - } else { + } + else + { ctx->first_callback = callback; } ctx->last_callback = callback; } - snc_unlock(&lock); + P_Unlock(&lock); } -/* ========================== * - * Log - * ========================== */ +//////////////////////////////// +//~ Append -INTERNAL void append_to_logfile(String msg) +void P__LogAppend(String msg) { __prof; - struct shared_log_ctx *ctx = &g_shared_log_ctx; + P_SharedLogCtx *ctx = &P_shared_log_ctx; if (!atomic32_fetch(&ctx->initialized)) { return; } - if (ctx->file_valid) { + if (ctx->file_valid) + { TempArena scratch = scratch_begin_no_conflict(); String msg_line = string_cat(scratch.arena, msg, LIT("\n")); P_WriteFile(ctx->file, msg_line); @@ -115,45 +100,96 @@ INTERNAL void append_to_logfile(String msg) } } +//////////////////////////////// +//~ Panic + /* Panic log function is separate to enforce zero side effects other than * writing to log file. */ -void _log_panic(String msg) +void P__LogPanic(String msg) { - struct shared_log_ctx *ctx = &g_shared_log_ctx; + P_SharedLogCtx *ctx = &P_shared_log_ctx; if (!atomic32_fetch(&ctx->initialized)) { return; } - if (ctx->file_valid) { + if (ctx->file_valid) + { P_WriteFile(ctx->file, LIT("******** PANICKING ********\n")); P_WriteFile(ctx->file, msg); P_WriteFile(ctx->file, LIT("\n***************************\n")); } } -#if LOG_INCLUDE_SOURCE_LOCATION -void _log(i32 level, String file, u32 line, String msg) +//////////////////////////////// +//~ Logfv + +#if P_IncludeLogSourceLocation +void P__LogFV(i32 level, String file, u32 line, String fmt, va_list args) #else -void _log(i32 level, String msg) +void P__LogFV(i32 level, String fmt, va_list args) +#endif +{ + P_SharedLogCtx *ctx = &P_shared_log_ctx; + if (!atomic32_fetch(&ctx->initialized)) { return; } + TempArena scratch = scratch_begin_no_conflict(); + String msg = string_formatv(scratch.arena, fmt, args); +#if P_IncludeLogSourceLocation + P__log(level, file, line, msg); +#else + P__log(level, msg); +#endif + scratch_end(scratch); +} + +//////////////////////////////// +//~ Logf + +#if P_IncludeLogSourceLocation +void P__LogF(i32 level, String file, u32 line, String fmt, ...) +#else +void P__LogF(i32 level, String fmt, ...) +#endif +{ + P_SharedLogCtx *ctx = &P_shared_log_ctx; + if (!atomic32_fetch(&ctx->initialized)) { return; } + va_list args; + va_start(args, fmt); +#if P_IncludeLogSourceLocation + P__LogFV(level, file, line, fmt, args); +#else + P__LogFV(level, fmt, args); +#endif + va_end(args); +} + +//////////////////////////////// +//~ Log + +#if P_IncludeLogSourceLocation +void P__log(i32 level, String file, u32 line, String msg) +#else +void P__log(i32 level, String msg) #endif { __prof; - struct shared_log_ctx *ctx = &g_shared_log_ctx; + P_SharedLogCtx *ctx = &P_shared_log_ctx; if (!atomic32_fetch(&ctx->initialized)) { return; } + TempArena scratch = scratch_begin_no_conflict(); - if (level < 0 || level >= LOG_LEVEL_COUNT) { + P_LogLevelSettings settings = P_log_settings[level]; + if (level < 0 || level >= P_LogLevel_Count) + { P_Panic(LIT("Invalid log level")); } - TempArena scratch = scratch_begin_no_conflict(); - - P_DateTime datetime = P_LocalTime(); - i64 time_ns = P_TimeNs(); u32 tid = P_GetThreadId(); - P_LogLevelSettings settings = g_log_settings[level]; + + //- Format message + P_DateTime datetime = P_LocalTime(); + i64 time_ns = P_TimeNs(); String shorthand = settings.shorthand; -#if LOG_INCLUDE_SOURCE_LOCATION +#if P_IncludeLogSourceLocation String msg_formatted = string_format( scratch.arena, LIT("[%F:%F:%F.%F] |%F| [%F] <%F:%F> %F"), @@ -200,65 +236,30 @@ void _log(i32 level, String msg) #endif __profmsg((char *)msg.text, msg.len, settings.color); - append_to_logfile(msg_formatted); + P__LogAppend(msg_formatted); - - /* Run callbacks */ + //- Run callbacks P_LogEvent event = ZI; event.level = level; event.msg = msg; event.datetime = datetime; event.time_ns = time_ns; -#if LOG_INCLUDE_SOURCE_LOCATION +#if P_IncludeLogSourceLocation event.file = file; event.line = line; #endif { - P_Lock lock = snc_lock_s(&ctx->callbacks_mutex); - for (struct log_event_callback *callback = ctx->first_callback; callback; callback = callback->next) { - if (level <= callback->level) { + P_Lock lock = P_LockS(&ctx->callbacks_mutex); + for (LogEventCallback *callback = ctx->first_callback; callback; callback = callback->next) + { + if (level <= callback->level) + { __profn("Run log callback"); callback->func(event); } } - snc_unlock(&lock); + P_Unlock(&lock); } scratch_end(scratch); } - -#if LOG_INCLUDE_SOURCE_LOCATION -void _logfv(i32 level, String file, u32 line, String fmt, va_list args) -#else -void _logfv(i32 level, String fmt, va_list args) -#endif -{ - struct shared_log_ctx *ctx = &g_shared_log_ctx; - if (!atomic32_fetch(&ctx->initialized)) { return; } - TempArena scratch = scratch_begin_no_conflict(); - String msg = string_formatv(scratch.arena, fmt, args); -#if LOG_INCLUDE_SOURCE_LOCATION - _log(level, file, line, msg); -#else - _log(level, msg); -#endif - scratch_end(scratch); -} - -#if LOG_INCLUDE_SOURCE_LOCATION -void _logf(i32 level, String file, u32 line, String fmt, ...) -#else -void _logf(i32 level, String fmt, ...) -#endif -{ - struct shared_log_ctx *ctx = &g_shared_log_ctx; - if (!atomic32_fetch(&ctx->initialized)) { return; } - va_list args; - va_start(args, fmt); -#if LOG_INCLUDE_SOURCE_LOCATION - _logfv(level, file, line, fmt, args); -#else - _logfv(level, fmt, args); -#endif - va_end(args); -} diff --git a/src/platform/platform_log.h b/src/platform/platform_log.h index c2fdb23a..4689b58f 100644 --- a/src/platform/platform_log.h +++ b/src/platform/platform_log.h @@ -1,40 +1,9 @@ -#define LOG_LEVEL(l) (l <= LOG_LEVEL_COMPTIME) +//////////////////////////////// +//~ Log event types -/* Log level configuration */ -#ifndef LOG_LEVEL_COMPTIME -# if RTC || PROFILING -# define LOG_LEVEL_COMPTIME LOG_LEVEL_DEBUG -# else -# define LOG_LEVEL_COMPTIME LOG_LEVEL_INFO -# endif -#endif - -/* Source location configuration */ -#ifndef LOG_INCLUDE_SOURCE_LOCATION -# define LOG_INCLUDE_SOURCE_LOCATION (DEBINFO) -#endif - -#define LOG_LEVEL_NONE -1 -#define LOG_LEVEL_CRITICAL 0 -#define LOG_LEVEL_ERROR 1 -#define LOG_LEVEL_WARNING 2 -#define LOG_LEVEL_SUCCESS 3 -#define LOG_LEVEL_INFO 4 -#define LOG_LEVEL_DEBUG 5 -#define LOG_LEVEL_COUNT 6 - -/* ========================== * - * Callback interface - * ========================== */ - -typedef struct P_LogLevelSettings P_LogLevelSettings; -struct P_LogLevelSettings { - String shorthand; - u32 color; -}; - -typedef struct P_LogEvent P_LogEvent; -struct P_LogEvent { +//- Event +Struct(P_LogEvent) +{ /* Msg lifetime is only as long as callback duration */ String msg; i32 level; @@ -42,122 +11,193 @@ struct P_LogEvent { P_DateTime datetime; i64 time_ns; - /* These will be zeroed if LOG_INCLUDE_SOURCE_LOCATION is disabled */ + /* These will be zeroed if P_IncludeLogSourceLocation is disabled */ String file; i32 line; }; -#define LOG_EVENT_CALLBACK_FUNC_DEF(name, log_event_arg) void name(P_LogEvent log_event_arg) -typedef LOG_EVENT_CALLBACK_FUNC_DEF(log_event_callback_func, log_event); +//- Callback +#define P_LogEventCallbackFuncDef(name, log_event_arg) void name(P_LogEvent log_event_arg) +typedef P_LogEventCallbackFuncDef(P_LogEventCallbackFunc, log_event); -void log_register_callback(log_event_callback_func *func, i32 level); +Struct(LogEventCallback) +{ + P_LogEventCallbackFunc *func; + LogEventCallback *next; + i32 level; +}; -/* ========================== * - * Logging macros - * ========================== */ +//////////////////////////////// +//~ Logging levels -#define log_panic(msg) _log_panic(msg) +#define P_LogLevel(l) (l <= P_LogLevel_CompTime) -#if LOG_LEVEL(LOG_LEVEL_CRITICAL) -# if LOG_INCLUDE_SOURCE_LOCATION -# define log_critical(msg) _log(LOG_LEVEL_CRITICAL, LIT(__FILE__), __LINE__, msg) -# define logf_critical(fmt_lit, ...) _logf(LOG_LEVEL_CRITICAL, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +/* Log level configuration */ +#ifndef P_LogLevel_CompTime +# if RTC || PROFILING +# define P_LogLevel_CompTime P_LogLevel_Debug # else -# define log_critical(msg) _log(LOG_LEVEL_CRITICAL, msg) -# define logf_critical(fmt_lit, ...) _logf(LOG_LEVEL_CRITICAL, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +# define P_LogLevel_CompTime P_LogLevel_Info +# endif +#endif + +/* Source location configuration */ +#ifndef P_IncludeLogSourceLocation +# define P_IncludeLogSourceLocation (DEBINFO) +#endif + +#define P_LogLevel_None -1 +#define P_LogLevel_Critical 0 +#define P_LogLevel_Error 1 +#define P_LogLevel_Warning 2 +#define P_LogLevel_Success 3 +#define P_LogLevel_Info 4 +#define P_LogLevel_Debug 5 +#define P_LogLevel_Count 6 + +//////////////////////////////// +//~ Shared state + +//- Shared context +Struct(P_SharedLogCtx) +{ + Atomic32 initialized; + + P_Mutex callbacks_mutex; + Arena *callbacks_arena; + LogEventCallback *first_callback; + LogEventCallback *last_callback; + + P_File file; + b32 file_valid; +}; + +extern P_SharedLogCtx P_shared_log_ctx; + +//-- Log level settings +Struct(P_LogLevelSettings) +{ + String shorthand; + u32 color; +}; + +extern READONLY P_LogLevelSettings P_log_settings[P_LogLevel_Count]; + +//////////////////////////////// +//~ Startup + +void P_LogStartup(String logfile_path); + +//////////////////////////////// +//~ Logging macros + +#define log_panic(msg) P__LogPanic(msg) + +#if P_LogLevel(P_LogLevel_Critical) +# if P_IncludeLogSourceLocation +# define P_LogCritical(msg) P__log(P_LogLevel_Critical, LIT(__FILE__), __LINE__, msg) +# define P_LogCriticalF(fmt_lit, ...) P__LogF(P_LogLevel_Critical, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +# else +# define P_LogCritical(msg) P__log(P_LogLevel_Critical, msg) +# define P_LogCriticalF(fmt_lit, ...) P__LogF(P_LogLevel_Critical, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # endif #else -# define log_critical(msg) -# define logf_critical(...) +# define P_LogCritical(msg) +# define P_LogCriticalF(...) #endif -#if LOG_LEVEL(LOG_LEVEL_ERROR) -# if LOG_INCLUDE_SOURCE_LOCATION -# define log_error(msg) _log(LOG_LEVEL_ERROR, LIT(__FILE__), __LINE__, msg) -# define logf_error(fmt_lit, ...) _logf(LOG_LEVEL_ERROR, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +#if P_LogLevel(P_LogLevel_Error) +# if P_IncludeLogSourceLocation +# define P_LogError(msg) P__log(P_LogLevel_Error, LIT(__FILE__), __LINE__, msg) +# define P_LogErrorF(fmt_lit, ...) P__LogF(P_LogLevel_Error, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # else -# define log_error(msg) _log(LOG_LEVEL_ERROR, msg) -# define logf_error(fmt_lit, ...) _logf(LOG_LEVEL_ERROR, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +# define P_LogError(msg) P__log(P_LogLevel_Error, msg) +# define P_LogErrorF(fmt_lit, ...) P__LogF(P_LogLevel_Error, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # endif #else -# define log_error(msg) -# define logf_error(...) +# define P_LogError(msg) +# define P_LogErrorF(...) #endif -#if LOG_LEVEL(LOG_LEVEL_WARNING) -# if LOG_INCLUDE_SOURCE_LOCATION -# define log_warning(msg) _log(LOG_LEVEL_WARNING, LIT(__FILE__), __LINE__, msg) -# define logf_warning(fmt_lit, ...) _logf(LOG_LEVEL_WARNING, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +#if P_LogLevel(P_LogLevel_Warning) +# if P_IncludeLogSourceLocation +# define P_LogWarning(msg) P__log(P_LogLevel_Warning, LIT(__FILE__), __LINE__, msg) +# define P_LogWarningF(fmt_lit, ...) P__LogF(P_LogLevel_Warning, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # else -# define log_warning(msg) _log(LOG_LEVEL_WARNING, msg) -# define logf_warning(fmt_lit, ...) _logf(LOG_LEVEL_WARNING, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +# define P_LogWarning(msg) P__log(P_LogLevel_Warning, msg) +# define P_LogWarningF(fmt_lit, ...) P__LogF(P_LogLevel_Warning, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # endif #else -# define log_warning(msg) -# define logf_warning(...) +# define P_LogWarning(msg) +# define P_LogWarningF(...) #endif -#if LOG_LEVEL(LOG_LEVEL_SUCCESS) -# if LOG_INCLUDE_SOURCE_LOCATION -# define log_success(msg) _log(LOG_LEVEL_SUCCESS, LIT(__FILE__), __LINE__, msg) -# define logf_success(fmt_lit, ...) _logf(LOG_LEVEL_SUCCESS, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +#if P_LogLevel(P_LogLevel_Success) +# if P_IncludeLogSourceLocation +# define P_LogSuccess(msg) P__log(P_LogLevel_Success, LIT(__FILE__), __LINE__, msg) +# define P_LogSuccessF(fmt_lit, ...) P__LogF(P_LogLevel_Success, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # else -# define log_success(msg) _log(LOG_LEVEL_SUCCESS, msg) -# define logf_success(fmt_lit, ...) _logf(LOG_LEVEL_SUCCESS, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +# define P_LogSuccess(msg) P__log(P_LogLevel_Success, msg) +# define P_LogSuccessF(fmt_lit, ...) P__LogF(P_LogLevel_Success, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # endif #else -# define log_success(msg) -# define logf_success(...) +# define P_LogSuccess(msg) +# define P_LogSuccessF(...) #endif -#if LOG_LEVEL(LOG_LEVEL_INFO) -# if LOG_INCLUDE_SOURCE_LOCATION -# define log_info(msg) _log(LOG_LEVEL_INFO, LIT(__FILE__), __LINE__, msg) -# define logf_info(fmt_lit, ...) _logf(LOG_LEVEL_INFO, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +#if P_LogLevel(P_LogLevel_Info) +# if P_IncludeLogSourceLocation +# define P_LogInfo(msg) P__log(P_LogLevel_Info, LIT(__FILE__), __LINE__, msg) +# define P_LogInfoF(fmt_lit, ...) P__LogF(P_LogLevel_Info, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # else -# define log_info(msg) _log(LOG_LEVEL_INFO, msg) -# define logf_info(fmt_lit, ...) _logf(LOG_LEVEL_INFO, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +# define P_LogInfo(msg) P__log(P_LogLevel_Info, msg) +# define P_LogInfoF(fmt_lit, ...) P__LogF(P_LogLevel_Info, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # endif #else -# define log_info(msg) -# define logf_info(...) +# define P_LogInfo(msg) +# define P_LogInfoF(...) #endif -#if LOG_LEVEL(LOG_LEVEL_DEBUG) -# if LOG_INCLUDE_SOURCE_LOCATION -# define log_debug(msg) _log(LOG_LEVEL_DEBUG, LIT(__FILE__), __LINE__, msg) -# define logf_debug(fmt_lit, ...) _logf(LOG_LEVEL_DEBUG, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +#if P_LogLevel(P_LogLevel_Debug) +# if P_IncludeLogSourceLocation +# define P_LogDebug(msg) P__log(P_LogLevel_Debug, LIT(__FILE__), __LINE__, msg) +# define P_LogDebugF(fmt_lit, ...) P__LogF(P_LogLevel_Debug, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # else -# define log_debug(msg) _log(LOG_LEVEL_DEBUG, msg) -# define logf_debug(fmt_lit, ...) _logf(LOG_LEVEL_DEBUG, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) +# define P_LogDebug(msg) P__log(P_LogLevel_Debug, msg) +# define P_LogDebugF(fmt_lit, ...) P__LogF(P_LogLevel_Debug, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END) # endif #else -# define log_debug(msg) -# define logf_debug(...) +# define P_LogDebug(msg) +# define P_LogDebugF(...) #endif -/* ========================== * - * Function declarations - * ========================== */ +//////////////////////////////// +//~ Callback registration -void log_startup(String logfile_path); +void P_RegisterLogCallback(P_LogEventCallbackFunc *func, i32 level); -void _log_panic(String msg); +//////////////////////////////// +//~ Raw log operations -#if LOG_INCLUDE_SOURCE_LOCATION -void _log(i32 level, String file, u32 line, String msg); +/* NOTE: Calling these functions rather than using the logging macros may result in logs that are compiled regardless of log level. */ + +void P__LogAppend(String msg); +void P__LogPanic(String msg); + +#if P_IncludeLogSourceLocation +void P__LogFV(i32 level, String file, u32 line, String fmt, va_list args); #else -void _log(i32 level, String msg); +void P__LogFV(i32 level, String fmt, va_list args); #endif -#if LOG_INCLUDE_SOURCE_LOCATION -void _logfv(i32 level, String file, u32 line, String fmt, va_list args); +#if P_IncludeLogSourceLocation +void P__LogF(i32 level, String file, u32 line, String fmt, ...); #else -void _logfv(i32 level, String fmt, va_list args); +void P__LogF(i32 level, String fmt, ...); #endif -#if LOG_INCLUDE_SOURCE_LOCATION -void _logf(i32 level, String file, u32 line, String fmt, ...); +#if P_IncludeLogSourceLocation +void P__log(i32 level, String file, u32 line, String msg); #else -void _logf(i32 level, String fmt, ...); +void P__log(i32 level, String msg); #endif diff --git a/src/platform/platform_sleep.c b/src/platform/platform_sleep.c deleted file mode 100644 index 3e80e7ac..00000000 --- a/src/platform/platform_sleep.c +++ /dev/null @@ -1,39 +0,0 @@ -void sys_sleep_precise(i64 sleep_time_ns) -{ - __prof; - - i64 big_sleep = P_GetCurrentSchedulerPeriodNs(); - i64 tolerance = (f64)big_sleep * 0.5; - //i64 tolerance = 1000000000; - - i64 now_ns = P_TimeNs(); - i64 target_ns = now_ns + sleep_time_ns; - - /* Sleep */ - while (now_ns < target_ns - big_sleep - tolerance) { - __profn("Sleep part"); - P_Wait(0, 0, 0, big_sleep); - now_ns = P_TimeNs(); - } - - /* Spin */ - { - __profn("Sleep spin"); - while (now_ns < target_ns) { - ix_pause(); - now_ns = P_TimeNs(); - } - } -} - -void sys_sleep_frame(i64 last_frame_time_ns, i64 target_dt_ns) -{ - if (last_frame_time_ns != 0 && target_dt_ns > 0) { - i64 now_ns = P_TimeNs(); - i64 last_frame_dt_ns = now_ns - last_frame_time_ns; - i64 sleep_time_ns = target_dt_ns - last_frame_dt_ns; - if (sleep_time_ns > 0) { - sys_sleep_precise(sleep_time_ns); - } - } -} diff --git a/src/platform/platform_sleep.h b/src/platform/platform_sleep.h deleted file mode 100644 index b807c12e..00000000 --- a/src/platform/platform_sleep.h +++ /dev/null @@ -1,3 +0,0 @@ -void sys_sleep_precise(i64 sleep_time_ns); - -void sys_sleep_frame(i64 last_frame_time_ns, i64 target_dt_ns); diff --git a/src/platform/platform_snc.c b/src/platform/platform_snc.c index 93744741..b60244b7 100644 --- a/src/platform/platform_snc.c +++ b/src/platform/platform_snc.c @@ -1,44 +1,54 @@ -#define DEFAULT_MUTEX_SPIN 4000 +//////////////////////////////// +//~ Mutex -/* ========================== * - * Mutex - * ========================== */ - -P_Lock snc_lock_spin_e(P_Mutex *m, i32 spin) +//- Exclusive mutex lock +P_Lock P_LockSpinE(P_Mutex *m, i32 spin) { b32 locked = 0; i32 spin_cnt = 0; - while (!locked) { + while (!locked) + { ++spin_cnt; u32 v = atomic32_fetch_test_set(&m->v, 0, 0x80000000); - if (v == 0) { + if (v == 0) + { locked = 1; - } else if (v == 0x40000000) { + } + else if (v == 0x40000000) + { /* Lock has pending bit set, try to lock */ u32 swp = atomic32_fetch_test_set(&m->v, v, 0x80000000); - while (swp != v && swp == 0x40000000) { + while (swp != v && swp == 0x40000000) + { v = swp; swp = atomic32_fetch_test_set(&m->v, v, 0x80000000); } v = swp; - if (v == 0x40000000) { + if (v == 0x40000000) + { locked = 1; } } - if (!locked && (v & 0xC0000000) == 0) { + if (!locked && (v & 0xC0000000) == 0) + { /* Lock has shared lockers and no pending waiter, set pending bit */ u32 swp = atomic32_fetch_test_set(&m->v, v, v | 0x40000000); - while (swp != v && (swp & 0xC0000000) == 0 && swp != 0) { + while (swp != v && (swp & 0xC0000000) == 0 && swp != 0) + { v = swp; swp = atomic32_fetch_test_set(&m->v, v, v | 0x40000000); } v = swp; } /* Pause or wait */ - if (!locked && v != 0 && v != 0x40000000) { - if (spin_cnt < spin) { + if (!locked && v != 0 && v != 0x40000000) + { + if (spin_cnt < spin) + { ix_pause(); - } else { + } + else + { P_Wait(&m->v, &v, 4, I64_MAX); spin_cnt = 0; } @@ -55,27 +65,37 @@ P_Lock snc_lock_spin_e(P_Mutex *m, i32 spin) return lock; } -P_Lock snc_lock_spin_s(P_Mutex *m, i32 spin) +//- Shared mutex lock +P_Lock P_LockSpinS(P_Mutex *m, i32 spin) { b32 locked = 0; i32 spin_cnt = 0; - while (!locked) { + while (!locked) + { ++spin_cnt; u32 v = atomic32_fetch(&m->v); - while (!locked && (v & 0xC0000000) == 0) { + while (!locked && (v & 0xC0000000) == 0) + { /* Lock has no exclusive or pending exclusive lock, increment shared count */ u32 swp = atomic32_fetch_test_set(&m->v, v, v + 1); - if (v == swp) { + if (v == swp) + { locked = 1; - } else { + } + else + { v = swp; } } /* Pause or wait */ - if (!locked) { - if (spin_cnt < spin) { + if (!locked) + { + if (spin_cnt < spin) + { ix_pause(); - } else { + } + else + { P_Wait(&m->v, &v, 4, I64_MAX); spin_cnt = 0; } @@ -86,81 +106,88 @@ P_Lock snc_lock_spin_s(P_Mutex *m, i32 spin) return lock; } -P_Lock snc_lock_e(P_Mutex *m) +//- Mutex lock wrappers +P_Lock P_LockE(P_Mutex *m) { - return snc_lock_spin_e(m, DEFAULT_MUTEX_SPIN); + return P_LockSpinE(m, P_DefaultMutexSpin); } -P_Lock snc_lock_s(P_Mutex *m) +P_Lock P_LockS(P_Mutex *m) { - return snc_lock_spin_s(m, DEFAULT_MUTEX_SPIN); + return P_LockSpinS(m, P_DefaultMutexSpin); } -void snc_unlock(P_Lock *l) +void P_Unlock(P_Lock *l) { P_Mutex *m = l->mutex; - if (l->exclusive) { + if (l->exclusive) + { #if RTC atomic32_fetch_set(&m->exclusive_fiber_id, 0); #endif atomic32_fetch_set(&m->v, 0); - } else { + } + else + { atomic32_fetch_add(&m->v, -1); } P_Wake(&m->v, I32_MAX); MEMZERO_STRUCT(l); } -/* ========================== * - * Condition variable - * ========================== */ +//////////////////////////////// +//~ Condition variable -void snc_cv_wait(P_Cv *cv, P_Lock *l) +void P_WaitOnCv(P_Cv *cv, P_Lock *l) { - snc_cv_wait_time(cv, l, I64_MAX); + P_WaitOnCvTime(cv, l, I64_MAX); } -void snc_cv_wait_time(P_Cv *cv, P_Lock *l, i64 timeout_ns) +void P_WaitOnCvTime(P_Cv *cv, P_Lock *l, i64 timeout_ns) { u64 old_wake_gen = atomic64_fetch(&cv->wake_gen); P_Mutex *mutex = l->mutex; b32 exclusive = l->exclusive; { - snc_unlock(l); + P_Unlock(l); { P_Wait(&cv->wake_gen, &old_wake_gen, sizeof(old_wake_gen), timeout_ns); } - if (exclusive) { - *l = snc_lock_e(mutex); - } else { - *l = snc_lock_s(mutex); + if (exclusive) + { + *l = P_LockE(mutex); + } + else + { + *l = P_LockS(mutex); } } } -void snc_cv_signal(P_Cv *cv, i32 count) +void P_SignalCv(P_Cv *cv, i32 count) { atomic64_fetch_add(&cv->wake_gen, 1); P_Wake(&cv->wake_gen, count); } -/* ========================== * - * Counter - * ========================== */ +//////////////////////////////// +//~ Counter -void snc_counter_add(P_Counter *counter, i64 x) +void P_CounterAdd(P_Counter *counter, i64 x) { i64 old_v = atomic64_fetch_add(&counter->v, x); i64 new_v = old_v + x; - if (old_v > 0 && new_v <= 0) { + if (old_v > 0 && new_v <= 0) + { P_Wake(&counter->v, I32_MAX); } } -void snc_counter_wait(P_Counter *counter) +void P_WaitOnCounter(P_Counter *counter) { i64 v = atomic64_fetch(&counter->v); - while (v > 0) { + while (v > 0) + { P_Wait(&counter->v, &v, sizeof(v), I64_MAX); v = atomic64_fetch(&counter->v); } diff --git a/src/platform/platform_snc.h b/src/platform/platform_snc.h index aa7b5394..faf64958 100644 --- a/src/platform/platform_snc.h +++ b/src/platform/platform_snc.h @@ -1,9 +1,10 @@ -/* ========================== * - * Mutex - * ========================== */ +//////////////////////////////// +//~ Mutex types -typedef struct P_Mutex P_Mutex; -struct alignas(64) P_Mutex { +#define P_DefaultMutexSpin 4000 + +AlignedStruct(P_Mutex, 64) +{ /* Bit 31 = Exclusive lock is held * Bit 30 = Exclusive lock is pending * Bit 0-30 = Shared locks count @@ -20,53 +21,63 @@ struct alignas(64) P_Mutex { STATIC_ASSERT(sizeof(P_Mutex) == 64); /* Padding validation */ STATIC_ASSERT(alignof(P_Mutex) == 64); /* Prevent false sharing */ -typedef struct P_Lock P_Lock; -struct P_Lock { +Struct(P_Lock) +{ P_Mutex *mutex; b32 exclusive; }; -P_Lock snc_lock_spin_e(P_Mutex *m, i32 spin); -P_Lock snc_lock_spin_s(P_Mutex *m, i32 spin); -P_Lock snc_lock_e(P_Mutex *m); -P_Lock snc_lock_s(P_Mutex *m); -void snc_unlock(P_Lock *lock); +//////////////////////////////// +//~ Condition variable types -#if RTC -# define snc_assert_locked_e(l, m) ASSERT((l)->mutex == (m) && (l)->exclusive == 1) -# define snc_assert_locked_e_or_s(l, m) ASSERT((l)->mutex == (m)) -#else -# define snc_assert_locked_e(l, m) (UNUSED)l -# define snc_assert_locked_e_or_s(l, m) (UNUSED)l -#endif - -/* ========================== * - * Condition variable - * ========================== */ - -typedef struct P_Cv P_Cv; -struct alignas(64) P_Cv { +AlignedStruct(P_Cv, 64) +{ Atomic64 wake_gen; u8 _pad[56]; }; STATIC_ASSERT(sizeof(P_Cv) == 64); /* Padding validation */ STATIC_ASSERT(alignof(P_Cv) == 64); /* Prevent false sharing */ -void snc_cv_wait(P_Cv *cv, P_Lock *lock); -void snc_cv_wait_time(P_Cv *cv, P_Lock *l, i64 timeout_ns); -void snc_cv_signal(P_Cv *cv, i32 count); +//////////////////////////////// +//~ Counter types -/* ========================== * - * Counter - * ========================== */ - -typedef struct P_Counter P_Counter; -struct alignas(64) P_Counter { +AlignedStruct(P_Counter, 64) +{ Atomic64 v; u8 _pad[56]; }; STATIC_ASSERT(sizeof(P_Counter) == 64); /* Padding validation */ STATIC_ASSERT(alignof(P_Counter) == 64); /* Prevent false sharing */ -void snc_counter_add(P_Counter *counter, i64 x); -void snc_counter_wait(P_Counter *counter); +//////////////////////////////// +//~ Mutex operations + +P_Lock P_LockSpinE(P_Mutex *m, i32 spin); +P_Lock P_LockSpinS(P_Mutex *m, i32 spin); + +P_Lock P_LockE(P_Mutex *m); +P_Lock P_LockS(P_Mutex *m); + +void P_Unlock(P_Lock *lock); + +//- Lock assertion +#if RTC +# define P_AssertLockedE(l, m) ASSERT((l)->mutex == (m) && (l)->exclusive == 1) +# define P_AssertLockedES(l, m) ASSERT((l)->mutex == (m)) +#else +# define P_AssertLockedE(l, m) (UNUSED)l +# define P_AssertLockedES(l, m) (UNUSED)l +#endif + +//////////////////////////////// +//~ Condition variable operations + +void P_WaitOnCv(P_Cv *cv, P_Lock *lock); +void P_WaitOnCvTime(P_Cv *cv, P_Lock *l, i64 timeout_ns); +void P_SignalCv(P_Cv *cv, i32 count); + +//////////////////////////////// +//~ Counter operations + +void P_CounterAdd(P_Counter *counter, i64 x); +void P_WaitOnCounter(P_Counter *counter); diff --git a/src/platform/platform_win32.c b/src/platform/platform_win32.c index 8f5d7d14..050ed176 100644 --- a/src/platform/platform_win32.c +++ b/src/platform/platform_win32.c @@ -1,3 +1,8 @@ +P_W32_SharedCtx P_W32_shared_ctx = ZI; + +//////////////////////////////// +//~ Win32 libs + #pragma comment(lib, "kernel32") #pragma comment(lib, "user32") #pragma comment(lib, "shell32") @@ -9,16 +14,14 @@ #pragma comment(lib, "avrt") #pragma comment(lib, "ws2_32.lib") -P_W32_Ctx P_W32_g_shared_ctx = ZI; - -/* ========================== * - * Ticket mutex - * ========================== */ +//////////////////////////////// +//~ Win32 ticket mutex void P_W32_LockTicketMutex(P_W32_TicketMutex *tm) { i64 ticket = atomic64_fetch_add(&tm->ticket.v, 1); - while (atomic64_fetch(&tm->serving.v) != ticket) { + while (atomic64_fetch(&tm->serving.v) != ticket) + { ix_pause(); } } @@ -28,9 +31,8 @@ void P_W32_UnlockTicketMutex(P_W32_TicketMutex *tm) atomic64_fetch_add(&tm->serving.v, 1); } -/* ========================== * - * Win32 thread - * ========================== */ +//////////////////////////////// +//~ Win32 thread DWORD WINAPI P_W32_Win32ThreadProc(LPVOID vt) { @@ -43,11 +45,12 @@ DWORD WINAPI P_W32_Win32ThreadProc(LPVOID vt) CoInitializeEx(0, COINIT_MULTITHREADED); /* Set thread name */ - if (t->thread_name_wstr[0] != 0) { + if (t->thread_name_wstr[0] != 0) + { SetThreadDescription(GetCurrentThread(), t->thread_name_wstr); } - logf_info("New thread \"%F\" created with ID %F", FMT_STR(string_from_cstr_no_limit(t->thread_name_cstr)), FMT_UINT(P_GetThreadId())); + P_LogInfoF("New thread \"%F\" created with ID %F", FMT_STR(string_from_cstr_no_limit(t->thread_name_cstr)), FMT_UINT(P_GetThreadId())); /* Enter thread entry point */ t->entry_point(t->thread_data); @@ -62,30 +65,36 @@ P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data { __prof; TempArena scratch = scratch_begin_no_conflict(); - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; ASSERT(entry_point != 0); - logf_info("Creating thread \"%F\"", FMT_STR(thread_name)); + P_LogInfoF("Creating thread \"%F\"", FMT_STR(thread_name)); /* Allocate thread object */ P_W32_Thread *t = 0; { - P_Lock lock = snc_lock_e(&g->threads_mutex); - if (g->first_free_thread) { + P_Lock lock = P_LockE(&g->threads_mutex); + if (g->first_free_thread) + { t = g->first_free_thread; g->first_free_thread = t->next; - } else { + } + else + { t = arena_push_no_zero(g->threads_arena, P_W32_Thread); } MEMZERO_STRUCT(t); - if (g->last_thread) { + if (g->last_thread) + { g->last_thread->next = t; t->prev = g->last_thread; - } else { + } + else + { g->first_thread = t; } g->last_thread = t; - snc_unlock(&lock); + P_Unlock(&lock); } @@ -115,7 +124,8 @@ P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data 0 ); - if (!t->handle) { + if (!t->handle) + { P_Panic(LIT("Failed to create thread")); } @@ -127,37 +137,45 @@ P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data b32 P_W32_TryReleaseThread(P_W32_Thread *thread, f32 timeout_seconds) { __prof; - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; b32 success = 0; P_W32_Thread *t = (P_W32_Thread *)thread; HANDLE handle = t->handle; - if (handle) { + if (handle) + { /* Wait for thread to stop */ DWORD timeout_ms = (timeout_seconds > 10000000) ? INFINITE : math_round_to_int(timeout_seconds * 1000); DWORD wait_res = WaitForSingleObject(handle, timeout_ms); - if (wait_res == WAIT_OBJECT_0) { + if (wait_res == WAIT_OBJECT_0) + { /* Release thread */ success = 1; CloseHandle(handle); { - P_Lock lock = snc_lock_e(&g->threads_mutex); + P_Lock lock = P_LockE(&g->threads_mutex); { P_W32_Thread *prev = t->prev; P_W32_Thread *next = t->next; - if (prev) { + if (prev) + { prev->next = next; - } else { + } + else + { g->first_thread = next; } - if (next) { + if (next) + { next->prev = prev; - } else { + } + else + { g->last_thread = prev; } t->next = g->first_free_thread; g->first_free_thread = t; } - snc_unlock(&lock); + P_Unlock(&lock); } } } @@ -172,17 +190,17 @@ void P_W32_WaitReleaseThread(P_W32_Thread *thread) (UNUSED)success; } -/* ========================== * - * Win32 Wait / wake - * ========================== */ +//////////////////////////////// +//~ Win32 wait list /* REQUIRED: Caller must have acquired `wake_lock` for each fiber in array */ void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; /* Update wait lists */ - for (i32 i = 0; i < num_fibers; ++i) { + for (i32 i = 0; i < num_fibers; ++i) + { P_W32_Fiber *fiber = fibers[i]; u64 wait_addr = fiber->wait_addr; u64 wait_time = fiber->wait_time; @@ -193,54 +211,76 @@ void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers) P_W32_WaitBin *wait_time_bin = 0; P_W32_WaitList *wait_addr_list = 0; P_W32_WaitList *wait_time_list = 0; - if (wait_addr != 0) { + if (wait_addr != 0) + { wait_addr_bin = &g->wait_addr_bins[wait_addr % P_W32_NumWaitAddrBins]; P_W32_LockTicketMutex(&wait_addr_bin->lock); - for (P_W32_WaitList *tmp = wait_addr_bin->first_wait_list; tmp && !wait_addr_list; tmp = tmp->next_in_bin) { - if (tmp->value == (u64)wait_addr) { + for (P_W32_WaitList *tmp = wait_addr_bin->first_wait_list; tmp && !wait_addr_list; tmp = tmp->next_in_bin) + { + if (tmp->value == (u64)wait_addr) + { wait_addr_list = tmp; } } } - if (wait_time != 0) { + if (wait_time != 0) + { wait_time_bin = &g->wait_time_bins[wait_time % P_W32_NumWaitTimeBins]; P_W32_LockTicketMutex(&wait_time_bin->lock); - for (P_W32_WaitList *tmp = wait_time_bin->first_wait_list; tmp && !wait_time_list; tmp = tmp->next_in_bin) { - if (tmp->value == (u64)wait_time) { + for (P_W32_WaitList *tmp = wait_time_bin->first_wait_list; tmp && !wait_time_list; tmp = tmp->next_in_bin) + { + if (tmp->value == (u64)wait_time) + { wait_time_list = tmp; } } } { /* Remove from addr list */ - if (wait_addr_list) { - if (--wait_addr_list->num_waiters == 0) { + if (wait_addr_list) + { + if (--wait_addr_list->num_waiters == 0) + { /* Free addr list */ P_W32_WaitList *prev = wait_addr_list->prev_in_bin; P_W32_WaitList *next = wait_addr_list->next_in_bin; - if (prev) { + if (prev) + { prev->next_in_bin = next; - } else { + } + else + { wait_addr_bin->first_wait_list = next; } - if (next) { + if (next) + { next->prev_in_bin = prev; - } else { + } + else + { wait_addr_bin->last_wait_list = prev; } wait_addr_list->next_in_bin = wait_addr_bin->first_free_wait_list; wait_addr_bin->first_free_wait_list = wait_addr_list; - } else { + } + else + { i16 prev_id = fiber->prev_addr_waiter; i16 next_id = fiber->next_addr_waiter; - if (prev_id) { + if (prev_id) + { P_W32_FiberFromId(prev_id)->next_addr_waiter = next_id; - } else { + } + else + { wait_addr_list->first_waiter = next_id; } - if (next_id) { + if (next_id) + { P_W32_FiberFromId(next_id)->prev_addr_waiter = prev_id; - } else { + } + else + { wait_addr_list->last_waiter = prev_id; } } @@ -249,34 +289,50 @@ void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers) fiber->next_addr_waiter = 0; } /* Remove from time list */ - if (wait_time_list) { - if (--wait_time_list->num_waiters == 0) { + if (wait_time_list) + { + if (--wait_time_list->num_waiters == 0) + { /* Free time list */ P_W32_WaitList *prev = wait_time_list->prev_in_bin; P_W32_WaitList *next = wait_time_list->next_in_bin; - if (prev) { + if (prev) + { prev->next_in_bin = next; - } else { + } + else + { wait_time_bin->first_wait_list = next; } - if (next) { + if (next) + { next->prev_in_bin = prev; - } else { + } + else + { wait_time_bin->last_wait_list = prev; } wait_time_list->next_in_bin = wait_time_bin->first_free_wait_list; wait_time_bin->first_free_wait_list = wait_time_list; - } else { + } + else + { i16 prev_id = fiber->prev_time_waiter; i16 next_id = fiber->next_time_waiter; - if (prev_id) { + if (prev_id) + { P_W32_FiberFromId(prev_id)->next_time_waiter = next_id; - } else { + } + else + { wait_time_list->first_waiter = next_id; } - if (next_id) { + if (next_id) + { P_W32_FiberFromId(next_id)->prev_time_waiter = prev_id; - } else { + } + else + { wait_time_list->last_waiter = prev_id; } } @@ -295,7 +351,8 @@ void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers) /* Resume jobs */ /* TODO: Batch submit waiters based on queue kind rather than one at a time */ i32 job_counts_per_pool[P_Pool_Count] = ZI; - for (i32 i = 0; i < num_fibers; ++i) { + for (i32 i = 0; i < num_fibers; ++i) + { P_W32_Fiber *fiber = fibers[i]; P_Pool pool_kind = fiber->job_pool; ++job_counts_per_pool[pool_kind]; @@ -304,10 +361,13 @@ void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers) P_W32_LockTicketMutex(&queue->lock); { P_W32_JobInfo *info = 0; - if (queue->first_free) { + if (queue->first_free) + { info = queue->first_free; queue->first_free = info->next; - } else { + } + else + { info = arena_push_no_zero(queue->arena, P_W32_JobInfo); } MEMZERO_STRUCT(info); @@ -317,9 +377,12 @@ void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers) info->sig = fiber->job_sig; info->counter = fiber->job_counter; info->fiber_id = fiber->id; - if (queue->first) { + if (queue->first) + { info->next = queue->first; - } else { + } + else + { queue->last = info; } queue->first = info; @@ -328,18 +391,25 @@ void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers) } /* Wake workers */ - if (num_fibers > 0) { - for (P_Pool pool_kind = 0; pool_kind < (i32)countof(job_counts_per_pool); ++pool_kind) { + if (num_fibers > 0) + { + for (P_Pool pool_kind = 0; pool_kind < (i32)countof(job_counts_per_pool); ++pool_kind) + { i32 job_count = job_counts_per_pool[pool_kind]; - if (job_count > 0) { + if (job_count > 0) + { P_W32_JobPool *pool = &g->job_pools[pool_kind]; P_W32_LockTicketMutex(&pool->workers_wake_lock); { atomic64_fetch_add(&pool->num_jobs_in_queue.v, job_count); - if (job_count >= P_W32_WakeAllThreshold) { + if (job_count >= P_W32_WakeAllThreshold) + { WakeByAddressAll(&pool->num_jobs_in_queue); - } else { - for (i32 i = 0; i < job_count; ++i) { + } + else + { + for (i32 i = 0; i < job_count; ++i) + { WakeByAddressSingle(&pool->num_jobs_in_queue); } } @@ -353,7 +423,7 @@ void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers) void P_W32_WakeByAddress(void *addr, i32 count) { TempArena scratch = scratch_begin_no_conflict(); - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; u64 wait_addr_bin_index = (u64)addr % P_W32_NumWaitAddrBins; P_W32_WaitBin *wait_addr_bin = &g->wait_addr_bins[wait_addr_bin_index]; @@ -366,17 +436,22 @@ void P_W32_WakeByAddress(void *addr, i32 count) P_W32_LockTicketMutex(&wait_addr_bin->lock); { /* Search for wait addr list */ - for (P_W32_WaitList *tmp = wait_addr_bin->first_wait_list; tmp && !wait_addr_list; tmp = tmp->next_in_bin) { - if (tmp->value == (u64)addr) { + for (P_W32_WaitList *tmp = wait_addr_bin->first_wait_list; tmp && !wait_addr_list; tmp = tmp->next_in_bin) + { + if (tmp->value == (u64)addr) + { wait_addr_list = tmp; } } /* Lock fibers & build array */ - if (wait_addr_list) { + if (wait_addr_list) + { fibers = arena_push_array_no_zero(scratch.arena, P_W32_Fiber *, wait_addr_list->num_waiters); - for (P_W32_Fiber *fiber = P_W32_FiberFromId(wait_addr_list->first_waiter); fiber && num_fibers < count; fiber = P_W32_FiberFromId(fiber->next_addr_waiter)) { - if (atomic32_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) { + for (P_W32_Fiber *fiber = P_W32_FiberFromId(wait_addr_list->first_waiter); fiber && num_fibers < count; fiber = P_W32_FiberFromId(fiber->next_addr_waiter)) + { + if (atomic32_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) + { fibers[num_fibers] = fiber; ++num_fibers; } @@ -386,15 +461,20 @@ void P_W32_WakeByAddress(void *addr, i32 count) P_W32_UnlockTicketMutex(&wait_addr_bin->lock); } - if (num_fibers > 0) { + if (num_fibers > 0) + { P_W32_WakeLockedFibers(num_fibers, fibers); } /* Wake win32 blocking thread waiters */ - if (count >= P_W32_WakeAllThreshold) { + if (count >= P_W32_WakeAllThreshold) + { WakeByAddressAll(addr); - } else { - for (i32 i = 0; i < count; ++i) { + } + else + { + for (i32 i = 0; i < count; ++i) + { WakeByAddressSingle(addr); } } @@ -405,7 +485,7 @@ void P_W32_WakeByAddress(void *addr, i32 count) void P_W32_WakeByTime(u64 time) { TempArena scratch = scratch_begin_no_conflict(); - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; u64 wait_time_bin_index = (u64)time % P_W32_NumWaitTimeBins; P_W32_WaitBin *wait_time_bin = &g->wait_time_bins[wait_time_bin_index]; @@ -418,17 +498,22 @@ void P_W32_WakeByTime(u64 time) P_W32_LockTicketMutex(&wait_time_bin->lock); { /* Search for wait time list */ - for (P_W32_WaitList *tmp = wait_time_bin->first_wait_list; tmp && !wait_time_list; tmp = tmp->next_in_bin) { - if (tmp->value == (u64)time) { + for (P_W32_WaitList *tmp = wait_time_bin->first_wait_list; tmp && !wait_time_list; tmp = tmp->next_in_bin) + { + if (tmp->value == (u64)time) + { wait_time_list = tmp; } } - if (wait_time_list) { + if (wait_time_list) + { /* Set waiter wake status & build fibers list */ fibers = arena_push_array_no_zero(scratch.arena, P_W32_Fiber *, wait_time_list->num_waiters); - for (P_W32_Fiber *fiber = P_W32_FiberFromId(wait_time_list->first_waiter); fiber; fiber = P_W32_FiberFromId(fiber->next_time_waiter)) { - if (atomic32_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) { + for (P_W32_Fiber *fiber = P_W32_FiberFromId(wait_time_list->first_waiter); fiber; fiber = P_W32_FiberFromId(fiber->next_time_waiter)) + { + if (atomic32_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) + { fibers[num_fibers] = fiber; ++num_fibers; } @@ -444,33 +529,36 @@ void P_W32_WakeByTime(u64 time) scratch_end(scratch); } -/* ========================== * - * Fibers - * ========================== */ +//////////////////////////////// +//~ Win32 fiber /* If `pool` is 0, then the currently running thread will be converted into a fiber */ P_W32_Fiber *P_W32_AllocFiber(P_W32_JobPool *pool) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; i16 fiber_id = 0; P_W32_Fiber *fiber = 0; char *new_name_cstr = 0; { - if (pool != 0) { + if (pool != 0) + { P_W32_LockTicketMutex(&pool->free_fibers_lock); - if (pool->first_free_fiber_id) { + if (pool->first_free_fiber_id) + { fiber_id = pool->first_free_fiber_id; fiber = &g->fibers[fiber_id]; pool->first_free_fiber_id = fiber->parent_id; } P_W32_UnlockTicketMutex(&pool->free_fibers_lock); } - if (!fiber_id) { + if (!fiber_id) + { P_W32_LockTicketMutex(&g->fibers_lock); { { fiber_id = g->num_fibers++; - if (fiber_id >= MAX_FIBERS) { + if (fiber_id >= MAX_FIBERS) + { P_Panic(LIT("Max fibers reached")); } fiber = &g->fibers[fiber_id]; @@ -481,7 +569,8 @@ P_W32_Fiber *P_W32_AllocFiber(P_W32_JobPool *pool) } } - if (new_name_cstr != 0) { + if (new_name_cstr != 0) + { __profn("Initialize fiber"); fiber->id = fiber_id; @@ -489,7 +578,8 @@ P_W32_Fiber *P_W32_AllocFiber(P_W32_JobPool *pool) i32 id_div = fiber_id; char id_chars[64] = ZI; i32 id_chars_len = 0; - do { + do + { i32 digit = id_div % 10; id_div /= 10; id_chars[id_chars_len] = ("0123456789")[digit]; @@ -497,7 +587,8 @@ P_W32_Fiber *P_W32_AllocFiber(P_W32_JobPool *pool) } while (id_div > 0); i32 rev_start = 0; i32 rev_end = id_chars_len - 1; - while (rev_start < rev_end) { + while (rev_start < rev_end) + { char swp = id_chars[rev_start]; id_chars[rev_start] = id_chars[rev_end]; id_chars[rev_end] = swp; @@ -518,10 +609,13 @@ P_W32_Fiber *P_W32_AllocFiber(P_W32_JobPool *pool) fiber->name_cstr = new_name_cstr; /* Init win32 fiber */ - if (pool != 0) { + if (pool != 0) + { __profn("CreateFiber"); fiber->addr = CreateFiber(P_W32_FiberStackSize, P_W32_FiberEntryPoint, (void *)(i64)fiber_id); - } else { + } + else + { /* Fiber is not a part of a job pool, convert thread to fiber */ __profn("ConvertThreadToFiber"); fiber->addr = ConvertThreadToFiber((void *)(i64)fiber_id); @@ -557,10 +651,13 @@ void P_W32_ReleaseFiber(P_W32_JobPool *pool, P_W32_Fiber *fiber) FORCE_INLINE P_W32_Fiber *P_W32_FiberFromId(i16 id) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; - if (id <= 0) { + P_W32_SharedCtx *g = &P_W32_shared_ctx; + if (id <= 0) + { return 0; - } else { + } + else + { return &g->fibers[id]; } } @@ -590,7 +687,8 @@ void P_W32_FiberEntryPoint(void *id_ptr) i16 id = (i32)(i64)id_ptr; volatile P_W32_Fiber *fiber = P_W32_FiberFromId(id); __prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id); - for (;;) { + for (;;) + { /* Run job */ { P_W32_YieldParam *yield_param = fiber->yield_param; @@ -608,8 +706,9 @@ void P_W32_FiberEntryPoint(void *id_ptr) { /* Decrement job counter */ P_Counter *job_counter = fiber->job_counter; - if (job_counter) { - snc_counter_add(job_counter, -1); + if (job_counter) + { + P_CounterAdd(job_counter, -1); } /* Yield to worker */ fiber->yield_param->kind = P_W32_YieldKind_Done; @@ -619,13 +718,12 @@ void P_W32_FiberEntryPoint(void *id_ptr) } } -/* ========================== * - * Job worker thread - * ========================== */ +//////////////////////////////// +//~ Win32 job worker P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; P_W32_WorkerCtx *ctx = worker_ctx_arg; P_Pool pool_kind = ctx->pool_kind; P_W32_JobPool *pool = &g->job_pools[pool_kind]; @@ -636,7 +734,8 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) /* TODO: Pin non-worker threads to other cores */ HANDLE thread_handle = GetCurrentThread(); - if (pool->thread_priority) { + if (pool->thread_priority) + { __profn("Set priority"); b32 success = SetThreadPriority(thread_handle, pool->thread_priority) != 0; ASSERT(success); @@ -644,14 +743,16 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) } #if 0 - if (pool->thread_affinity_mask) { + if (pool->thread_affinity_mask) + { __profn("Set affinity"); b32 success = SetThreadAffinityMask(thread_handle, pool->thread_affinity_mask) != 0; #if RTC || PROFILING { /* Retry until external tools can set correct process affinity */ i32 delay_ms = 16; - while (!success && delay_ms <= 1024) { + while (!success && delay_ms <= 1024) + { __profn("Affinity retry"); Sleep(delay_ms); success = SetThreadAffinityMask(thread_handle, pool->thread_affinity_mask) != 0; @@ -664,7 +765,8 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) } #endif - if (pool->thread_is_audio) { + if (pool->thread_is_audio) + { /* https://learn.microsoft.com/en-us/windows/win32/procthread/multimedia-class-scheduler-service#registry-settings */ __profn("Set mm thread characteristics"); DWORD task = 0; @@ -678,7 +780,8 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) P_W32_Fiber *job_fiber = 0; b32 shutdown = 0; - while (!shutdown) { + while (!shutdown) + { /* Pull job from queue */ P_Priority job_priority = 0; i16 job_fiber_id = 0; @@ -688,30 +791,38 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) P_Counter *job_counter = 0; { //__profnc("Pull job", RGB32_F(0.75, 0.75, 0)); - for (P_Priority priority = 0; priority < (i32)countof(pool->job_queues) && !job_func; ++priority) { + for (P_Priority priority = 0; priority < (i32)countof(pool->job_queues) && !job_func; ++priority) + { P_W32_JobQueue *queue = &pool->job_queues[priority]; - if (queue) { + if (queue) + { P_W32_LockTicketMutex(&queue->lock); { P_W32_JobInfo *info = queue->first; - while (info && !job_func) { + while (info && !job_func) + { P_W32_JobInfo *next = info->next; b32 dequeue = 0; - if (info->fiber_id <= 0) { + if (info->fiber_id <= 0) + { job_id = info->num_dispatched++; - if (job_id < info->count) { + if (job_id < info->count) + { /* Pick job */ atomic64_fetch_add(&pool->num_jobs_in_queue.v, -1); job_priority = priority; job_func = info->func; job_sig = info->sig; job_counter = info->counter; - if (job_id == (info->count - 1)) { + if (job_id == (info->count - 1)) + { /* We're picking up the last dispatch, so dequeue the job */ dequeue = 1; } } - } else { + } + else + { /* This job is to be resumed from a yield */ atomic64_fetch_add(&pool->num_jobs_in_queue.v, -1); job_fiber_id = info->fiber_id; @@ -722,8 +833,10 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) job_counter = info->counter; dequeue = 1; } - if (dequeue) { - if (!next) { + if (dequeue) + { + if (!next) + { queue->last = 0; } queue->first = next; @@ -739,16 +852,20 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) } /* Use resumed fiber if present */ - if (job_fiber_id > 0) { - if (job_fiber) { + if (job_fiber_id > 0) + { + if (job_fiber) + { P_W32_ReleaseFiber(pool, job_fiber); } job_fiber = P_W32_FiberFromId(job_fiber_id); } /* Run fiber */ - if (job_func) { - if (!job_fiber) { + if (job_func) + { + if (!job_fiber) + { job_fiber = P_W32_AllocFiber(pool); } job_fiber_id = job_fiber->id; @@ -765,9 +882,11 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) job_fiber->job_counter = job_counter; job_fiber->yield_param = &yield; b32 done = 0; - while (!done) { + while (!done) + { P_W32_FiberResume(job_fiber); - switch (yield.kind) { + switch (yield.kind) + { default: { /* Invalid yield kind */ @@ -784,7 +903,8 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) u32 wait_size = yield.wait.size; i64 wait_timeout_ns = yield.wait.timeout_ns; i64 wait_time = 0; - if (wait_timeout_ns > 0 && wait_timeout_ns < I64_MAX) { + if (wait_timeout_ns > 0 && wait_timeout_ns < I64_MAX) + { u64 current_scheduler_cycle = atomic64_fetch(&g->current_scheduler_cycle.v); i64 current_scheduler_cycle_period_ns = atomic64_fetch(&g->current_scheduler_cycle_period_ns.v); wait_time = current_scheduler_cycle + max_i64((i64)((f64)wait_timeout_ns / (f64)current_scheduler_cycle_period_ns), 1); @@ -800,8 +920,10 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) if (wait_time != 0) P_W32_LockTicketMutex(&wait_time_bin->lock); { b32 cancel_wait = wait_addr == 0 && wait_time == 0; - if (wait_addr != 0) { - switch (wait_size) { + if (wait_addr != 0) + { + switch (wait_size) + { case 1: cancel_wait = (u8)_InterlockedCompareExchange8(wait_addr, 0, 0) != *(u8 *)wait_cmp; break; case 2: cancel_wait = (u16)_InterlockedCompareExchange16(wait_addr, 0, 0) != *(u16 *)wait_cmp; break; case 4: cancel_wait = (u32)_InterlockedCompareExchange(wait_addr, 0, 0) != *(u32 *)wait_cmp; break; @@ -809,24 +931,33 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) default: cancel_wait = 1; ASSERT(0); break; /* Invalid wait size */ } } - if (wait_time != 0 && !cancel_wait) { + if (wait_time != 0 && !cancel_wait) + { cancel_wait = wait_time <= atomic64_fetch(&g->current_scheduler_cycle.v); } - if (!cancel_wait) { - if (wait_addr != 0) { + if (!cancel_wait) + { + if (wait_addr != 0) + { /* Search for wait addr list in bin */ P_W32_WaitList *wait_addr_list = 0; - for (P_W32_WaitList *tmp = wait_addr_bin->first_wait_list; tmp && !wait_addr_list; tmp = tmp->next_in_bin) { - if (tmp->value == (u64)wait_addr) { + for (P_W32_WaitList *tmp = wait_addr_bin->first_wait_list; tmp && !wait_addr_list; tmp = tmp->next_in_bin) + { + if (tmp->value == (u64)wait_addr) + { wait_addr_list = tmp; } } /* Allocate new wait addr list */ - if (!wait_addr_list) { - if (wait_addr_bin->first_free_wait_list) { + if (!wait_addr_list) + { + if (wait_addr_bin->first_free_wait_list) + { wait_addr_list = wait_addr_bin->first_free_wait_list; wait_addr_bin->first_free_wait_list = wait_addr_list->next_in_bin; - } else { + } + else + { P_W32_LockTicketMutex(&g->wait_lists_arena_lock); { wait_addr_list = arena_push_no_zero(g->wait_lists_arena, P_W32_WaitList); @@ -835,39 +966,52 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) } MEMZERO_STRUCT(wait_addr_list); wait_addr_list->value = (u64)wait_addr; - if (wait_addr_bin->last_wait_list) { + if (wait_addr_bin->last_wait_list) + { wait_addr_bin->last_wait_list->next_in_bin = wait_addr_list; wait_addr_list->prev_in_bin = wait_addr_bin->last_wait_list; - } else { + } + else + { wait_addr_bin->first_wait_list = wait_addr_list; } wait_addr_bin->last_wait_list = wait_addr_list; } /* Insert fiber into wait addr list */ job_fiber->wait_addr = (u64)wait_addr; - if (wait_addr_list->last_waiter) { + if (wait_addr_list->last_waiter) + { P_W32_FiberFromId(wait_addr_list->last_waiter)->next_addr_waiter = job_fiber_id; job_fiber->prev_addr_waiter = wait_addr_list->last_waiter; - } else { + } + else + { wait_addr_list->first_waiter = job_fiber_id; } wait_addr_list->last_waiter = job_fiber_id; ++wait_addr_list->num_waiters; } - if (wait_time != 0) { + if (wait_time != 0) + { /* Search for wait time list in bin */ P_W32_WaitList *wait_time_list = 0; - for (P_W32_WaitList *tmp = wait_time_bin->first_wait_list; tmp && !wait_time_list; tmp = tmp->next_in_bin) { - if (tmp->value == (u64)wait_time) { + for (P_W32_WaitList *tmp = wait_time_bin->first_wait_list; tmp && !wait_time_list; tmp = tmp->next_in_bin) + { + if (tmp->value == (u64)wait_time) + { wait_time_list = tmp; } } /* Allocate new wait time list */ - if (!wait_time_list) { - if (wait_time_bin->first_free_wait_list) { + if (!wait_time_list) + { + if (wait_time_bin->first_free_wait_list) + { wait_time_list = wait_time_bin->first_free_wait_list; wait_time_bin->first_free_wait_list = wait_time_list->next_in_bin; - } else { + } + else + { P_W32_LockTicketMutex(&g->wait_lists_arena_lock); { wait_time_list = arena_push_no_zero(g->wait_lists_arena, P_W32_WaitList); @@ -876,20 +1020,26 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) } MEMZERO_STRUCT(wait_time_list); wait_time_list->value = wait_time; - if (wait_time_bin->last_wait_list) { + if (wait_time_bin->last_wait_list) + { wait_time_bin->last_wait_list->next_in_bin = wait_time_list; wait_time_list->prev_in_bin = wait_time_bin->last_wait_list; - } else { + } + else + { wait_time_bin->first_wait_list = wait_time_list; } wait_time_bin->last_wait_list = wait_time_list; } /* Insert fiber into wait time list */ job_fiber->wait_time = wait_time; - if (wait_time_list->last_waiter) { + if (wait_time_list->last_waiter) + { P_W32_FiberFromId(wait_time_list->last_waiter)->next_time_waiter = job_fiber_id; job_fiber->prev_time_waiter = wait_time_list->last_waiter; - } else { + } + else + { wait_time_list->first_waiter = job_fiber_id; } wait_time_list->last_waiter = job_fiber_id; @@ -918,13 +1068,15 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) /* Wait for job */ i64 num_jobs_in_queue = atomic64_fetch(&pool->num_jobs_in_queue.v); shutdown = atomic32_fetch(&pool->workers_shutdown.v); - if (num_jobs_in_queue <= 0 && !shutdown) { + if (num_jobs_in_queue <= 0 && !shutdown) + { //__profnc("Wait for job", RGB32_F(0.75, 0.75, 0)); P_W32_LockTicketMutex(&pool->workers_wake_lock); { num_jobs_in_queue = atomic64_fetch(&pool->num_jobs_in_queue.v); shutdown = atomic32_fetch(&pool->workers_shutdown.v); - while (num_jobs_in_queue <= 0 && !shutdown) { + while (num_jobs_in_queue <= 0 && !shutdown) + { { P_W32_UnlockTicketMutex(&pool->workers_wake_lock); WaitOnAddress(&pool->num_jobs_in_queue, &num_jobs_in_queue, sizeof(num_jobs_in_queue), INFINITE); @@ -939,18 +1091,18 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg) } /* Worker shutdown */ - if (job_fiber) { + if (job_fiber) + { P_W32_ReleaseFiber(pool, job_fiber); } } -/* ========================== * - * Job scheduler thread - * ========================== */ +//////////////////////////////// +//~ Win32 job scheduler P_W32_ThreadDef(P_W32_JobSchedulerEntryFunc, _) { - struct P_W32_Ctx *g = &P_W32_g_shared_ctx; + struct P_W32_SharedCtx *g = &P_W32_shared_ctx; (UNUSED)_; { @@ -962,19 +1114,22 @@ P_W32_ThreadDef(P_W32_JobSchedulerEntryFunc, _) /* Create high resolution timer */ HANDLE timer = CreateWaitableTimerExW(0, 0, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS); - if (!timer) { + if (!timer) + { P_Panic(LIT("Failed to create high resolution timer")); } /* Create rolling buffer of scheduler cycles initialized to default value */ i32 periods_index = 0; i64 periods[P_W32_NumRollingSchedulerPeriods] = ZI; - for (i32 i = 0; i < (i32)countof(periods); ++i) { + for (i32 i = 0; i < (i32)countof(periods); ++i) + { periods[i] = P_W32_DefaultSchedulerPeriodNs; } i64 last_cycle_ns = 0; - while (!atomic32_fetch(&g->shutdown)) { + while (!atomic32_fetch(&g->shutdown)) + { __profn("Job scheduler cycle"); { __profn("Job scheduler wait"); @@ -996,11 +1151,13 @@ P_W32_ThreadDef(P_W32_JobSchedulerEntryFunc, _) /* Calculate mean period */ { periods[periods_index++] = period_ns; - if (periods_index == countof(periods)) { + if (periods_index == countof(periods)) + { periods_index = 0; } f64 periods_sum_ns = 0; - for (i32 i = 0; i < (i32)countof(periods); ++i) { + for (i32 i = 0; i < (i32)countof(periods); ++i) + { periods_sum_ns += (f64)periods[i]; } f64 mean_ns = periods_sum_ns / (f64)countof(periods); @@ -1015,15 +1172,776 @@ P_W32_ThreadDef(P_W32_JobSchedulerEntryFunc, _) } } -/* ========================== * - * Wait / wake - * ========================== */ +//////////////////////////////// +//~ Win32 time + +P_DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st) +{ + return (P_DateTime) + { + .year = st.wYear, + .month = st.wMonth, + .day_of_week = st.wDayOfWeek, + .day = st.wDay, + .hour = st.wHour, + .minute = st.wMinute, + .second = st.wSecond, + .milliseconds = st.wMilliseconds + }; +} + +//////////////////////////////// +//~ Win32 file system + +String P_W32_StringFromWin32Path(Arena *arena, wchar_t *src) +{ + String res = { + .len = 0, + .text = arena_push_dry(arena, u8) + }; + + while (*src) + { + String16 decode_str = { .len = *(src + 1) ? 2 : 1, .text = src }; + Utf16DecodeResult decoded = uni_decode_utf16(decode_str); + Utf8EncodeResult encoded = uni_encode_utf8(decoded.codepoint); + u8 *dest = arena_push_array_no_zero(arena, u8, encoded.count8); + for (u32 i = 0; i < encoded.count8; ++i) + { + u8 byte = encoded.chars8[i]; + if (byte == '\\') + { + byte = '/'; + } + dest[i] = byte; + } + res.len += encoded.count8; + src += decoded.advance16; + } + + return res; +} + +//////////////////////////////// +//~ Win32 window + +P_W32_Window *P_W32_AllocWindow(void) +{ + P_W32_SharedCtx *g = &P_W32_shared_ctx; + P_W32_Window *window = 0; + { + P_Lock lock = P_LockE(&g->windows_mutex); + if (g->first_free_window) + { + window = g->first_free_window; + g->first_free_window = window->next_free; + } + else + { + window = arena_push_no_zero(g->windows_arena, P_W32_Window); + } + P_Unlock(&lock); + } + MEMZERO_STRUCT(window); + + window->event_arenas[0] = arena_alloc(GIBI(64)); + window->event_arenas[1] = arena_alloc(GIBI(64)); + + /* Start window event thread */ + /* NOTE: This thread must finish building for the window to actually be + * created and receive a HWND, because on Windows a the event proc must run on + * the same thread that created the window. */ + P_CounterAdd(&window->ready_fence, 1); + window->window_thread = P_W32_AllocThread(&P_W32_WindowThreadEntryFunc, window, LIT("Window thread"), PROF_THREAD_GROUP_WINDOW); + P_WaitOnCounter(&window->ready_fence); + + return window; +} + +void P_W32_ReleaseWindow(P_W32_Window *window) +{ + /* Stop window threads */ + atomic32_fetch_set(&window->shutdown, 1); + P_W32_SharedCtx *g = &P_W32_shared_ctx; + P_W32_WakeWindow(window); + P_W32_WaitReleaseThread(window->window_thread); + + P_Lock lock = P_LockE(&g->windows_mutex); + { + window->next_free = g->first_free_window; + g->first_free_window = window; + } + P_Unlock(&lock); +} + +HWND P_W32_InitWindow(P_W32_Window *window) +{ + struct P_W32_SharedCtx *g = &P_W32_shared_ctx; + + /* + * From martins (https://gist.github.com/mmozeiko/5e727f845db182d468a34d524508ad5f#file-win32_d3d11-c-L66-L70): + * WS_EX_NOREDIRECTIONBITMAP flag here is needed to fix ugly bug with Windows 10 + * when window is resized and DXGI swap chain uses FLIP presentation model + * DO NOT use it if you choose to use non-FLIP presentation model + * read about the bug here: https://stackoverflow.com/q/63096226 and here: https://stackoverflow.com/q/53000291 + */ + DWORD exstyle = WS_EX_APPWINDOW | WS_EX_NOREDIRECTIONBITMAP; + + /* TODO: Check for hwnd success */ + HWND hwnd = CreateWindowExW( + exstyle, + g->window_class.lpszClassName, + L"", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + 0, + 0, + g->window_class.hInstance, + 0 + ); + + /* Dark mode */ + BOOL dark_mode = 1; + DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, (LPCVOID)&dark_mode, sizeof(dark_mode)); + + /* Set window as userdata */ + SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)window); + + return hwnd; +} + +//////////////////////////////// +//~ Win32 window settings + +void P_W32_UpdateWindowFromSystem(P_W32_Window *window) +{ + HWND hwnd = window->hwnd; + + RECT window_rect = ZI; + GetWindowRect(hwnd, &window_rect); + + RECT client_rect = ZI; + GetClientRect(hwnd, (LPRECT)&client_rect); + ClientToScreen(hwnd, (LPPOINT)&client_rect.left); + ClientToScreen(hwnd, (LPPOINT)&client_rect.right); + + /* TODO: Error if we can't get monitor info */ + /* Screen dimensions */ + MONITORINFO monitor_info = { .cbSize = sizeof(monitor_info) }; + GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY), &monitor_info); + RECT monitor_rect = monitor_info.rcMonitor; + window->monitor_width = monitor_rect.right - monitor_rect.left; + window->monitor_height = monitor_rect.bottom - monitor_rect.top; + + /* Minimized / maximized */ + if (window->flags & P_WindowFlag_Showing) + { + WINDOWPLACEMENT placement = { .length = sizeof(placement) }; + GetWindowPlacement(hwnd, &placement); + if (placement.showCmd == SW_SHOWMINIMIZED) + { + window->settings.flags |= P_WindowSettingsFlag_Minimized; + } + else + { + window->settings.flags &= ~P_WindowSettingsFlag_Minimized; + } + if (placement.showCmd == SW_SHOWMAXIMIZED + || ((window->settings.flags & P_WindowSettingsFlag_Minimized) && ((placement.flags & WPF_RESTORETOMAXIMIZED) != 0))) + { + window->settings.flags |= P_WindowSettingsFlag_Maximized; + } + else + { + window->settings.flags &= ~P_WindowSettingsFlag_Maximized; + } + } + + /* Window dimensions */ + i32 x = client_rect.left; + i32 y = client_rect.top; + i32 width = client_rect.right - client_rect.left; + i32 height = client_rect.bottom - client_rect.top; + if (!(window->settings.flags & P_WindowSettingsFlag_Minimized)) + { + window->x = x; + window->y = y; + window->width = width; + window->height = height; + if (!(window->settings.flags & (P_WindowSettingsFlag_Maximized | P_WindowSettingsFlag_Fullscreen))) + { + /* Treat a window resize in non maximized/fullscreen mode as a + * settings change. + * + * TODO: make sure we check for fullscreen here too if we ever + * allow it. */ + window->settings.floating_x = x; + window->settings.floating_y = y; + window->settings.floating_width = width; + window->settings.floating_height = height; + } + } +} + +void P_W32_UpdateWindowFromSettings(P_W32_Window *window, P_WindowSettings *settings) +{ + HWND hwnd = window->hwnd; + + P_WindowSettings old_settings = window->settings; + window->settings = *settings; + + i32 show_cmd = SW_HIDE; + if (window->flags & P_WindowFlag_Showing) + { + show_cmd = SW_NORMAL; + if (settings->flags & P_WindowSettingsFlag_Maximized) + { + show_cmd = SW_SHOWMAXIMIZED; + } + else if (settings->flags & P_WindowSettingsFlag_Minimized) + { + show_cmd = SW_MINIMIZE; + } + } + + RECT rect = ZI; + + b32 old_fullscreen = old_settings.flags & P_WindowSettingsFlag_Fullscreen; + b32 fullscreen = settings->flags & P_WindowSettingsFlag_Fullscreen; + + if (fullscreen) + { + if (!old_fullscreen) + { + /* Entering fullscreen */ + SetWindowLongPtrW(hwnd, GWL_STYLE, WS_POPUP); + } + rect = (RECT) { + .left = 0, + .top = 0, + .right = window->monitor_width, + .bottom = window->monitor_height + }; + } + else + { + if (old_fullscreen) + { + /* Leaving fullscreen */ + SetWindowLongPtrW(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); + } + rect = (RECT) { + .left = settings->floating_x, + .top = settings->floating_y, + .right = settings->floating_x + settings->floating_width, + .bottom = settings->floating_y + settings->floating_height + }; + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, 0); + } + + WINDOWPLACEMENT wp = { + .length = sizeof(WINDOWPLACEMENT), + .showCmd = show_cmd, + .rcNormalPosition = rect + }; + SetWindowPlacement(hwnd, &wp); + + { + TempArena scratch = scratch_begin_no_conflict(); + wchar_t *title_wstr = wstr_from_string(scratch.arena, string_from_cstr_no_limit(settings->title)); + SetWindowTextW(hwnd, title_wstr); + scratch_end(scratch); + } +} + +//////////////////////////////// +//~ Win32 window thread + +P_W32_ThreadDef(P_W32_WindowThreadEntryFunc, arg) +{ + P_W32_Window *window = (P_W32_Window *)arg; + + /* Win32 limitation: Window must be initialized on same thread that processes events */ + window->hwnd = P_W32_InitWindow(window); + P_W32_UpdateWindowFromSystem(window); + BringWindowToTop(window->hwnd); + P_CounterAdd(&window->ready_fence, -1); + + while (!atomic32_fetch(&window->shutdown)) + { + MSG msg = ZI; + { + GetMessageW(&msg, 0, 0, 0); + } + { + __profn("Process window message"); + if (!atomic32_fetch(&window->shutdown)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + } + + /* Destroy window hwnd */ + DestroyWindow(window->hwnd); +} + +void P_W32_ProcessWindowEvent(P_W32_Window *window, P_WindowEvent event) +{ + __prof; + P_Lock lock = P_LockE(&window->event_arena_swp_mutex); + { + *arena_push(window->event_arenas[window->current_event_arena_index], P_WindowEvent) = event; + } + P_Unlock(&lock); +} + +void P_W32_WakeWindow(P_W32_Window *window) +{ + /* Post a blank message to the window's thread message queue to wake it. */ + PostMessageW(window->hwnd, 0, 0, 0); +} + +LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + __prof; + P_W32_SharedCtx *g = &P_W32_shared_ctx; + P_W32_Window *window = (P_W32_Window *)GetWindowLongPtrW(hwnd, GWLP_USERDATA); + + if (!window) + { + return DefWindowProcW(hwnd, msg, wparam, lparam); + } + + /* Update cursor */ + if (GetFocus() == window->hwnd) + { + u32 cursor_flags = window->cursor_set_flags; + + /* Hide cursor */ + if (cursor_flags & P_W32_CursorFlag_Hide) + { + while (ShowCursor(0) >= 0); + } + + /* Show cursor */ + if (cursor_flags & P_W32_CursorFlag_Show) + { + while (ShowCursor(1) < 0); + } + + /* Update position */ + if (cursor_flags & P_W32_CursorFlag_Position) + { + V2 window_space_pos = window->cursor_set_position; + POINT p = { window_space_pos.x, window_space_pos.y }; + ClientToScreen(window->hwnd, &p); + SetCursorPos(p.x, p.y); + } + + /* Stop clipping cursor */ + if (cursor_flags & P_W32_CursorFlag_DisableClip) + { + ClipCursor(0); + } + + /* Clip cursor in window window */ + if (cursor_flags & P_W32_CursorFlag_EnableClip) + { + i32 left = window->x + math_round_to_int(window->cursor_clip_bounds.x); + i32 right = left + math_round_to_int(window->cursor_clip_bounds.width); + i32 top = window->y + math_round_to_int(window->cursor_clip_bounds.y); + i32 bottom = top + math_round_to_int(window->cursor_clip_bounds.height); + RECT clip = { + .left = clamp_i32(left, window->x, window->x + window->width), + .right = clamp_i32(right, window->x, window->x + window->width), + .top = clamp_i32(top, window->y, window->y + window->height), + .bottom = clamp_i32(bottom, window->y, window->y + window->height) + }; + ClipCursor(&clip); + } + + window->cursor_set_flags = 0; + } + + /* Update always on top */ + { + u32 toggles = atomic32_fetch_set(&window->topmost_toggles, 0); + if (toggles % 2 != 0) + { + b32 new_topmost = !window->is_topmost; + if (new_topmost) + { + SetWindowText(hwnd, L"============================= TOP ============================="); + } + else + { + SetWindowText(hwnd, L""); + } + SetWindowPos(hwnd, new_topmost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + window->is_topmost = new_topmost; + } + } + + LRESULT result = 0; + b32 is_release = 0; + switch (msg) + { + case WM_QUIT: + case WM_CLOSE: + case WM_DESTROY: + { + P_W32_ProcessWindowEvent(window, (P_WindowEvent) { .kind = P_WindowEventKind_Quit }); + } break; + + case WM_PAINT: + { + result = DefWindowProcW(hwnd, msg, wparam, lparam); + } break; + + case WM_ENTERSIZEMOVE: + case WM_MOVE: + case WM_MOVING: + case WM_SIZE: + case WM_SIZING: + { + P_W32_UpdateWindowFromSystem(window); + result = DefWindowProcW(hwnd, msg, wparam, lparam); + } break; + + /* Keyboard buttons */ + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + { + if (LOWORD(wparam) != VK_MENU) + { + result = DefWindowProcW(hwnd, msg, wparam, lparam); + } + } FALLTHROUGH; + case WM_KEYUP: + case WM_KEYDOWN: + { + WORD vk_code = LOWORD(wparam); + b32 is_repeat = 0; + + P_WindowEventKind event_kind = P_WindowEventKind_None; + if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) + { + event_kind = P_WindowEventKind_ButtonDown; + is_repeat = (lparam & 0x40000000) != 0; + } + else if (msg == WM_KEYUP || msg == WM_SYSKEYUP) + { + event_kind = P_WindowEventKind_ButtonUp; + } + + P_Btn button = P_Btn_None; + if (vk_code < countof(g->vk_btn_table)) + { + button = g->vk_btn_table[vk_code]; + } + + P_W32_ProcessWindowEvent( + window, + (P_WindowEvent) + { + .kind = event_kind, + .button = button, + .is_repeat = is_repeat + } + ); + } break; + + /* Text */ + case WM_SYSCHAR: + case WM_CHAR: + { + u16 utf16_char = (u32)wparam; + + /* Decode */ + u32 codepoint = 0; + if (uni_is_utf16_high_surrogate(utf16_char)) + { + window->utf16_high_surrogate_last_input = utf16_char; + } + else if (uni_is_utf16_low_surrogate(utf16_char)) + { + u16 high = window->utf16_high_surrogate_last_input; + u16 low = utf16_char; + if (high) + { + u16 utf16_pair_bytes[2] = { high, low }; + Utf16DecodeResult decoded = uni_decode_utf16((String16) { .len = countof(utf16_pair_bytes), .text = utf16_pair_bytes }); + if (decoded.advance16 == 2 && decoded.codepoint < U32_MAX) + { + codepoint = decoded.codepoint; + } + } + window->utf16_high_surrogate_last_input = 0; + } + else + { + window->utf16_high_surrogate_last_input = 0; + codepoint = utf16_char; + } + + if (codepoint) + { + if (codepoint == '\r') + { + codepoint = '\n'; /* Just treat all \r as newline */ + } + if ((codepoint >= 32 && codepoint != 127) || codepoint == '\t' || codepoint == '\n') + { + P_W32_ProcessWindowEvent( + window, + (P_WindowEvent) + { + .kind = P_WindowEventKind_Text, + .text_codepoint = codepoint + } + ); + } + } + + + } break; + + /* Mouse buttons */ + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_XBUTTONUP: + { + ReleaseCapture(); + is_release = 1; + } FALLTHROUGH; + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_XBUTTONDOWN: + { + if (!is_release) + { + SetCapture(hwnd); + } + + P_WindowEventKind event_kind = is_release ? P_WindowEventKind_ButtonUp : P_WindowEventKind_ButtonDown; + P_Btn button = 0; + + switch (msg) + { + case WM_LBUTTONUP: case WM_LBUTTONDOWN: button = P_Btn_M1; break; + case WM_RBUTTONUP: case WM_RBUTTONDOWN: button = P_Btn_M2; break; + case WM_MBUTTONUP: case WM_MBUTTONDOWN: button = P_Btn_M3; break; + case WM_XBUTTONUP: case WM_XBUTTONDOWN: + { + u32 wparam_xbutton = GET_XBUTTON_WPARAM(wparam); + if (wparam_xbutton == XBUTTON1) + { + button = P_Btn_M4; + } + else if (wparam_xbutton == XBUTTON2) + { + button = P_Btn_M5; + } + } break; + } + + if (button) + { + P_W32_ProcessWindowEvent( + window, + (P_WindowEvent) + { + .kind = event_kind, + .button = button + } + ); + } + } break; + + /* Mouse wheel */ + case WM_MOUSEWHEEL: + { + int delta = GET_WHEEL_DELTA_WPARAM(wparam); + i32 dir = delta >= 0 ? 1 : -1; + P_Btn button = dir >= 0 ? P_Btn_MWheelUp : P_Btn_MWheelDown; + for (i32 i = 0; i < (dir * delta); i += WHEEL_DELTA) + { + /* Send a button down & button up event simultaneously */ + P_W32_ProcessWindowEvent(window, (P_WindowEvent) { .kind = P_WindowEventKind_ButtonDown, .button = button }); + P_W32_ProcessWindowEvent(window, (P_WindowEvent) { .kind = P_WindowEventKind_ButtonUp, .button = button }); + } + } break; + + /* Mouse move */ + case WM_MOUSEMOVE: + { + i32 x = GET_X_LPARAM(lparam); + i32 y = GET_Y_LPARAM(lparam); + P_W32_ProcessWindowEvent( + window, + (P_WindowEvent) + { + .kind = P_WindowEventKind_CursorMove, + .cursor_position = V2FromXY(x, y) + } + ); + } break; + + /* Raw mouse move */ + case WM_INPUT: + { + TempArena scratch = scratch_begin_no_conflict(); + + /* Read raw input buffer */ + UINT buff_size; + GetRawInputData((HRAWINPUT)lparam, RID_INPUT, 0, &buff_size, sizeof(RAWINPUTHEADER)); + u8 *buff = arena_push_array(scratch.arena, u8, buff_size); + if (GetRawInputData((HRAWINPUT)lparam, RID_INPUT, buff, &buff_size, sizeof(RAWINPUTHEADER)) != buff_size) + { + P_LogErrorF("GetRawInputData did not return correct size"); + break; + } + RAWINPUT raw = ZI; + MEMCPY(&raw, buff, sizeof(RAWINPUT)); + + if (raw.header.dwType == RIM_TYPEMOUSE) + { + i32 x = raw.data.mouse.lLastX; + i32 y = raw.data.mouse.lLastY; + V2 delta = V2FromXY(x, y); + P_W32_ProcessWindowEvent( + window, + (P_WindowEvent) + { + .kind = P_WindowEventKind_MouseMove, + .mouse_delta = delta + } + ); + } + + scratch_end(scratch); + } break; + + /* Minmax info */ + case WM_GETMINMAXINFO: + { + /* Set minimum window size */ + LPMINMAXINFO mmi = (LPMINMAXINFO)lparam; + mmi->ptMinTrackSize.x = 100; + mmi->ptMinTrackSize.y = 100; + } break; + + default: + { + result = DefWindowProcW(hwnd, msg, wparam, lparam); + } break; + } + + return result; +} + +//////////////////////////////// +//~ Win32 Address + +P_W32_Address P_W32_Win32AddressFromPlatformAddress(P_Address addr) +{ + P_W32_Address res = ZI; + if (addr.family == P_AddressFamily_Ipv4) + { + res.family = AF_INET; + res.size = sizeof(struct sockaddr_in); + res.sin.sin_port = addr.portnb; + res.sin.sin_family = res.family; + MEMCPY(&res.sin.sin_addr, addr.ipnb, 4); + } + else + { + res.family = AF_INET6; + res.sin6.sin6_port = addr.portnb; + res.sin6.sin6_family = res.family; + res.size = sizeof(struct sockaddr_in6); + MEMCPY(&res.sin6.sin6_addr.s6_addr, addr.ipnb, 16); + } + return res; +} + +/* If supplied address has ip INADDR_ANY (0), convert ip to localhost */ +P_W32_Address P_W32_ConvertAnyaddrToLocalhost(P_W32_Address addr) +{ + if (addr.family == AF_INET) + { + u8 *bytes = (u8 *)&addr.sin.sin_addr; + b32 is_any = 1; + for (u64 i = 0; i < 4; ++i) + { + if (bytes[i] != 0) + { + is_any = 0; + break; + } + } + if (is_any) + { + bytes[0] = 127; + bytes[3] = 1; + } + } + else if (addr.family == AF_INET6) + { + u8 *bytes = (u8 *)&addr.sin.sin_addr; + b32 is_any = 1; + for (u64 i = 0; i < 16; ++i) + { + if (bytes[i] != 0) + { + is_any = 0; + break; + } + } + if (is_any) + { + bytes[15] = 1; + } + } + return addr; +} + +P_Address P_W32_PlatformAddressFromWin32Address(P_W32_Address ws_addr) +{ + P_Address res = ZI; + if (ws_addr.family == AF_INET) + { + res.family = P_AddressFamily_Ipv4; + res.portnb = ws_addr.sin.sin_port; + MEMCPY(res.ipnb, &ws_addr.sin.sin_addr, 4); + res.valid = 1; + } + else if (ws_addr.family == AF_INET6) + { + res.family = P_AddressFamily_Ipv6; + res.portnb = ws_addr.sin6.sin6_port; + MEMCPY(res.ipnb, &ws_addr.sin6.sin6_addr.s6_addr, 16); + res.valid = 1; + } + return res; +} + +//////////////////////////////// +//~ Wait / wake void P_Wait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns) { P_W32_Fiber *fiber = P_W32_FiberFromId(FiberId()); i16 parent_id = fiber->parent_id; - if (parent_id != 0) { + if (parent_id != 0) + { *fiber->yield_param = (P_W32_YieldParam) { .kind = P_W32_YieldKind_Wait, .wait = { @@ -1034,17 +1952,25 @@ void P_Wait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns) } }; P_W32_YieldFiber(fiber, P_W32_FiberFromId(parent_id)); - } else { + } + else + { i32 timeout_ms = 0; - if (timeout_ns > 10000000000000000ll) { + if (timeout_ns > 10000000000000000ll) + { timeout_ms = INFINITE; - } else if (timeout_ns != 0) { + } + else if (timeout_ns != 0) + { timeout_ms = timeout_ns / 1000000; timeout_ms += (timeout_ms == 0) * math_fsign(timeout_ns); } - if (addr == 0) { + if (addr == 0) + { Sleep(timeout_ms); - } else { + } + else + { WaitOnAddress(addr, cmp, size, timeout_ms); } } @@ -1055,21 +1981,23 @@ void P_Wake(void *addr, i32 count) P_W32_WakeByAddress(addr, count); } -/* ========================== * - * Job - * ========================== */ +//////////////////////////////// +//~ Job void P_Run(i32 count, P_JobFunc *func, void *sig, P_Pool pool_kind, P_Priority priority, P_Counter *counter) { __prof; - struct P_W32_Ctx *g = &P_W32_g_shared_ctx; - if (count > 0) { - if (counter) { - snc_counter_add(counter, count); + struct P_W32_SharedCtx *g = &P_W32_shared_ctx; + if (count > 0) + { + if (counter) + { + P_CounterAdd(counter, count); } P_W32_Fiber *fiber = P_W32_FiberFromId(FiberId()); priority = clamp_i32(priority, fiber->job_priority, P_Priority_Count - 1); /* A job cannot create a job with a higher priority than itself */ - if (pool_kind == P_Pool_Inherit) { + if (pool_kind == P_Pool_Inherit) + { pool_kind = fiber->job_pool; } P_W32_JobPool *pool = &g->job_pools[pool_kind]; @@ -1077,10 +2005,13 @@ void P_Run(i32 count, P_JobFunc *func, void *sig, P_Pool pool_kind, P_Priority p P_W32_LockTicketMutex(&queue->lock); { P_W32_JobInfo *info = 0; - if (queue->first_free) { + if (queue->first_free) + { info = queue->first_free; queue->first_free = info->next; - } else { + } + else + { info = arena_push_no_zero(queue->arena, P_W32_JobInfo); } MEMZERO_STRUCT(info); @@ -1088,9 +2019,12 @@ void P_Run(i32 count, P_JobFunc *func, void *sig, P_Pool pool_kind, P_Priority p info->func = func; info->sig = sig; info->counter = counter; - if (queue->last) { + if (queue->last) + { queue->last->next = info; - } else { + } + else + { queue->first = info; } queue->last = info; @@ -1102,10 +2036,14 @@ void P_Run(i32 count, P_JobFunc *func, void *sig, P_Pool pool_kind, P_Priority p P_W32_LockTicketMutex(&pool->workers_wake_lock); { atomic64_fetch_add(&pool->num_jobs_in_queue.v, count); - if (count >= P_W32_WakeAllThreshold) { + if (count >= P_W32_WakeAllThreshold) + { WakeByAddressAll(&pool->num_jobs_in_queue); - } else { - for (i32 i = 0; i < count; ++i) { + } + else + { + for (i32 i = 0; i < count; ++i) + { WakeByAddressSingle(&pool->num_jobs_in_queue); } } @@ -1115,23 +2053,8 @@ void P_Run(i32 count, P_JobFunc *func, void *sig, P_Pool pool_kind, P_Priority p } } -/* ========================== * - * Time - * ========================== */ - -P_DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st) -{ - return (P_DateTime) { - .year = st.wYear, - .month = st.wMonth, - .day_of_week = st.wDayOfWeek, - .day = st.wDay, - .hour = st.wHour, - .minute = st.wMinute, - .second = st.wSecond, - .milliseconds = st.wMilliseconds - }; -} +//////////////////////////////// +//~ Time P_DateTime P_LocalTime(void) { @@ -1142,43 +2065,15 @@ P_DateTime P_LocalTime(void) i64 P_TimeNs(void) { - struct P_W32_Ctx *g = &P_W32_g_shared_ctx; + struct P_W32_SharedCtx *g = &P_W32_shared_ctx; LARGE_INTEGER qpc; QueryPerformanceCounter(&qpc); i64 res = (qpc.QuadPart - g->timer_start_qpc) * g->ns_per_qpc; return res; } - -/* ========================== * - * File system - * ========================== */ - -String P_W32_StringFromWin32Path(Arena *arena, wchar_t *src) -{ - String res = { - .len = 0, - .text = arena_push_dry(arena, u8) - }; - - while (*src) { - String16 decode_str = { .len = *(src + 1) ? 2 : 1, .text = src }; - Utf16DecodeResult decoded = uni_decode_utf16(decode_str); - Utf8EncodeResult encoded = uni_encode_utf8(decoded.codepoint); - u8 *dest = arena_push_array_no_zero(arena, u8, encoded.count8); - for (u32 i = 0; i < encoded.count8; ++i) { - u8 byte = encoded.chars8[i]; - if (byte == '\\') { - byte = '/'; - } - dest[i] = byte; - } - res.len += encoded.count8; - src += decoded.advance16; - } - - return res; -} +//////////////////////////////// +//~ File system String P_GetWritePath(Arena *arena) { @@ -1191,7 +2086,8 @@ String P_GetWritePath(Arena *arena) &p ); String path = ZI; - if (res == S_OK) { + if (res == S_OK) + { path = P_W32_StringFromWin32Path(arena, p); } CoTaskMemFree(p); @@ -1224,7 +2120,8 @@ void P_MkDir(String path) wchar_t *path_wstr = wstr_from_string(scratch.arena, path); int err_code = SHCreateDirectory(0, path_wstr); String err = ZI; - switch (err_code) { + switch (err_code) + { case ERROR_BAD_PATHNAME: { err = LIT("Bad path name"); @@ -1247,7 +2144,8 @@ void P_MkDir(String path) default: break; } - if (err.len > 0) { + if (err.len > 0) + { String msg = string_format(scratch.arena, LIT("Failed to create directory \"%F\": %F"), FMT_STR(path), @@ -1289,14 +2187,19 @@ P_File P_OpenFileReadWait(String path) wchar_t *path_wstr = wstr_from_string(scratch.arena, path); i32 delay_ms = 1; HANDLE handle; - while ((handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_SHARING_VIOLATION) { + while ((handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) + { + if (GetLastError() == ERROR_SHARING_VIOLATION) + { __profn("File share conflict delay"); Sleep(delay_ms); - if (delay_ms < 1024) { + if (delay_ms < 1024) + { delay_ms *= 2; } - } else { + } + else + { break; } } @@ -1356,7 +2259,8 @@ P_File P_OpenFileAppend(String path) void P_CloseFIle(P_File file) { __prof; - if (file.handle) { + if (file.handle) + { CloseHandle((HANDLE)file.handle); } } @@ -1372,7 +2276,8 @@ String P_ReadFile(Arena *arena, P_File file) .text = 0 }; - if (size > 0) { + if (size > 0) + { /* ReadFile returns non-zero on success */ /* TODO: error checking */ arena_align(arena, 16); @@ -1394,7 +2299,8 @@ void P_WriteFile(P_File file, String data) __prof; /* TODO: Check what the real data limit is and chunk sequentially based on * that (rather than failing) */ - if (data.len >= 0x7FFF) { + if (data.len >= 0x7FFF) + { TempArena scratch = scratch_begin_no_conflict(); P_Panic(string_format(scratch.arena, LIT("Tried to write too many bytes to disk (%F)"), @@ -1428,7 +2334,8 @@ P_FileTime P_GetFileTime(P_File file) FILETIME ft_accessed; FILETIME ft_modified; b32 success = !!GetFileTime((HANDLE)file.handle, &ft_created, &ft_accessed, &ft_modified); - if (success) { + if (success) + { /* Convert file times to local file time */ FileTimeToLocalFileTime(&ft_created, &ft_created); FileTimeToLocalFileTime(&ft_accessed, &ft_accessed); @@ -1448,14 +2355,15 @@ P_FileTime P_GetFileTime(P_File file) .accessed = P_W32_DateTimeFromWin32SystemTime(st_accessed), .modified = P_W32_DateTimeFromWin32SystemTime(st_modified) }; - } else { + } + else + { return (P_FileTime) { 0 }; } } -/* ========================== * - * File map - * ========================== */ +//////////////////////////////// +//~ File map P_FileMap P_OpenFileMap(P_File file) { @@ -1466,7 +2374,8 @@ P_FileMap P_OpenFileMap(P_File file) u8 *base_ptr = 0; HANDLE map_handle = 0; - if (size > 0) { + if (size > 0) + { map_handle = CreateFileMappingW( (HANDLE)file.handle, 0, @@ -1475,7 +2384,8 @@ P_FileMap P_OpenFileMap(P_File file) 0, 0 ); - if (map_handle != INVALID_HANDLE_VALUE) { + if (map_handle != INVALID_HANDLE_VALUE) + { base_ptr = MapViewOfFile( map_handle, FILE_MAP_READ, @@ -1483,14 +2393,16 @@ P_FileMap P_OpenFileMap(P_File file) 0, 0 ); - if (base_ptr == 0) { + if (base_ptr == 0) + { /* Failed to create view */ CloseHandle(map_handle); map_handle = INVALID_HANDLE_VALUE; } } } - if (map_handle == INVALID_HANDLE_VALUE) { + if (map_handle == INVALID_HANDLE_VALUE) + { size = 0; } map.handle = (u64)map_handle; @@ -1503,10 +2415,12 @@ P_FileMap P_OpenFileMap(P_File file) void P_CloseFileMap(P_FileMap map) { - if (map.mapped_memory.text) { + if (map.mapped_memory.text) + { UnmapViewOfFile(map.mapped_memory.text); } - if (map.handle) { + if (map.handle) + { CloseHandle((HANDLE)map.handle); } } @@ -1516,28 +2430,29 @@ String P_GetFileMapData(P_FileMap map) return map.mapped_memory; } - -/* ========================== * - * Watch - * ========================== */ +//////////////////////////////// +//~ Watch P_Watch *P_AllocWatch(String dir_path) { TempArena scratch = scratch_begin_no_conflict(); - struct P_W32_Ctx *g = &P_W32_g_shared_ctx; + struct P_W32_SharedCtx *g = &P_W32_shared_ctx; P_W32_Watch *w32_watch = 0; { - P_Lock lock = snc_lock_e(&g->watches_mutex); + P_Lock lock = P_LockE(&g->watches_mutex); { - if (g->watches_first_free) { + if (g->watches_first_free) + { w32_watch = g->watches_first_free; g->watches_first_free = w32_watch->next_free; - } else { + } + else + { w32_watch = arena_push_no_zero(g->watches_arena, P_W32_Watch); } } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(w32_watch); @@ -1561,16 +2476,16 @@ P_Watch *P_AllocWatch(String dir_path) void P_ReleaseWatch(P_Watch *dw) { P_W32_Watch *w32_watch = (P_W32_Watch *)dw; - struct P_W32_Ctx *g = &P_W32_g_shared_ctx; + struct P_W32_SharedCtx *g = &P_W32_shared_ctx; CloseHandle(w32_watch->dir_handle); CloseHandle(w32_watch->wake_handle); - P_Lock lock = snc_lock_e(&g->watches_mutex); + P_Lock lock = P_LockE(&g->watches_mutex); { w32_watch->next_free = g->watches_first_free; g->watches_first_free = w32_watch; } - snc_unlock(&lock); + P_Unlock(&lock); } P_WatchInfoList P_ReadWatchWait(Arena *arena, P_Watch *dw) @@ -1585,7 +2500,8 @@ P_WatchInfoList P_ReadWatchWait(Arena *arena, P_Watch *dw) FILE_NOTIFY_CHANGE_CREATION; b32 done = 0; - while (!done) { + while (!done) + { OVERLAPPED ov = ZI; ov.hEvent = CreateEventW(0, 0, 0, 0); ASSERT(ov.hEvent); @@ -1607,16 +2523,21 @@ P_WatchInfoList P_ReadWatchWait(Arena *arena, P_Watch *dw) }; DWORD wait_res = WaitForMultipleObjects(2, handles, 0, INFINITE); - if (wait_res == WAIT_OBJECT_0) { + if (wait_res == WAIT_OBJECT_0) + { i64 offset = 0; - while (!done) { + while (!done) + { FILE_NOTIFY_INFORMATION *res = (FILE_NOTIFY_INFORMATION *)(w32_watch->results_buff + offset); P_WatchInfo *info = arena_push(arena, P_WatchInfo); - if (list.last) { + if (list.last) + { list.last->next = info; info->prev = list.last; - } else { + } + else + { list.first = info; } list.last = info; @@ -1627,13 +2548,16 @@ P_WatchInfoList P_ReadWatchWait(Arena *arena, P_Watch *dw) name16.len = res->FileNameLength / sizeof(wchar_t); info->name = string_from_string16(arena, name16); - for (u64 i = 0; i < info->name.len; ++i) { - if (info->name.text[i] == '\\') { + for (u64 i = 0; i < info->name.len; ++i) + { + if (info->name.text[i] == '\\') + { info->name.text[i] = '/'; } } - switch (res->Action) { + switch (res->Action) + { case FILE_ACTION_ADDED: { info->kind = P_WatchInfoKind_Added; @@ -1665,16 +2589,23 @@ P_WatchInfoList P_ReadWatchWait(Arena *arena, P_Watch *dw) } break; } - if (res->NextEntryOffset == 0) { + if (res->NextEntryOffset == 0) + { done = 1; - } else { + } + else + { offset += res->NextEntryOffset; } } - } else if (wait_res == WAIT_OBJECT_0 + 1) { + } + else if (wait_res == WAIT_OBJECT_0 + 1) + { ResetEvent(w32_watch->wake_handle); done = 1; - } else { + } + else + { ASSERT(0); } } @@ -1688,587 +2619,8 @@ void P_WakeWatch(P_Watch *dw) SetEvent(w32_watch->wake_handle); } -/* ========================== * - * Window - * ========================== */ - -void P_W32_ProcessWindowEvent(P_W32_Window *window, P_WindowEvent event) -{ - __prof; - P_Lock lock = snc_lock_e(&window->event_arena_swp_mutex); - { - *arena_push(window->event_arenas[window->current_event_arena_index], P_WindowEvent) = event; - } - snc_unlock(&lock); -} - -HWND P_W32_InitWindow(P_W32_Window *window) -{ - struct P_W32_Ctx *g = &P_W32_g_shared_ctx; - - /* - * From martins (https://gist.github.com/mmozeiko/5e727f845db182d468a34d524508ad5f#file-win32_d3d11-c-L66-L70): - * WS_EX_NOREDIRECTIONBITMAP flag here is needed to fix ugly bug with Windows 10 - * when window is resized and DXGI swap chain uses FLIP presentation model - * DO NOT use it if you choose to use non-FLIP presentation model - * read about the bug here: https://stackoverflow.com/q/63096226 and here: https://stackoverflow.com/q/53000291 - */ - DWORD exstyle = WS_EX_APPWINDOW | WS_EX_NOREDIRECTIONBITMAP; - - /* TODO: Check for hwnd success */ - HWND hwnd = CreateWindowExW( - exstyle, - g->window_class.lpszClassName, - L"", - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - 0, - 0, - g->window_class.hInstance, - 0 - ); - - /* Dark mode */ - BOOL dark_mode = 1; - DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, (LPCVOID)&dark_mode, sizeof(dark_mode)); - - /* Set window as userdata */ - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)window); - - return hwnd; -} - -P_W32_ThreadDef(P_W32_WindowThreadEntryFunc, arg) -{ - P_W32_Window *window = (P_W32_Window *)arg; - - /* Win32 limitation: Window must be initialized on same thread that processes events */ - window->hwnd = P_W32_InitWindow(window); - P_W32_UpdateWindowFromSystem(window); - BringWindowToTop(window->hwnd); - snc_counter_add(&window->ready_fence, -1); - - while (!atomic32_fetch(&window->shutdown)) { - MSG msg = ZI; - { - GetMessageW(&msg, 0, 0, 0); - } - { - __profn("Process window message"); - if (!atomic32_fetch(&window->shutdown)) { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - } - } - - /* Destroy window hwnd */ - DestroyWindow(window->hwnd); -} - -P_W32_Window *P_W32_AllocWindow(void) -{ - P_W32_Ctx *g = &P_W32_g_shared_ctx; - P_W32_Window *window = 0; - { - P_Lock lock = snc_lock_e(&g->windows_mutex); - if (g->first_free_window) { - window = g->first_free_window; - g->first_free_window = window->next_free; - } else { - window = arena_push_no_zero(g->windows_arena, P_W32_Window); - } - snc_unlock(&lock); - } - MEMZERO_STRUCT(window); - - window->event_arenas[0] = arena_alloc(GIBI(64)); - window->event_arenas[1] = arena_alloc(GIBI(64)); - - /* Start window event thread */ - /* NOTE: This thread must finish building for the window to actually be - * created and receive a HWND, because on Windows a the event proc must run on - * the same thread that created the window. */ - snc_counter_add(&window->ready_fence, 1); - window->window_thread = P_W32_AllocThread(&P_W32_WindowThreadEntryFunc, window, LIT("Window thread"), PROF_THREAD_GROUP_WINDOW); - snc_counter_wait(&window->ready_fence); - - return window; -} - -void P_W32_ReleaseWindow(P_W32_Window *window) -{ - /* Stop window threads */ - atomic32_fetch_set(&window->shutdown, 1); - P_W32_Ctx *g = &P_W32_g_shared_ctx; - P_W32_WakeWindow(window); - P_W32_WaitReleaseThread(window->window_thread); - - P_Lock lock = snc_lock_e(&g->windows_mutex); - { - window->next_free = g->first_free_window; - g->first_free_window = window; - } - snc_unlock(&lock); -} - -P_WindowEventArray P_PopWindowEvents(Arena *arena, P_Window *p_window) -{ - __prof; - P_W32_Window *window = (P_W32_Window *)p_window; - i32 event_arena_index = 0; - { - /* Swap event buffers */ - P_Lock lock = snc_lock_e(&window->event_arena_swp_mutex); - event_arena_index = window->current_event_arena_index; - window->current_event_arena_index = 1 - window->current_event_arena_index; - snc_unlock(&lock); - } - Arena *events_arena = window->event_arenas[event_arena_index]; - P_WindowEventArray events = ZI; - events.count = events_arena->pos / sizeof(P_WindowEvent); - events.events = arena_push_array_no_zero(arena, P_WindowEvent, events.count); - MEMCPY(events.events, arena_base(events_arena), events_arena->pos); - arena_reset(events_arena); - return events; -} - -void P_W32_UpdateWindowFromSystem(P_W32_Window *window) -{ - HWND hwnd = window->hwnd; - - RECT window_rect = ZI; - GetWindowRect(hwnd, &window_rect); - - RECT client_rect = ZI; - GetClientRect(hwnd, (LPRECT)&client_rect); - ClientToScreen(hwnd, (LPPOINT)&client_rect.left); - ClientToScreen(hwnd, (LPPOINT)&client_rect.right); - - /* TODO: Error if we can't get monitor info */ - /* Screen dimensions */ - MONITORINFO monitor_info = { .cbSize = sizeof(monitor_info) }; - GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY), &monitor_info); - RECT monitor_rect = monitor_info.rcMonitor; - window->monitor_width = monitor_rect.right - monitor_rect.left; - window->monitor_height = monitor_rect.bottom - monitor_rect.top; - - /* Minimized / maximized */ - if (window->flags & P_WindowFlag_Showing) { - WINDOWPLACEMENT placement = { .length = sizeof(placement) }; - GetWindowPlacement(hwnd, &placement); - if (placement.showCmd == SW_SHOWMINIMIZED) { - window->settings.flags |= P_WindowSettingsFlag_Minimized; - } else { - window->settings.flags &= ~P_WindowSettingsFlag_Minimized; - } - if (placement.showCmd == SW_SHOWMAXIMIZED - || ((window->settings.flags & P_WindowSettingsFlag_Minimized) && ((placement.flags & WPF_RESTORETOMAXIMIZED) != 0))) { - window->settings.flags |= P_WindowSettingsFlag_Maximized; - } else { - window->settings.flags &= ~P_WindowSettingsFlag_Maximized; - } - } - - /* Window dimensions */ - i32 x = client_rect.left; - i32 y = client_rect.top; - i32 width = client_rect.right - client_rect.left; - i32 height = client_rect.bottom - client_rect.top; - if (!(window->settings.flags & P_WindowSettingsFlag_Minimized)) { - window->x = x; - window->y = y; - window->width = width; - window->height = height; - if (!(window->settings.flags & (P_WindowSettingsFlag_Maximized | P_WindowSettingsFlag_Fullscreen))) { - /* Treat a window resize in non maximized/fullscreen mode as a - * settings change. - * - * TODO: make sure we check for fullscreen here too if we ever - * allow it. */ - window->settings.floating_x = x; - window->settings.floating_y = y; - window->settings.floating_width = width; - window->settings.floating_height = height; - } - } -} - -void P_W32_UpdateWindowFromSettings(P_W32_Window *window, P_WindowSettings *settings) -{ - HWND hwnd = window->hwnd; - - P_WindowSettings old_settings = window->settings; - window->settings = *settings; - - i32 show_cmd = SW_HIDE; - if (window->flags & P_WindowFlag_Showing) { - show_cmd = SW_NORMAL; - if (settings->flags & P_WindowSettingsFlag_Maximized) { - show_cmd = SW_SHOWMAXIMIZED; - } else if (settings->flags & P_WindowSettingsFlag_Minimized) { - show_cmd = SW_MINIMIZE; - } - } - - RECT rect = ZI; - - b32 old_fullscreen = old_settings.flags & P_WindowSettingsFlag_Fullscreen; - b32 fullscreen = settings->flags & P_WindowSettingsFlag_Fullscreen; - - if (fullscreen) { - if (!old_fullscreen) { - /* Entering fullscreen */ - SetWindowLongPtrW(hwnd, GWL_STYLE, WS_POPUP); - } - rect = (RECT) { - .left = 0, - .top = 0, - .right = window->monitor_width, - .bottom = window->monitor_height - }; - } else { - if (old_fullscreen) { - /* Leaving fullscreen */ - SetWindowLongPtrW(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); - } - rect = (RECT) { - .left = settings->floating_x, - .top = settings->floating_y, - .right = settings->floating_x + settings->floating_width, - .bottom = settings->floating_y + settings->floating_height - }; - AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, 0); - } - - WINDOWPLACEMENT wp = { - .length = sizeof(WINDOWPLACEMENT), - .showCmd = show_cmd, - .rcNormalPosition = rect - }; - SetWindowPlacement(hwnd, &wp); - - { - TempArena scratch = scratch_begin_no_conflict(); - wchar_t *title_wstr = wstr_from_string(scratch.arena, string_from_cstr_no_limit(settings->title)); - SetWindowTextW(hwnd, title_wstr); - scratch_end(scratch); - } -} - -void P_W32_WakeWindow(P_W32_Window *window) -{ - /* Post a blank message to the window's thread message queue to wake it. */ - PostMessageW(window->hwnd, 0, 0, 0); -} - -LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - __prof; - P_W32_Ctx *g = &P_W32_g_shared_ctx; - P_W32_Window *window = (P_W32_Window *)GetWindowLongPtrW(hwnd, GWLP_USERDATA); - - if (!window) { - return DefWindowProcW(hwnd, msg, wparam, lparam); - } - - /* Update cursor */ - if (GetFocus() == window->hwnd) { - u32 cursor_flags = window->cursor_set_flags; - - /* Hide cursor */ - if (cursor_flags & P_W32_CursorFlag_Hide) { - while (ShowCursor(0) >= 0); - } - - /* Show cursor */ - if (cursor_flags & P_W32_CursorFlag_Show) { - while (ShowCursor(1) < 0); - } - - /* Update position */ - if (cursor_flags & P_W32_CursorFlag_Position) { - V2 window_space_pos = window->cursor_set_position; - POINT p = { window_space_pos.x, window_space_pos.y }; - ClientToScreen(window->hwnd, &p); - SetCursorPos(p.x, p.y); - } - - /* Stop clipping cursor */ - if (cursor_flags & P_W32_CursorFlag_DisableClip) { - ClipCursor(0); - } - - /* Clip cursor in window window */ - if (cursor_flags & P_W32_CursorFlag_EnableClip) { - i32 left = window->x + math_round_to_int(window->cursor_clip_bounds.x); - i32 right = left + math_round_to_int(window->cursor_clip_bounds.width); - i32 top = window->y + math_round_to_int(window->cursor_clip_bounds.y); - i32 bottom = top + math_round_to_int(window->cursor_clip_bounds.height); - RECT clip = { - .left = clamp_i32(left, window->x, window->x + window->width), - .right = clamp_i32(right, window->x, window->x + window->width), - .top = clamp_i32(top, window->y, window->y + window->height), - .bottom = clamp_i32(bottom, window->y, window->y + window->height) - }; - ClipCursor(&clip); - } - - window->cursor_set_flags = 0; - } - - /* Update always on top */ - { - u32 toggles = atomic32_fetch_set(&window->topmost_toggles, 0); - if (toggles % 2 != 0) { - b32 new_topmost = !window->is_topmost; - if (new_topmost) { - SetWindowText(hwnd, L"============================= TOP ============================="); - } else { - SetWindowText(hwnd, L""); - } - SetWindowPos(hwnd, new_topmost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - window->is_topmost = new_topmost; - } - } - - LRESULT result = 0; - b32 is_release = 0; - switch (msg) { - case WM_QUIT: - case WM_CLOSE: - case WM_DESTROY: - { - P_W32_ProcessWindowEvent(window, (P_WindowEvent) { .kind = P_WindowEventKind_Quit }); - } break; - - case WM_PAINT: - { - result = DefWindowProcW(hwnd, msg, wparam, lparam); - } break; - - case WM_ENTERSIZEMOVE: - case WM_MOVE: - case WM_MOVING: - case WM_SIZE: - case WM_SIZING: - { - P_W32_UpdateWindowFromSystem(window); - result = DefWindowProcW(hwnd, msg, wparam, lparam); - } break; - - /* Keyboard buttons */ - case WM_SYSKEYUP: - case WM_SYSKEYDOWN: - { - if (LOWORD(wparam) != VK_MENU) { - result = DefWindowProcW(hwnd, msg, wparam, lparam); - } - } FALLTHROUGH; - case WM_KEYUP: - case WM_KEYDOWN: - { - WORD vk_code = LOWORD(wparam); - b32 is_repeat = 0; - - P_WindowEventKind event_kind = P_WindowEventKind_None; - if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) { - event_kind = P_WindowEventKind_ButtonDown; - is_repeat = (lparam & 0x40000000) != 0; - } else if (msg == WM_KEYUP || msg == WM_SYSKEYUP) { - event_kind = P_WindowEventKind_ButtonUp; - } - - P_Btn button = P_Btn_None; - if (vk_code < countof(g->vk_btn_table)) { - button = g->vk_btn_table[vk_code]; - } - - P_W32_ProcessWindowEvent( - window, - (P_WindowEvent) - { - .kind = event_kind, - .button = button, - .is_repeat = is_repeat - } - ); - } break; - - /* Text */ - case WM_SYSCHAR: - case WM_CHAR: - { - u16 utf16_char = (u32)wparam; - - /* Decode */ - u32 codepoint = 0; - if (uni_is_utf16_high_surrogate(utf16_char)) { - window->utf16_high_surrogate_last_input = utf16_char; - } else if (uni_is_utf16_low_surrogate(utf16_char)) { - u16 high = window->utf16_high_surrogate_last_input; - u16 low = utf16_char; - if (high) { - u16 utf16_pair_bytes[2] = { high, low }; - Utf16DecodeResult decoded = uni_decode_utf16((String16) { .len = countof(utf16_pair_bytes), .text = utf16_pair_bytes }); - if (decoded.advance16 == 2 && decoded.codepoint < U32_MAX) { - codepoint = decoded.codepoint; - } - } - window->utf16_high_surrogate_last_input = 0; - } else { - window->utf16_high_surrogate_last_input = 0; - codepoint = utf16_char; - } - - if (codepoint) { - if (codepoint == '\r') { - codepoint = '\n'; /* Just treat all \r as newline */ - } - if ((codepoint >= 32 && codepoint != 127) || codepoint == '\t' || codepoint == '\n') { - P_W32_ProcessWindowEvent( - window, - (P_WindowEvent) - { - .kind = P_WindowEventKind_Text, - .text_codepoint = codepoint - } - ); - } - } - - - } break; - - /* Mouse buttons */ - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_XBUTTONUP: - { - ReleaseCapture(); - is_release = 1; - } FALLTHROUGH; - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_XBUTTONDOWN: - { - if (!is_release) { - SetCapture(hwnd); - } - - P_WindowEventKind event_kind = is_release ? P_WindowEventKind_ButtonUp : P_WindowEventKind_ButtonDown; - P_Btn button = 0; - - switch (msg) { - case WM_LBUTTONUP: case WM_LBUTTONDOWN: button = P_Btn_M1; break; - case WM_RBUTTONUP: case WM_RBUTTONDOWN: button = P_Btn_M2; break; - case WM_MBUTTONUP: case WM_MBUTTONDOWN: button = P_Btn_M3; break; - case WM_XBUTTONUP: case WM_XBUTTONDOWN: - { - u32 wparam_xbutton = GET_XBUTTON_WPARAM(wparam); - if (wparam_xbutton == XBUTTON1) { - button = P_Btn_M4; - } else if (wparam_xbutton == XBUTTON2) { - button = P_Btn_M5; - } - } break; - } - - if (button) { - P_W32_ProcessWindowEvent( - window, - (P_WindowEvent) - { - .kind = event_kind, - .button = button - } - ); - } - } break; - - /* Mouse wheel */ - case WM_MOUSEWHEEL: - { - int delta = GET_WHEEL_DELTA_WPARAM(wparam); - i32 dir = delta >= 0 ? 1 : -1; - P_Btn button = dir >= 0 ? P_Btn_MWheelUp : P_Btn_MWheelDown; - for (i32 i = 0; i < (dir * delta); i += WHEEL_DELTA) { - /* Send a button down & button up event simultaneously */ - P_W32_ProcessWindowEvent(window, (P_WindowEvent) { .kind = P_WindowEventKind_ButtonDown, .button = button }); - P_W32_ProcessWindowEvent(window, (P_WindowEvent) { .kind = P_WindowEventKind_ButtonUp, .button = button }); - } - } break; - - /* Mouse move */ - case WM_MOUSEMOVE: - { - i32 x = GET_X_LPARAM(lparam); - i32 y = GET_Y_LPARAM(lparam); - P_W32_ProcessWindowEvent( - window, - (P_WindowEvent) - { - .kind = P_WindowEventKind_CursorMove, - .cursor_position = V2FromXY(x, y) - } - ); - } break; - - /* Raw mouse move */ - case WM_INPUT: - { - TempArena scratch = scratch_begin_no_conflict(); - - /* Read raw input buffer */ - UINT buff_size; - GetRawInputData((HRAWINPUT)lparam, RID_INPUT, 0, &buff_size, sizeof(RAWINPUTHEADER)); - u8 *buff = arena_push_array(scratch.arena, u8, buff_size); - if (GetRawInputData((HRAWINPUT)lparam, RID_INPUT, buff, &buff_size, sizeof(RAWINPUTHEADER)) != buff_size) { - logf_error("GetRawInputData did not return correct size"); - break; - } - RAWINPUT raw = ZI; - MEMCPY(&raw, buff, sizeof(RAWINPUT)); - - if (raw.header.dwType == RIM_TYPEMOUSE) { - i32 x = raw.data.mouse.lLastX; - i32 y = raw.data.mouse.lLastY; - V2 delta = V2FromXY(x, y); - P_W32_ProcessWindowEvent( - window, - (P_WindowEvent) - { - .kind = P_WindowEventKind_MouseMove, - .mouse_delta = delta - } - ); - } - - scratch_end(scratch); - } break; - - /* Minmax info */ - case WM_GETMINMAXINFO: - { - /* Set minimum window size */ - LPMINMAXINFO mmi = (LPMINMAXINFO)lparam; - mmi->ptMinTrackSize.x = 100; - mmi->ptMinTrackSize.y = 100; - } break; - - default: - { - result = DefWindowProcW(hwnd, msg, wparam, lparam); - } break; - } - - return result; -} +//////////////////////////////// +//~ Window P_Window *P_AllocWindow(void) { @@ -2283,15 +2635,38 @@ void P_ReleaseWindow(P_Window *p_window) P_W32_ReleaseWindow(window); } +//- Window events +P_WindowEventArray P_PopWindowEvents(Arena *arena, P_Window *p_window) +{ + __prof; + P_W32_Window *window = (P_W32_Window *)p_window; + i32 event_arena_index = 0; + { + /* Swap event buffers */ + P_Lock lock = P_LockE(&window->event_arena_swp_mutex); + event_arena_index = window->current_event_arena_index; + window->current_event_arena_index = 1 - window->current_event_arena_index; + P_Unlock(&lock); + } + Arena *events_arena = window->event_arenas[event_arena_index]; + P_WindowEventArray events = ZI; + events.count = events_arena->pos / sizeof(P_WindowEvent); + events.events = arena_push_array_no_zero(arena, P_WindowEvent, events.count); + MEMCPY(events.events, arena_base(events_arena), events_arena->pos); + arena_reset(events_arena); + return events; +} + +//- Window settings void P_UpdateWindowSettings(P_Window *p_window, P_WindowSettings *settings) { __prof; P_W32_Window *window = (P_W32_Window *)p_window; - P_Lock lock = snc_lock_e(&window->settings_mutex); + P_Lock lock = P_LockE(&window->settings_mutex); { P_W32_UpdateWindowFromSettings(window, settings); } - snc_unlock(&lock); + P_Unlock(&lock); } /* FIXME: Lock settings mutex for these functions */ @@ -2306,38 +2681,23 @@ void P_ShowWindow(P_Window *p_window) { P_W32_Window *window = (P_W32_Window *)p_window; HWND hwnd = window->hwnd; - P_Lock lock = snc_lock_e(&window->settings_mutex); + P_Lock lock = P_LockE(&window->settings_mutex); { i32 show_cmd = SW_NORMAL; P_WindowSettings *settings = &window->settings; - if (settings->flags & P_WindowSettingsFlag_Maximized) { + if (settings->flags & P_WindowSettingsFlag_Maximized) + { show_cmd = SW_SHOWMAXIMIZED; - } else if (settings->flags & P_WindowSettingsFlag_Minimized) { + } + else if (settings->flags & P_WindowSettingsFlag_Minimized) + { show_cmd = SW_MINIMIZE; } window->flags |= P_WindowFlag_Showing; ShowWindow(hwnd, show_cmd); BringWindowToTop(hwnd); } - snc_unlock(&lock); -} - -V2 P_GetWindowSize(P_Window *p_window) -{ - P_W32_Window *window = (P_W32_Window *)p_window; - return V2FromXY((f32)window->width, (f32)window->height); -} - -V2 P_GetWindowMonitorSize(P_Window *p_window) -{ - P_W32_Window *window = (P_W32_Window *)p_window; - return V2FromXY((f32)window->monitor_width, (f32)window->monitor_height); -} - -u64 P_GetInternalWindowHandle(P_Window *p_window) -{ - P_W32_Window *window = (P_W32_Window *)p_window; - return (u64)window->hwnd; + P_Unlock(&lock); } void P_SetWindowCursorPos(P_Window *p_window, V2 pos) @@ -2384,9 +2744,27 @@ void P_ToggleWindowTopmost(P_Window *p_window) P_W32_WakeWindow(window); } -/* ========================== * - * Address - * ========================== */ +//- Window info +V2 P_GetWindowSize(P_Window *p_window) +{ + P_W32_Window *window = (P_W32_Window *)p_window; + return V2FromXY((f32)window->width, (f32)window->height); +} + +V2 P_GetWindowMonitorSize(P_Window *p_window) +{ + P_W32_Window *window = (P_W32_Window *)p_window; + return V2FromXY((f32)window->monitor_width, (f32)window->monitor_height); +} + +u64 P_GetInternalWindowHandle(P_Window *p_window) +{ + P_W32_Window *window = (P_W32_Window *)p_window; + return (u64)window->hwnd; +} + +//////////////////////////////// +//~ Address P_Address P_AddressFromIpPortCstr(char *ip_cstr, char *port_cstr) { @@ -2399,9 +2777,12 @@ P_Address P_AddressFromIpPortCstr(char *ip_cstr, char *port_cstr) struct addrinfo *ai_res = 0; i32 status = getaddrinfo(ip_cstr, port_cstr, &hints, &ai_res); - if (status == 0) { - while (ai_res) { - if (ai_res->ai_family == AF_INET) { + if (status == 0) + { + while (ai_res) + { + if (ai_res->ai_family == AF_INET) + { struct sockaddr_in *sockaddr = (struct sockaddr_in *)ai_res->ai_addr; res.valid = 1; res.family = P_AddressFamily_Ipv4; @@ -2409,7 +2790,9 @@ P_Address P_AddressFromIpPortCstr(char *ip_cstr, char *port_cstr) STATIC_ASSERT(sizeof(sockaddr->sin_addr) == 4); MEMCPY(res.ipnb, (void *)&sockaddr->sin_addr, 4); break; - } else if (ai_res->ai_family == AF_INET6) { + } + else if (ai_res->ai_family == AF_INET6) + { /* TODO: Enable ipv6 */ #if 0 struct sockaddr_in6 *sockaddr = (struct sockaddr_in6 *)ai_res->ai_addr; @@ -2438,59 +2821,82 @@ P_Address P_AddressFromString(String str) char *port_cstr = 0; { u64 colon_count = 0; - for (u64 i = 0; i < str.len; ++i) { + for (u64 i = 0; i < str.len; ++i) + { u8 c = str.text[i]; - if (c == ':') { + if (c == ':') + { ++colon_count; } } u64 ip_len = 0; u64 port_len = 0; u64 parse_len = min_u64(min_u64(str.len, countof(ip_buff) - 1), countof(port_buff) - 1); - if (colon_count > 1 && str.text[0] == '[') { + if (colon_count > 1 && str.text[0] == '[') + { /* Parse ipv6 with port */ b32 parse_addr = 1; - for (u64 i = 1; i < parse_len; ++i) { + for (u64 i = 1; i < parse_len; ++i) + { u8 c = str.text[i]; - if (parse_addr) { - if (c == ']') { + if (parse_addr) + { + if (c == ']') + { parse_addr = 0; - } else { + } + else + { ip_buff[ip_len] = c; ++ip_len; } - } else if (c != ':') { + } + else if (c != ':') + { port_buff[port_len] = c; ++port_len; } } - } else if (colon_count == 1) { + } + else if (colon_count == 1) + { /* Parse address with port */ b32 parse_addr = 1; - for (u64 i = 0; i < parse_len; ++i) { + for (u64 i = 0; i < parse_len; ++i) + { u8 c = str.text[i]; - if (parse_addr) { - if (c == ':') { + if (parse_addr) + { + if (c == ':') + { parse_addr = 0; - } else { + } + else + { ip_buff[ip_len] = c; ++ip_len; } - } else { + } + else + { port_buff[port_len] = c; ++port_len; } } - } else { + } + else + { /* Copy address without port */ ip_len = min_u64(str.len, countof(ip_buff) - 1); MEMCPY(ip_buff, str.text, ip_len); } - if (ip_len > 0) { + if (ip_len > 0) + { ip_buff[ip_len] = 0; ip_cstr = (char *)ip_buff; } - if (port_len > 0) { + if (port_len > 0) + { port_buff[port_len] = 0; port_cstr = (char *)port_buff; @@ -2508,17 +2914,20 @@ P_Address P_AddressFromPort(u16 port) { u8 port_buff_reverse[countof(port_buff)]; u64 port_len = 0; - while (port > 0 && port_len < (countof(port_buff) - 1)) { + while (port > 0 && port_len < (countof(port_buff) - 1)) + { u8 digit = port % 10; port /= 10; port_buff_reverse[port_len] = '0' + digit; ++port_len; } - for (u64 i = 0; i < port_len; ++i) { + for (u64 i = 0; i < port_len; ++i) + { u64 j = port_len - 1 - i; port_buff[i] = port_buff_reverse[j]; } - if (port_len > 0) { + if (port_len > 0) + { port_buff[port_len] = 0; port_cstr = (char *)port_buff; } @@ -2533,11 +2942,15 @@ String P_StringFromAddress(Arena *arena, P_Address address) { String res = ZI; - if (address.family == P_AddressFamily_Ipv6) { + if (address.family == P_AddressFamily_Ipv6) + { /* TODO */ - } else { + } + else + { u8 ip[4]; - for (u32 i = 0; i < 4; ++i) { + for (u32 i = 0; i < 4; ++i) + { ip[i] = ntohs(address.ipnb[i]); } u16 port = ntohs(address.portnb); @@ -2552,92 +2965,25 @@ b32 P_AddressIsEqual(P_Address a, P_Address b) return MEMEQ_STRUCT(&a, &b); } -P_W32_Address P_W32_Win32AddressFromPlatformAddress(P_Address addr) -{ - P_W32_Address res = ZI; - if (addr.family == P_AddressFamily_Ipv4) { - res.family = AF_INET; - res.size = sizeof(struct sockaddr_in); - res.sin.sin_port = addr.portnb; - res.sin.sin_family = res.family; - MEMCPY(&res.sin.sin_addr, addr.ipnb, 4); - } else { - res.family = AF_INET6; - res.sin6.sin6_port = addr.portnb; - res.sin6.sin6_family = res.family; - res.size = sizeof(struct sockaddr_in6); - MEMCPY(&res.sin6.sin6_addr.s6_addr, addr.ipnb, 16); - } - return res; -} - -/* If supplied address has ip INADDR_ANY (0), convert ip to localhost */ -P_W32_Address P_W32_ConvertAnyaddrToLocalhost(P_W32_Address addr) -{ - if (addr.family == AF_INET) { - u8 *bytes = (u8 *)&addr.sin.sin_addr; - b32 is_any = 1; - for (u64 i = 0; i < 4; ++i) { - if (bytes[i] != 0) { - is_any = 0; - break; - } - } - if (is_any) { - bytes[0] = 127; - bytes[3] = 1; - } - } else if (addr.family == AF_INET6) { - u8 *bytes = (u8 *)&addr.sin.sin_addr; - b32 is_any = 1; - for (u64 i = 0; i < 16; ++i) { - if (bytes[i] != 0) { - is_any = 0; - break; - } - } - if (is_any) { - bytes[15] = 1; - } - } - return addr; -} - -P_Address P_W32_PlatformAddressFromWin32Address(P_W32_Address ws_addr) -{ - P_Address res = ZI; - if (ws_addr.family == AF_INET) { - res.family = P_AddressFamily_Ipv4; - res.portnb = ws_addr.sin.sin_port; - MEMCPY(res.ipnb, &ws_addr.sin.sin_addr, 4); - res.valid = 1; - } else if (ws_addr.family == AF_INET6) { - res.family = P_AddressFamily_Ipv6; - res.portnb = ws_addr.sin6.sin6_port; - MEMCPY(res.ipnb, &ws_addr.sin6.sin6_addr.s6_addr, 16); - res.valid = 1; - } - return res; -} - - -/* ========================== * - * Sock - * ========================== */ +//////////////////////////////// +//~ Sock P_Sock *P_AllocSock(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; P_W32_Sock *ws = 0; { - P_Lock lock = snc_lock_e(&g->socks_mutex); - if (g->first_free_sock) { + P_Lock lock = P_LockE(&g->socks_mutex); + if (g->first_free_sock) + { ws = g->first_free_sock; g->first_free_sock = ws->next_free; - } else { + } + else + { ws = arena_push_no_zero(g->socks_arena, P_W32_Sock); } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(ws); @@ -2659,15 +3005,15 @@ P_Sock *P_AllocSock(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size) void P_ReleaseSock(P_Sock *sock) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; P_W32_Sock *ws = (P_W32_Sock *)sock; closesocket(ws->sock); - P_Lock lock = snc_lock_e(&g->socks_mutex); + P_Lock lock = P_LockE(&g->socks_mutex); { ws->next_free = g->first_free_sock; g->first_free_sock = ws; } - snc_unlock(&lock); + P_Unlock(&lock); } P_SockReadResult P_ReadSock(Arena *arena, P_Sock *sock) @@ -2688,7 +3034,8 @@ P_SockReadResult P_ReadSock(Arena *arena, P_Sock *sock) ws_addr.family = ws_addr.sin.sin_family; res.address = P_W32_PlatformAddressFromWin32Address(ws_addr); - if (size >= 0) { + if (size >= 0) + { gstat_add(GSTAT_SOCK_BYTES_RECEIVED, size); res.data.text = read_buff.text; res.data.len = size; @@ -2696,10 +3043,13 @@ P_SockReadResult P_ReadSock(Arena *arena, P_Sock *sock) /* Pop arena back to end of msg */ arena_pop_to(arena, arena->pos - read_buff_size + size); - } else { + } + else + { #if RTC i32 err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK && err != WSAETIMEDOUT && err != WSAECONNRESET) { + if (err != WSAEWOULDBLOCK && err != WSAETIMEDOUT && err != WSAECONNRESET) + { ASSERT(0); } #endif @@ -2713,11 +3063,13 @@ void P_WriteSock(P_Sock *sock, P_Address address, String data) P_W32_Sock *ws = (P_W32_Sock *)sock; P_W32_Address ws_addr = P_W32_Win32AddressFromPlatformAddress(address); i32 size = sendto(ws->sock, (char *)data.text, data.len, 0, &ws_addr.sa, ws_addr.size); - if (size > 0) { + if (size > 0) + { gstat_add(GSTAT_SOCK_BYTES_SENT, size); } #if RTC - if (size != (i32)data.len) { + if (size != (i32)data.len) + { i32 err = WSAGetLastError(); (UNUSED)err; ASSERT(0); @@ -2725,9 +3077,8 @@ void P_WriteSock(P_Sock *sock, P_Address address, String data) #endif } -/* ========================== * - * Util - * ========================== */ +//////////////////////////////// +//~ Util void P_MessageBox(P_MessageBoxKind kind, String message) { @@ -2737,7 +3088,8 @@ void P_MessageBox(P_MessageBoxKind kind, String message) const wchar_t *title = L""; UINT mbox_type = MB_SETFOREGROUND; - switch (kind) { + switch (kind) + { case P_MessageBoxKind_Ok: { mbox_type |= MB_ICONINFORMATION; @@ -2762,7 +3114,7 @@ void P_MessageBox(P_MessageBoxKind kind, String message) } break; } - logf_debug("Showing message box kind %F with text \"%F\"", FMT_SINT(kind), FMT_STR(message)); + P_LogDebugF("Showing message box kind %F with text \"%F\"", FMT_SINT(kind), FMT_STR(message)); MessageBoxExW(0, message_wstr, title, mbox_type, 0); scratch_end(scratch); @@ -2770,13 +3122,15 @@ void P_MessageBox(P_MessageBoxKind kind, String message) void P_SetClipboardText(String str) { - if (OpenClipboard(0)) { + if (OpenClipboard(0)) + { TempArena scratch = scratch_begin_no_conflict(); String16 str16 = string16_from_string(scratch.arena, str); u64 str16_size_bytes = str16.len * 2; EmptyClipboard(); HANDLE handle = GlobalAlloc(GMEM_MOVEABLE, str16_size_bytes + 1); - if (handle) { + if (handle) + { u16 *dest_wstr = (u16 *)GlobalLock(handle); MEMCPY(dest_wstr, str16.text, str16_size_bytes); dest_wstr[str16.len] = 0; @@ -2791,9 +3145,11 @@ void P_SetClipboardText(String str) String P_GetClipboardText(Arena *arena) { String res = ZI; - if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(0)) { + if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(0)) + { HANDLE handle = GetClipboardData(CF_UNICODETEXT); - if (handle) { + if (handle) + { u16 *src_wstr = (u16 *)GlobalLock(handle); res = string_from_string16(arena, string16_from_wstr_no_limit(src_wstr)); GlobalUnlock(handle); @@ -2815,19 +3171,66 @@ u32 P_GetThreadId(void) i64 P_GetCurrentSchedulerPeriodNs(void) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; return atomic64_fetch(&g->current_scheduler_cycle_period_ns.v); } -/* ========================== * - * Exit - * ========================== */ +//////////////////////////////// +//~ Sleep + +void P_SleepPrecise(i64 sleep_time_ns) +{ + __prof; + + i64 big_sleep = P_GetCurrentSchedulerPeriodNs(); + i64 tolerance = (f64)big_sleep * 0.5; + //i64 tolerance = 1000000000; + + i64 now_ns = P_TimeNs(); + i64 target_ns = now_ns + sleep_time_ns; + + /* Sleep */ + while (now_ns < target_ns - big_sleep - tolerance) + { + __profn("Sleep part"); + P_Wait(0, 0, 0, big_sleep); + now_ns = P_TimeNs(); + } + + /* Spin */ + { + __profn("Sleep spin"); + while (now_ns < target_ns) + { + ix_pause(); + now_ns = P_TimeNs(); + } + } +} + +void P_SleepFrame(i64 last_frame_time_ns, i64 target_dt_ns) +{ + if (last_frame_time_ns != 0 && target_dt_ns > 0) + { + i64 now_ns = P_TimeNs(); + i64 last_frame_dt_ns = now_ns - last_frame_time_ns; + i64 sleep_time_ns = target_dt_ns - last_frame_dt_ns; + if (sleep_time_ns > 0) + { + P_SleepPrecise(sleep_time_ns); + } + } +} + +//////////////////////////////// +//~ Exit void P_OnExit(P_ExitFunc *func) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; i32 index = atomic32_fetch_add(&g->num_exit_funcs, 1); - if (index >= P_W32_MaxOnExitFuncs) { + if (index >= P_W32_MaxOnExitFuncs) + { P_Panic(LIT("Maximum on exit functions registered")); } g->exit_funcs[index] = func; @@ -2835,14 +3238,15 @@ void P_OnExit(P_ExitFunc *func) void P_Exit(void) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; SetEvent(g->exit_begin_event); } void P_Panic(String msg) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; - if (atomic32_fetch_test_set(&g->panicking, 0, 1) == 0) { + P_W32_SharedCtx *g = &P_W32_shared_ctx; + if (atomic32_fetch_test_set(&g->panicking, 0, 1) == 0) + { log_panic(msg); wchar_t *wstr = g->panic_wstr; @@ -2856,17 +3260,21 @@ void P_Panic(String msg) * allocation (in case allocation is unreliable) */ String str8 = msg; u64 pos8 = 0; - while (pos8 < str8.len) { + while (pos8 < str8.len) + { String str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 }; Utf8DecodeResult decoded = uni_decode_utf8(str8_remaining); Utf16EncodeResult encoded = uni_encode_utf16(decoded.codepoint); u64 wstr_new_len = wstr_len + encoded.count16; - if (wstr_new_len < (countof(g->panic_wstr) - 1)) { + if (wstr_new_len < (countof(g->panic_wstr) - 1)) + { u16 *dest = wstr + wstr_len; MEMCPY(dest, encoded.chars16, (encoded.count16 << 1)); wstr_len = wstr_new_len; pos8 += decoded.advance8; - } else { + } + else + { break; } } @@ -2881,28 +3289,31 @@ void P_Panic(String msg) SetEvent(g->panic_event); /* Wait for process termination */ - if (GetCurrentThreadId() != g->main_thread_id) { + if (GetCurrentThreadId() != g->main_thread_id) + { Sleep(INFINITE); } } } -/* ========================== * - * Entry point - * ========================== */ +//////////////////////////////// +//~ Win32 entry point void P_W32_InitBtnTable(void) { - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; MEMZERO_ARRAY(g->vk_btn_table); - for (u32 i = 'A', j = P_Btn_A; i <= 'Z'; ++i, ++j) { + for (u32 i = 'A', j = P_Btn_A; i <= 'Z'; ++i, ++j) + { g->vk_btn_table[i] = (P_Btn)j; } - for (u32 i = '0', j = P_Btn_0; i <= '9'; ++i, ++j) { + for (u32 i = '0', j = P_Btn_0; i <= '9'; ++i, ++j) + { g->vk_btn_table[i] = (P_Btn)j; } - for (u32 i = VK_F1, j = P_Btn_F1; i <= VK_F24; ++i, ++j) { + for (u32 i = VK_F1, j = P_Btn_F1; i <= VK_F24; ++i, ++j) + { g->vk_btn_table[i] = (P_Btn)j; } @@ -2939,7 +3350,7 @@ void P_W32_InitBtnTable(void) P_JobDef(P_W32_AppStartupJob, _) { (UNUSED)_; - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; TempArena scratch = scratch_begin_no_conflict(); { String cmdline_args = string_from_wstr(scratch.arena, g->cmdline_args_wstr, countof(g->cmdline_args_wstr)); @@ -2952,10 +3363,11 @@ P_JobDef(P_W32_AppStartupJob, _) P_JobDef(P_W32_AppShutdownJob, _) { __prof; - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; (UNUSED)_; i32 num_funcs = atomic32_fetch(&g->num_exit_funcs); - for (i32 i = num_funcs - 1; i >= 0; --i) { + for (i32 i = num_funcs - 1; i >= 0; --i) + { P_ExitFunc *func = g->exit_funcs[i]; func(); } @@ -2970,7 +3382,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, (UNUSED)show_code; __profthread("Main thread", PROF_THREAD_GROUP_MAIN); - P_W32_Ctx *g = &P_W32_g_shared_ctx; + P_W32_SharedCtx *g = &P_W32_shared_ctx; #if PROFILING /* Start profiler */ @@ -2983,7 +3395,8 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, MEMCPY(cmd, PROFILING_CMD_WSTR, sizeof(PROFILING_CMD_WSTR)); DeleteFileW(PROFILING_FILE_WSTR); b32 success = CreateProcessW(0, cmd, 0, 0, 0, DETACHED_PROCESS, 0, 0, &si, &pi); - if (!success) { + if (!success) + { MessageBoxExW(0, L"Failed to launch profiler using command '" PROFILING_CMD_WSTR L"'.", L"Error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0); } } @@ -2992,29 +3405,38 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, __profn("Set profiler thread affinities"); wchar_t *prefix_name_wstr = PROFILER_THREAD_PREFIX_WSTR; u64 prefix_name_wstr_len = ((i32)sizeof(PROFILER_THREAD_PREFIX_WSTR) >> 1) - 1; - if (prefix_name_wstr_len > 0 && PROFILER_THREAD_AFFINITY_MASK != 0) { + if (prefix_name_wstr_len > 0 && PROFILER_THREAD_AFFINITY_MASK != 0) + { DWORD proc_id = GetCurrentProcessId(); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - if (snapshot != INVALID_HANDLE_VALUE) { + if (snapshot != INVALID_HANDLE_VALUE) + { THREADENTRY32 te = ZI; te.dwSize = sizeof(THREADENTRY32); - if (Thread32First(snapshot, &te)) { - do { - if (te.th32OwnerProcessID == proc_id) { + if (Thread32First(snapshot, &te)) + { + do + { + if (te.th32OwnerProcessID == proc_id) + { i32 thread_id = te.th32ThreadID; HANDLE thread = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); - if (thread) { + if (thread) + { wchar_t *thread_name_wstr = 0; HRESULT hr = GetThreadDescription(thread, &thread_name_wstr); - if (SUCCEEDED(hr)) { + if (SUCCEEDED(hr)) + { u64 thread_name_len = wstr_len_no_limit(thread_name_wstr); - if (thread_name_len >= prefix_name_wstr_len && MEMEQ(thread_name_wstr, prefix_name_wstr, prefix_name_wstr_len)) { + if (thread_name_len >= prefix_name_wstr_len && MEMEQ(thread_name_wstr, prefix_name_wstr, prefix_name_wstr_len)) + { __profn("Set profiler thread affinity"); b32 success = SetThreadAffinityMask(thread, PROFILER_THREAD_AFFINITY_MASK) != 0; { /* Retry until external tools can set correct process affinity */ i32 delay_ms = 16; - while (!success && delay_ms <= 1024) { + while (!success && delay_ms <= 1024) + { __profn("Profiler thread affinity retry"); Sleep(delay_ms); success = SetThreadAffinityMask(thread, PROFILER_THREAD_AFFINITY_MASK) != 0; @@ -3065,11 +3487,13 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, P_W32_AllocFiber(0); /* Init job pools */ - for (P_Pool pool_kind = 0; pool_kind < (i32)countof(g->job_pools); ++pool_kind) { + for (P_Pool pool_kind = 0; pool_kind < (i32)countof(g->job_pools); ++pool_kind) + { P_W32_JobPool *pool = &g->job_pools[pool_kind]; /* Init queues */ - for (P_Priority priority = 0; priority < (i32)countof(pool->job_queues); ++priority) { + for (P_Priority priority = 0; priority < (i32)countof(pool->job_queues); ++priority) + { P_W32_JobQueue *queue = &pool->job_queues[priority]; queue->arena = arena_alloc(GIBI(64)); } @@ -3105,13 +3529,15 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, GetModuleFileNameW(instance, path, countof(path)); ExtractIconExW(path, 0, &wc->hIcon, &wc->hIconSm, 1); - if (!RegisterClassExW(wc)) { + if (!RegisterClassExW(wc)) + { P_Panic(LIT("Failed to register window class")); } } /* Register raw input */ - if (!atomic32_fetch(&g->panicking)) { + if (!atomic32_fetch(&g->panicking)) + { RAWINPUTDEVICE rid = (RAWINPUTDEVICE) { .usUsagePage = 0x01, /* HID_USAGE_PAGE_GENERIC */ .usUsage = 0x02, /* HID_USAGE_GENERIC_MOUSE */ @@ -3140,15 +3566,17 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, atomic64_fetch_set(&g->current_scheduler_cycle_period_ns.v, P_W32_DefaultSchedulerPeriodNs); P_W32_Thread *scheduler_thread = P_W32_AllocThread(P_W32_JobSchedulerEntryFunc, 0, LIT("Scheduler thread"), PROF_THREAD_GROUP_SCHEDULER); - /* Start job workers */ + //- Start job workers /* TODO: Heuristic worker counts & affinities */ { __profn("Start job workers"); - for (P_Pool pool_kind = 0; pool_kind < (i32)countof(g->job_pools); ++pool_kind) { + for (P_Pool pool_kind = 0; pool_kind < (i32)countof(g->job_pools); ++pool_kind) + { P_W32_JobPool *pool = &g->job_pools[pool_kind]; String name_fmt = ZI; i32 prof_group = PROF_THREAD_GROUP_FIBERS - MEBI(pool_kind); - switch (pool_kind) { + switch (pool_kind) + { default: ASSERT(0); break; case P_Pool_Sim: @@ -3193,7 +3621,8 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, pool->worker_threads_arena = arena_alloc(GIBI(64)); pool->worker_threads = arena_push_array(pool->worker_threads_arena, P_W32_Thread *, pool->num_worker_threads); pool->worker_contexts = arena_push_array(pool->worker_threads_arena, P_W32_WorkerCtx, pool->num_worker_threads); - for (i32 i = 0; i < pool->num_worker_threads; ++i) { + for (i32 i = 0; i < pool->num_worker_threads; ++i) + { P_W32_WorkerCtx *ctx = &pool->worker_contexts[i]; ctx->pool_kind = pool_kind; ctx->id = i; @@ -3203,16 +3632,17 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, } } - /* ================================================== * - * App startup */ + //- App startup /* Run app start job */ - if (!atomic32_fetch(&g->panicking)) { + if (!atomic32_fetch(&g->panicking)) + { P_Run(1, P_W32_AppStartupJob, 0, P_Pool_Floating, P_Priority_High, 0); } /* Wait for startup end or panic */ - if (!atomic32_fetch(&g->panicking)) { + if (!atomic32_fetch(&g->panicking)) + { HANDLE handles[] = { g->startup_end_event, g->panic_event @@ -3221,7 +3651,8 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, } /* Wait for exit start or panic */ - if (!atomic32_fetch(&g->panicking)) { + if (!atomic32_fetch(&g->panicking)) + { HANDLE handles[] = { g->exit_begin_event, g->panic_event @@ -3229,16 +3660,17 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, WaitForMultipleObjects(countof(handles), handles, 0, INFINITE); } - /* ================================================== * - * App shutdown */ + //- App shutdown /* Run exit callbacks job */ - if (!atomic32_fetch(&g->panicking)) { + if (!atomic32_fetch(&g->panicking)) + { P_Run(1, P_W32_AppShutdownJob, 0, P_Pool_Floating, P_Priority_High, 0); } /* Wait for exit end or panic */ - if (!atomic32_fetch(&g->panicking)) { + if (!atomic32_fetch(&g->panicking)) + { HANDLE handles[] = { g->exit_end_event, g->panic_event @@ -3247,9 +3679,11 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, } /* Signal shutdown */ - if (!atomic32_fetch(&g->panicking)) { + if (!atomic32_fetch(&g->panicking)) + { atomic32_fetch_set(&g->shutdown, 1); - for (P_Pool pool_kind = 0; pool_kind < (i32)countof(g->job_pools); ++pool_kind) { + for (P_Pool pool_kind = 0; pool_kind < (i32)countof(g->job_pools); ++pool_kind) + { P_W32_JobPool *pool = &g->job_pools[pool_kind]; P_W32_LockTicketMutex(&pool->workers_wake_lock); { @@ -3262,10 +3696,13 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, } /* Wait on worker threads */ - if (!atomic32_fetch(&g->panicking)) { - for (P_Pool pool_kind = 0; pool_kind < (i32)countof(g->job_pools); ++pool_kind) { + if (!atomic32_fetch(&g->panicking)) + { + for (P_Pool pool_kind = 0; pool_kind < (i32)countof(g->job_pools); ++pool_kind) + { P_W32_JobPool *pool = &g->job_pools[pool_kind]; - for (i32 i = 0; i < pool->num_worker_threads; ++i) { + for (i32 i = 0; i < pool->num_worker_threads; ++i) + { P_W32_Thread *worker_thread = pool->worker_threads[i]; P_W32_WaitReleaseThread(worker_thread); } @@ -3273,19 +3710,23 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, } /* Wait on scheduler thread */ - if (!atomic32_fetch(&g->panicking)) { + if (!atomic32_fetch(&g->panicking)) + { P_W32_WaitReleaseThread(scheduler_thread); } /* Find any dangling threads that haven't exited gracefully by now */ - if (!atomic32_fetch(&g->panicking)) { - P_Lock lock = snc_lock_s(&g->threads_mutex); - if (g->first_thread) { + if (!atomic32_fetch(&g->panicking)) + { + P_Lock lock = P_LockS(&g->threads_mutex); + if (g->first_thread) + { TempArena scratch = scratch_begin_no_conflict(); u64 num_dangling_threads = 0; String threads_msg = ZI; threads_msg.text = arena_push_dry(scratch.arena, u8); - for (P_W32_Thread *t = g->first_thread; t; t = t->next) { + for (P_W32_Thread *t = g->first_thread; t; t = t->next) + { String name = string_from_cstr(t->thread_name_cstr, countof(t->thread_name_cstr)); threads_msg.len += string_format(scratch.arena, LIT(" \"%F\"\n"), FMT_STR(name)).len; ++num_dangling_threads; @@ -3294,12 +3735,13 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, P_Panic(threads_msg); scratch_end(scratch); } - snc_unlock(&lock); + P_Unlock(&lock); } /* Exit */ i32 exit_code = 0; - if (atomic32_fetch(&g->panicking)) { + if (atomic32_fetch(&g->panicking)) + { WaitForSingleObject(g->panic_event, INFINITE); MessageBoxExW(0, g->panic_wstr, L"Fatal error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0); exit_code = 1; @@ -3307,9 +3749,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, return exit_code; } -/* ========================== * - * CRT Stub - * ========================== */ +//- CRT stub #if !CRTLIB diff --git a/src/platform/platform_win32.h b/src/platform/platform_win32.h index 809c3eaf..06c360d0 100644 --- a/src/platform/platform_win32.h +++ b/src/platform/platform_win32.h @@ -1,63 +1,21 @@ -#pragma warning(push, 0) -# define UNICODE -# define WIN32_LEAN_AND_MEAN -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#pragma warning(pop) +//////////////////////////////// +//~ Ticket mutex types -#define P_W32_WindowClassName L"power_play_window_class" - -#define P_W32_ThreadStackSize KIBI(64) -#define P_W32_FiberStackSize MEBI(4) - -#define P_W32_ThreadDef(name, arg_name) void name(void *arg_name) -typedef P_W32_ThreadDef(P_W32_ThreadFunc, data); - -/* Assume scheduler cycle is 20hz at start to be conservative */ -#define P_W32_DefaultSchedulerPeriodNs 50000000 -#define P_W32_NumRollingSchedulerPeriods 1000 - -#define P_W32_FiberNamePrefixCstr "Fiber [" -#define P_W32_FiberNameSuffixCstr "]" -#define P_W32_FiberNameMaxSize 64 - -#define P_W32_NumWaitAddrBins 16384 -#define P_W32_NumWaitTimeBins 1024 - -#define P_W32_MaxOnExitFuncs 1024 - -/* Arbitrary threshold for determining when to fall back from a looped WakeByAddressSingle to WakeByAddressAll */ -#define P_W32_WakeAllThreshold 16 - -/* ========================== * - * Ticket mutex - * ========================== */ - -typedef struct P_W32_TicketMutex P_W32_TicketMutex; -struct P_W32_TicketMutex { +Struct(P_W32_TicketMutex) +{ Atomic64Padded ticket; Atomic64Padded serving; }; -void P_W32_LockTicketMutex(P_W32_TicketMutex *tm); +//////////////////////////////// +//~ Thread types -void P_W32_UnlockTicketMutex(P_W32_TicketMutex *tm); +#define P_W32_ThreadStackSize KIBI(64) +#define P_W32_ThreadDef(name, arg_name) void name(void *arg_name) +typedef P_W32_ThreadDef(P_W32_ThreadFunc, data); -/* ========================== * - * Thread - * ========================== */ - -typedef struct P_W32_Thread P_W32_Thread; -struct P_W32_Thread { +Struct(P_W32_Thread) +{ P_W32_ThreadFunc *entry_point; void *thread_data; char thread_name_cstr[256]; @@ -70,22 +28,11 @@ struct P_W32_Thread { HANDLE handle; }; -DWORD WINAPI P_W32_Win32ThreadProc(LPVOID vt); +//////////////////////////////// +//~ Wait list types -P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data, String thread_name, i32 profiler_group); - -b32 P_W32_TryReleaseThread(P_W32_Thread *thread, f32 timeout_seconds); - -void P_W32_WaitReleaseThread(P_W32_Thread *thread); - -/* ========================== * - * Wait list - * ========================== */ - -typedef struct P_W32_JobPool P_W32_JobPool; - -typedef struct P_W32_WaitList P_W32_WaitList; -struct alignas(64) P_W32_WaitList { +AlignedStruct(P_W32_WaitList, 64) +{ u64 value; i16 first_waiter; i16 last_waiter; @@ -95,8 +42,8 @@ struct alignas(64) P_W32_WaitList { }; STATIC_ASSERT(alignof(P_W32_WaitList) == 64); /* Avoid false sharing */ -typedef struct P_W32_WaitBin P_W32_WaitBin; -struct alignas(64) P_W32_WaitBin { +AlignedStruct(P_W32_WaitBin, 64) +{ P_W32_WaitList *first_wait_list; P_W32_WaitList *last_wait_list; P_W32_WaitList *first_free_wait_list; @@ -104,30 +51,31 @@ struct alignas(64) P_W32_WaitBin { }; STATIC_ASSERT(alignof(P_W32_WaitBin) == 64); /* Avoid false sharing */ -typedef struct P_W32_Fiber P_W32_Fiber; -void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers); +//////////////////////////////// +//~ Fiber types -void P_W32_WakeByAddress(void *addr, i32 count); +#define P_W32_FiberStackSize MEBI(4) +#define P_W32_FiberNamePrefixCstr "Fiber [" +#define P_W32_FiberNameSuffixCstr "]" +#define P_W32_FiberNameMaxSize 64 -void P_W32_WakeByTime(u64 time); - -/* ========================== * - * Fiber - * ========================== */ - -typedef enum P_W32_YieldKind { +//- Yield param +typedef i32 P_W32_YieldKind; enum +{ P_W32_YieldKind_None, P_W32_YieldKind_Done, P_W32_YieldKind_Wait, P_W32_YieldKind_Count -} P_W32_YieldKind; +}; -typedef struct P_W32_YieldParam P_W32_YieldParam; -struct P_W32_YieldParam { +Struct(P_W32_YieldParam) +{ P_W32_YieldKind kind; - union { - struct { + union + { + struct + { volatile void *addr; void *cmp; u32 size; @@ -136,8 +84,9 @@ struct P_W32_YieldParam { }; }; -typedef struct P_W32_Fiber P_W32_Fiber; -struct alignas(64) P_W32_Fiber { +//- Fiber +AlignedStruct(P_W32_Fiber, 64) +{ /* ---------------------------------------------------- */ void *addr; /* 08 bytes */ /* ---------------------------------------------------- */ @@ -181,30 +130,19 @@ STATIC_ASSERT(sizeof(P_W32_Fiber) == 128); /* Padding validation (increase if n STATIC_ASSERT(alignof(P_W32_Fiber) == 64); /* Avoid false sharing */ STATIC_ASSERT(offsetof(P_W32_Fiber, wake_lock) % 4 == 0); /* Atomic must be aligned */ -P_W32_Fiber *P_W32_AllocFiber(P_W32_JobPool *pool); +//////////////////////////////// +//~ Job queue types -void P_W32_ReleaseFiber(P_W32_JobPool *pool, P_W32_Fiber *fiber); - -FORCE_INLINE P_W32_Fiber *P_W32_FiberFromId(i16 id); - -FORCE_NO_INLINE void P_W32_FiberResume(P_W32_Fiber *fiber); - -void P_W32_YieldFiber(P_W32_Fiber *fiber, P_W32_Fiber *parent_fiber); - -void P_W32_FiberEntryPoint(void *id_ptr); - -/* ========================== * - * Job queue - * ========================== */ - -typedef struct P_W32_WorkerCtx P_W32_WorkerCtx; -struct alignas(64) P_W32_WorkerCtx { +//- Worker ctx +AlignedStruct(P_W32_WorkerCtx, 64) +{ P_Pool pool_kind; i32 id; }; -typedef struct P_W32_JobInfo P_W32_JobInfo; -struct P_W32_JobInfo { +//- Job info +Struct(P_W32_JobInfo) +{ i32 num_dispatched; i32 count; @@ -217,8 +155,9 @@ struct P_W32_JobInfo { P_W32_JobInfo *next; }; -typedef struct P_W32_JobQueue P_W32_JobQueue; -struct alignas(64) P_W32_JobQueue { +//- Job queue +AlignedStruct(P_W32_JobQueue, 64) +{ P_W32_TicketMutex lock; Arena *arena; @@ -228,8 +167,9 @@ struct alignas(64) P_W32_JobQueue { P_W32_JobInfo *first_free; }; -typedef struct P_W32_JobPool P_W32_JobPool; -struct alignas(64) P_W32_JobPool { +//- Job pool +AlignedStruct(P_W32_JobPool, 64) +{ /* Jobs */ P_W32_JobQueue job_queues[P_Priority_Count]; @@ -250,37 +190,21 @@ struct alignas(64) P_W32_JobPool { P_W32_WorkerCtx *worker_contexts; }; -P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg); +//////////////////////////////// +//~ Window types -P_W32_ThreadDef(P_W32_JobSchedulerEntryFunc, _); - -/* ========================== * - * Time - * ========================== */ - -P_DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st); - -/* ========================== * - * File system - * ========================== */ - -String P_W32_StringFromWin32Path(Arena *arena, wchar_t *src); - -/* ========================== * - * Window - * ========================== */ - -typedef enum P_W32_CursorFlag { +typedef i32 P_W32_CursorFlag; enum +{ P_W32_CursorFlag_None = (0 << 0), P_W32_CursorFlag_Position = (1 << 0), P_W32_CursorFlag_Hide = (1 << 1), P_W32_CursorFlag_Show = (1 << 2), P_W32_CursorFlag_EnableClip = (1 << 3), P_W32_CursorFlag_DisableClip = (1 << 4) -} P_W32_CursorFlag; +}; -typedef struct P_W32_Window P_W32_Window; -struct P_W32_Window { +Struct(P_W32_Window) +{ u32 flags; HWND hwnd; @@ -316,45 +240,26 @@ struct P_W32_Window { P_W32_Window *next_free; }; -void P_W32_ProcessWindowEvent(P_W32_Window *window, P_WindowEvent event); +//////////////////////////////// +//~ Watch types -HWND P_W32_InitWindow(P_W32_Window *window); - -P_W32_ThreadDef(P_W32_WindowThreadEntryFunc, arg); - -P_W32_Window *P_W32_AllocWindow(void); - -void P_W32_ReleaseWindow(P_W32_Window *window); - -void P_W32_UpdateWindowFromSystem(P_W32_Window *window); - -void P_W32_UpdateWindowFromSettings(P_W32_Window *window, P_WindowSettings *settings); - -void P_W32_WakeWindow(P_W32_Window *window); - -LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - -/* ========================== * - * Watch - * ========================== */ - -typedef struct P_W32_Watch P_W32_Watch; -struct P_W32_Watch { +Struct(P_W32_Watch) +{ HANDLE dir_handle; HANDLE wake_handle; P_W32_Watch *next_free; u8 results_buff[KIBI(64)]; }; -/* ========================== * - * Address - * ========================== */ +//////////////////////////////// +//~ Address types -typedef struct P_W32_Address P_W32_Address; -struct P_W32_Address { +Struct(P_W32_Address) +{ i32 size; i32 family; - union { + union + { struct sockaddr_storage sas; struct sockaddr sa; struct sockaddr_in sin; @@ -362,40 +267,34 @@ struct P_W32_Address { }; }; -P_W32_Address P_W32_Win32AddressFromPlatformAddress(P_Address addr); +//////////////////////////////// +//~ Sock types -/* If supplied address has ip INADDR_ANY (0), convert ip to localhost */ -P_W32_Address P_W32_ConvertAnyaddrToLocalhost(P_W32_Address addr); - -P_Address P_W32_PlatformAddressFromWin32Address(P_W32_Address ws_addr); - -/* ========================== * - * Sock - * ========================== */ - -typedef struct P_W32_Sock P_W32_Sock; -struct P_W32_Sock { +Struct(P_W32_Sock) +{ SOCKET sock; P_W32_Sock *next_free; }; -/* ========================== * - * Entry - * ========================== */ +//////////////////////////////// +//~ Shared state +#define P_W32_WindowClassName L"power_play_window_class" -void P_W32_InitBtnTable(void); +/* Assume scheduler cycle is 20hz at start to be conservative */ +#define P_W32_DefaultSchedulerPeriodNs 50000000 +#define P_W32_NumRollingSchedulerPeriods 1000 -P_JobDef(P_W32_AppStartupJob, _); +#define P_W32_NumWaitAddrBins 16384 +#define P_W32_NumWaitTimeBins 1024 -P_JobDef(P_W32_AppShutdownJob, _); +#define P_W32_MaxOnExitFuncs 1024 -/* ========================== * - * Global state - * ========================== */ +/* Arbitrary threshold for determining when to fall back from a looped WakeByAddressSingle to WakeByAddressAll */ +#define P_W32_WakeAllThreshold 16 -typedef struct P_W32_Ctx P_W32_Ctx; -struct P_W32_Ctx { +Struct(P_W32_SharedCtx) +{ SYSTEM_INFO info; i64 timer_start_qpc; i64 ns_per_qpc; @@ -404,7 +303,7 @@ struct P_W32_Ctx { wchar_t cmdline_args_wstr[8192]; - /* Application control flow */ + //- Application control flow Atomic32 panicking; wchar_t panic_wstr[4096]; HANDLE panic_event; @@ -412,58 +311,136 @@ struct P_W32_Ctx { HANDLE exit_begin_event; HANDLE exit_end_event; - /* Key lookup table */ + //- Key lookup table P_Btn vk_btn_table[256]; - /* Threads pool */ + //- Worker thread pool P_Mutex threads_mutex; Arena *threads_arena; P_W32_Thread *first_thread; P_W32_Thread *last_thread; P_W32_Thread *first_free_thread; - /* Watches pool */ + //- Watches pool P_Mutex watches_mutex; Arena *watches_arena; P_W32_Watch *watches_first_free; - /* Windows pool */ + //- Windows pool WNDCLASSEXW window_class; P_Mutex windows_mutex; Arena *windows_arena; P_W32_Window *first_free_window; - /* Sockets pool */ + //- Socket pool WSADATA wsa_data; Arena *socks_arena; P_Mutex socks_mutex; P_W32_Sock *first_free_sock; - /* Exit funcs */ + //- Exit funcs Atomic32 num_exit_funcs; P_ExitFunc *exit_funcs[P_W32_MaxOnExitFuncs]; - /* Scheduler */ + //- Scheduler Atomic64Padded current_scheduler_cycle; Atomic64Padded current_scheduler_cycle_period_ns; - /* Fibers */ + //- Fibers P_W32_TicketMutex fibers_lock; i16 num_fibers; Arena *fiber_names_arena; P_W32_Fiber fibers[MAX_FIBERS]; - /* Wait lists */ + //- Wait lists Atomic64Padded waiter_wake_gen; P_W32_TicketMutex wait_lists_arena_lock; Arena *wait_lists_arena; - /* Wait tables */ + //- Wait tables P_W32_WaitBin wait_addr_bins[P_W32_NumWaitAddrBins]; P_W32_WaitBin wait_time_bins[P_W32_NumWaitTimeBins]; - /* Job pools */ + //- Job pools P_W32_JobPool job_pools[P_Pool_Count]; }; -extern P_W32_Ctx P_W32_g_shared_ctx; +extern P_W32_SharedCtx P_W32_shared_ctx; + +//////////////////////////////// +//~ Ticket mutex operations + +void P_W32_LockTicketMutex(P_W32_TicketMutex *tm); +void P_W32_UnlockTicketMutex(P_W32_TicketMutex *tm); + +//////////////////////////////// +//~ Thread operations + +DWORD WINAPI P_W32_Win32ThreadProc(LPVOID vt); +P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data, String thread_name, i32 profiler_group); +b32 P_W32_TryReleaseThread(P_W32_Thread *thread, f32 timeout_seconds); +void P_W32_WaitReleaseThread(P_W32_Thread *thread); + +//////////////////////////////// +//~ Wait list operations + +void P_W32_WakeLockedFibers(i32 num_fibers, P_W32_Fiber **fibers); +void P_W32_WakeByAddress(void *addr, i32 count); +void P_W32_WakeByTime(u64 time); + +//////////////////////////////// +//~ Fiber operations + +P_W32_Fiber *P_W32_AllocFiber(P_W32_JobPool *pool); +void P_W32_ReleaseFiber(P_W32_JobPool *pool, P_W32_Fiber *fiber); +FORCE_INLINE P_W32_Fiber *P_W32_FiberFromId(i16 id); +FORCE_NO_INLINE void P_W32_FiberResume(P_W32_Fiber *fiber); +void P_W32_YieldFiber(P_W32_Fiber *fiber, P_W32_Fiber *parent_fiber); +void P_W32_FiberEntryPoint(void *id_ptr); + +//////////////////////////////// +//~ Workers + +P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg); +P_W32_ThreadDef(P_W32_JobSchedulerEntryFunc, _); + +//////////////////////////////// +//~ Time operations + +P_DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st); + +//////////////////////////////// +//~ File system operations + +String P_W32_StringFromWin32Path(Arena *arena, wchar_t *src); + +//////////////////////////////// +//~ Window operations + +P_W32_Window *P_W32_AllocWindow(void); +void P_W32_ReleaseWindow(P_W32_Window *window); +HWND P_W32_InitWindow(P_W32_Window *window); + +//- Window settings +void P_W32_UpdateWindowFromSystem(P_W32_Window *window); +void P_W32_UpdateWindowFromSettings(P_W32_Window *window, P_WindowSettings *settings); + +//- Window thread +P_W32_ThreadDef(P_W32_WindowThreadEntryFunc, arg); +void P_W32_ProcessWindowEvent(P_W32_Window *window, P_WindowEvent event); +void P_W32_WakeWindow(P_W32_Window *window); +LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); + +//////////////////////////////// +//~ Address operations + +P_W32_Address P_W32_Win32AddressFromPlatformAddress(P_Address addr); +P_W32_Address P_W32_ConvertAnyaddrToLocalhost(P_W32_Address addr); +P_Address P_W32_PlatformAddressFromWin32Address(P_W32_Address ws_addr); + +//////////////////////////////// +//~ Entry point + +void P_W32_InitBtnTable(void); +P_JobDef(P_W32_AppStartupJob, _); +P_JobDef(P_W32_AppShutdownJob, _); diff --git a/src/playback/playback_core.h b/src/playback/playback_core.h index 73e20e61..78e31f28 100644 --- a/src/playback/playback_core.h +++ b/src/playback/playback_core.h @@ -1,3 +1,2 @@ -typedef struct PB_StartupReceipt PB_StartupReceipt; -struct PB_StartupReceipt { i32 _; }; +Struct(PB_StartupReceipt) { i32 _; }; PB_StartupReceipt playback_startup(M_StartupReceipt *mixer_sr); diff --git a/src/playback/playback_core_win32.c b/src/playback/playback_core_win32.c index 23d3659f..0b91b067 100644 --- a/src/playback/playback_core_win32.c +++ b/src/playback/playback_core_win32.c @@ -62,7 +62,7 @@ INTERNAL P_ExitFuncDef(playback_shutdown) { __prof; atomic32_fetch_set(&G.shutdown, 1); - snc_counter_wait(&G.playback_job_counter); + P_WaitOnCounter(&G.playback_job_counter); } /* ========================== * diff --git a/src/resource/resource_core.h b/src/resource/resource_core.h index 53f55fd9..dbb4a51e 100644 --- a/src/resource/resource_core.h +++ b/src/resource/resource_core.h @@ -3,8 +3,7 @@ /* A resource contains data that can be retrieved globally by name. * If enabled during compilation, resource data is embedded in the * executable. Otherwise each resource represents a file on disk. */ -typedef struct R_Resource R_Resource; -struct R_Resource { +Struct(R_Resource) { String _data; b32 _exists; #if RESOURCES_EMBEDDED @@ -21,8 +20,7 @@ struct R_Resource { * Startup * ========================== */ -typedef struct R_StartupReceipt R_StartupReceipt; -struct R_StartupReceipt { i32 _; }; +Struct(R_StartupReceipt) { i32 _; }; R_StartupReceipt resource_startup(void); /* ========================== * diff --git a/src/sim/sim_core.c b/src/sim/sim_core.c index a7c05b97..9dbcd8bf 100644 --- a/src/sim/sim_core.c +++ b/src/sim/sim_core.c @@ -37,7 +37,7 @@ GLOBAL struct { ClientStore *nil_client_store; Client *nil_client; Snapshot *nil_snapshot; - struct sim_ent *nil_ent; + Ent *nil_ent; } G = ZI, DEBUG_ALIAS(G, G_sim); /* Accessed via `sim_client_store_nil()` */ @@ -50,7 +50,7 @@ READONLY Client **_g_sim_client_nil = &G.nil_client; READONLY Snapshot **_g_sim_snapshot_nil = &G.nil_snapshot; /* Accessed via `sim_ent_nil()` */ -READONLY struct sim_ent **_g_sim_ent_nil = &G.nil_ent; +READONLY Ent **_g_sim_ent_nil = &G.nil_ent; SimStartupReceipt sim_startup(void) { @@ -72,7 +72,7 @@ SimStartupReceipt sim_startup(void) G.nil_snapshot->client = sim_client_nil(); /* Nil ent */ - G.nil_ent = arena_push(G.nil_arena, struct sim_ent); + G.nil_ent = arena_push(G.nil_arena, Ent); G.nil_ent->ss = sim_snapshot_nil(); G.nil_ent->valid = 0; G.nil_ent->id = SIM_ENT_NIL_ID; @@ -312,7 +312,7 @@ Snapshot *sim_snapshot_alloc(Client *client, Snapshot *src, u64 tick) /* Copy id lookup bins */ ss->num_id_bins = src->num_id_bins > 0 ? src->num_id_bins : ID_LOOKUP_BINS; - ss->id_bins = arena_push_array_no_zero(ss->arena, struct sim_ent_bin, ss->num_id_bins); + ss->id_bins = arena_push_array_no_zero(ss->arena, EntBin, ss->num_id_bins); if (src->num_id_bins > 0) { for (u64 i = 0; i < src->num_id_bins; ++i) { ss->id_bins[i] = src->id_bins[i]; @@ -325,20 +325,20 @@ Snapshot *sim_snapshot_alloc(Client *client, Snapshot *src, u64 tick) ss->first_free_ent = src->first_free_ent; ss->num_ents_allocated = src->num_ents_allocated; ss->num_ents_reserved = src->num_ents_reserved; - ss->ents = arena_push_array_no_zero(ss->ents_arena, struct sim_ent, ss->num_ents_reserved); + ss->ents = arena_push_array_no_zero(ss->ents_arena, Ent, ss->num_ents_reserved); if (ss->num_ents_reserved == 0) { /* Copying from nil snapshot, need to create blank & root entity */ /* Push blank ent at index 0 (because index 0 is never valid anyway since it maps to sim_ent_nil()) */ { - arena_push(ss->ents_arena, struct sim_ent); + arena_push(ss->ents_arena, Ent); ++ss->num_ents_allocated; ++ss->num_ents_reserved; } /* Push root ent with constant id */ { - struct sim_ent *root = arena_push_no_zero(ss->ents_arena, struct sim_ent); + Ent *root = arena_push_no_zero(ss->ents_arena, Ent); *root = *sim_ent_nil(); root->ss = ss; root->valid = 1; @@ -351,8 +351,8 @@ Snapshot *sim_snapshot_alloc(Client *client, Snapshot *src, u64 tick) } } else { for (u64 i = 0; i < ss->num_ents_reserved; ++i) { - struct sim_ent *dst_ent = &ss->ents[i]; - struct sim_ent *src_ent = &src->ents[i]; + Ent *dst_ent = &ss->ents[i]; + Ent *src_ent = &src->ents[i]; *dst_ent = *src_ent; dst_ent->ss = ss; } @@ -594,9 +594,9 @@ void sim_snapshot_set_tile(Snapshot *ss, V2i32 world_tile_index, TileKind tile_k V2i32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index); EntId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index); - struct sim_ent *chunk_ent = sim_ent_from_id(ss, chunk_id); + Ent *chunk_ent = sim_ent_from_id(ss, chunk_id); if (!chunk_ent->valid) { - struct sim_ent *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID); + Ent *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID); chunk_ent = sim_ent_alloc_sync_src_with_id(root, chunk_id); sim_ent_enable_prop(chunk_ent, SEPROP_TILE_CHUNK); chunk_ent->tile_chunk_index = chunk_index; @@ -645,9 +645,9 @@ Snapshot *sim_snapshot_alloc_from_lerp(Client *client, Snapshot *ss0, Snapshot * __profn("Lerp snapshot entities"); u64 num_entities = min_u64(ss0->num_ents_reserved, ss1->num_ents_reserved); for (u64 i = 0; i < num_entities; ++i) { - struct sim_ent *e = &ss->ents[i]; - struct sim_ent *e0 = &ss0->ents[i]; - struct sim_ent *e1 = &ss1->ents[i]; + Ent *e = &ss->ents[i]; + Ent *e0 = &ss0->ents[i]; + Ent *e1 = &ss1->ents[i]; sim_ent_lerp(e, e0, e1, blend); } } @@ -670,24 +670,24 @@ void sim_snapshot_sync_ents(Snapshot *local_ss, Snapshot *remote_ss, EntId remot * - Determine new UUIDs for newly created ents */ - struct sim_ent *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID); - struct sim_ent *remote_root = sim_ent_from_id(remote_ss, SIM_ENT_ROOT_ID); + Ent *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID); + Ent *remote_root = sim_ent_from_id(remote_ss, SIM_ENT_ROOT_ID); /* Create new ents from remote */ - for (struct sim_ent *remote_top = sim_ent_from_id(remote_ss, remote_root->first); remote_top->valid; remote_top = sim_ent_from_id(remote_ss, remote_top->next)) { + for (Ent *remote_top = sim_ent_from_id(remote_ss, remote_root->first); remote_top->valid; remote_top = sim_ent_from_id(remote_ss, remote_top->next)) { sim_ent_sync_alloc_tree(local_root, remote_top, remote_player); } /* Sync ents with remote, skipping index 0 (nil) & index 1 (root) */ for (u64 i = 2; i < local_ss->num_ents_reserved; ++i) { - struct sim_ent *local_ent = &local_ss->ents[i]; + Ent *local_ent = &local_ss->ents[i]; if (local_ent->valid && sim_ent_has_prop(local_ent, SEPROP_SYNC_DST)) { b32 should_sync = sim_ent_id_eq(local_ent->owner, remote_player) || sim_ent_id_is_nil(remote_player); if ((sync_flags & SIM_SYNC_FLAG_NOSYNC_PREDICTABLES) && sim_ent_id_eq(local_ent->predictor, local_ss->local_player)) { should_sync = 0; } if (should_sync) { - struct sim_ent *remote_ent = sim_ent_from_id(remote_ss, local_ent->id); + Ent *remote_ent = sim_ent_from_id(remote_ss, local_ent->id); if (remote_ent->valid) { /* Copy all ent data from remote */ sim_ent_sync(local_ent, remote_ent); @@ -741,11 +741,11 @@ void sim_snapshot_encode(BitbuffWriter *bw, Client *receiver, Snapshot *ss0, Sna u32 old_first = 0; u32 old_last = 0; if (i < ss0->num_id_bins) { - struct sim_ent_bin *old_bin = &ss0->id_bins[i]; + EntBin *old_bin = &ss0->id_bins[i]; old_first = old_bin->first; old_last = old_bin->last; } - struct sim_ent_bin *bin = &ss1->id_bins[i]; + EntBin *bin = &ss1->id_bins[i]; b32 first_diff = bin->first != old_first; b32 last_diff = bin->last != old_last; if (first_diff || last_diff) { @@ -774,11 +774,11 @@ void sim_snapshot_encode(BitbuffWriter *bw, Client *receiver, Snapshot *ss0, Sna bw_write_dbg_marker(bw, STRING_FROM_STRUCT(&ss1->num_ents_reserved)); for (u64 i = 1; i < ss1->num_ents_reserved; ++i) { - struct sim_ent *e0 = sim_ent_nil(); + Ent *e0 = sim_ent_nil(); if (i < ss0->num_ents_reserved) { e0 = &ss0->ents[i]; } - struct sim_ent *e1 = &ss1->ents[i]; + Ent *e1 = &ss1->ents[i]; sim_ent_encode(bw, e0, e1); } @@ -811,7 +811,7 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) while (bin_changed) { u32 bin_index = br_read_uv(br); if (bin_index < ss->num_id_bins) { - struct sim_ent_bin *bin = &ss->id_bins[bin_index]; + EntBin *bin = &ss->id_bins[bin_index]; if (br_read_bit(br)) { bin->first = br_read_uv(br); } @@ -838,9 +838,9 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) ss->num_ents_reserved = br_read_uv(br); i64 reserve_diff = (i64)ss->num_ents_reserved - (i64)old_num_ents_reserved; if (reserve_diff > 0) { - arena_push_array_no_zero(ss->ents_arena, struct sim_ent, reserve_diff); + arena_push_array_no_zero(ss->ents_arena, Ent, reserve_diff); for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) { - struct sim_ent *e = &ss->ents[i]; + Ent *e = &ss->ents[i]; *e = *sim_ent_nil(); e->ss = ss; } @@ -854,7 +854,7 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) br_read_dbg_marker(br, LIT("SNAPSHOT ENTS")); br_read_dbg_marker(br, STRING_FROM_STRUCT(&ss->num_ents_reserved)); for (u64 i = 1; i < ss->num_ents_reserved; ++i) { - struct sim_ent *e = &ss->ents[i]; + Ent *e = &ss->ents[i]; e->ss = ss; sim_ent_decode(br, e); } @@ -901,7 +901,7 @@ void sim_snapshot_encode(BitbuffWriter *bw, Client *receiver, Snapshot *ss0, Sna bw_align(bw); for (u64 i = 0; i < ss1->num_ents_reserved; ++i) { - struct sim_ent *e0 = sim_ent_nil(); + Ent *e0 = sim_ent_nil(); if (i < ss0->num_ents_reserved) { e0 = &ss0->ents[i]; } @@ -917,7 +917,7 @@ void sim_snapshot_encode(BitbuffWriter *bw, Client *receiver, Snapshot *ss0, Sna } if (e1->valid) { - struct sim_ent *e1 = &ss1->ents[i]; + Ent *e1 = &ss1->ents[i]; sim_ent_encode(bw, e0, e1); } } @@ -959,9 +959,9 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) ss->num_ents_reserved = br_read_uv(br); i64 reserve_diff = (i64)ss->num_ents_reserved - (i64)old_num_ents_reserved; if (reserve_diff > 0) { - arena_push_array_no_zero(ss->ents_arena, struct sim_ent, reserve_diff); + arena_push_array_no_zero(ss->ents_arena, Ent, reserve_diff); for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) { - struct sim_ent *e = &ss->ents[i]; + Ent *e = &ss->ents[i]; *e = *sim_ent_nil(); e->ss = ss; } @@ -982,7 +982,7 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) if (allocation_changed) { released = br_read_bit(br); if (released) { - struct sim_ent *e = sim_ent_from_index(ss, e); + Ent *e = sim_ent_from_index(ss, e); ASSERT(e->valid); /* An entity that we don't have allocated should never have been marked for release */ if (e->valid) { sim_ent_enable_prop(e, SEPROP_RELEASE); @@ -1019,11 +1019,11 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) for (struct sim_ent_decode_node *n = queue.first; n; n = n->next) { if (n->is_new) { u32 index = n->index; - struct sim_ent *parent = sim_ent_from_index(ss, n->alloc_parent_index); + Ent *parent = sim_ent_from_index(ss, n->alloc_parent_index); ASSERT(!sim_ent_from_index(ss, index)->valid && !sim_ent_from_id(ss, alloc_ent_id)->valid); /* An entity that we have allocated already should never be marked for allocation */ ASSERT(parent->valid); /* Parent for new entity allocation should always be valid */ if (parent->valid && index < ss->num_ents_reserved) { - struct sim_ent *ent = &ss->ents[index]; + Ent *ent = &ss->ents[index]; ent->valid = 1; sim_ent_set_id(ent, n->alloc_ent_id); sim_ent_link_parent(parent, ent); @@ -1038,7 +1038,7 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) for (struct sim_ent_decode_node *n = queue.first; n; n = n->next) { BitbuffReader ent_br = n->br; u32 index = n->index; - struct sim_ent *e = sim_ent_from_index(ss, index); + Ent *e = sim_ent_from_index(ss, index); if (e->valid) { sim_ent_decode(&ent_br, e); } else { @@ -1056,9 +1056,9 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) ss->num_ents_reserved = br_read_uv(br); i64 reserve_diff = (i64)ss->num_ents_reserved - (i64)old_num_ents_reserved; if (reserve_diff > 0) { - arena_push_array_no_zero(ss->ents_arena, struct sim_ent, reserve_diff); + arena_push_array_no_zero(ss->ents_arena, Ent, reserve_diff); for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) { - struct sim_ent *e = &ss->ents[i]; + Ent *e = &ss->ents[i]; *e = *sim_ent_nil(); e->ss = ss; } @@ -1077,7 +1077,7 @@ void sim_snapshot_decode(BitbuffReader *br, Snapshot *ss) } for (u64 i = 0; i < ss->num_ents_reserved; ++i) { - struct sim_ent *e = &ss->ents[i]; + Ent *e = &ss->ents[i]; e->ss = ss; b32 valid_changed = br_read_bit(br); diff --git a/src/sim/sim_core.h b/src/sim/sim_core.h index ddc306bc..ba3385e2 100644 --- a/src/sim/sim_core.h +++ b/src/sim/sim_core.h @@ -11,13 +11,11 @@ #define SIM_LAYER_RELATIVE_DEFAULT (0) #define SIM_LAYER_RELATIVE_WEAPON (1) -typedef struct EntId EntId; -struct EntId { +Struct(EntId) { UID uid; }; -typedef struct ClientHandle ClientHandle; -struct ClientHandle { +Struct(ClientHandle) { u32 idx; u32 gen; }; @@ -26,23 +24,19 @@ struct ClientHandle { * Startup * ========================== */ -typedef struct SimStartupReceipt SimStartupReceipt; -struct SimStartupReceipt { i32 _; }; +Struct(SimStartupReceipt) { i32 _; }; SimStartupReceipt sim_startup(void); /* ========================== * * Client store * ========================== */ -typedef struct ClientLookupBin ClientLookupBin; -struct ClientLookupBin { - ClientHandle first; - ClientHandle last; +Struct(ClientLookupBin) { + struct ClientHandle first; + struct ClientHandle last; }; -typedef struct Client Client; -typedef struct ClientStore ClientStore; -struct ClientStore { +Struct(ClientStore) { b32 valid; Arena *arena; @@ -52,7 +46,7 @@ struct ClientStore { /* Clients */ Arena *clients_arena; - Client *clients; + struct Client *clients; ClientHandle first_free_client; u64 num_clients_allocated; u64 num_clients_reserved; @@ -71,15 +65,12 @@ void sim_client_store_release(ClientStore *store); * Client * ========================== */ -typedef struct Snapshot Snapshot; -typedef struct SnapshotLookupBin SnapshotLookupBin; -struct SnapshotLookupBin { - Snapshot *first; - Snapshot *last; +Struct(SnapshotLookupBin) { + struct Snapshot *first; + struct Snapshot *last; }; -typedef struct Client Client; -struct Client { +Struct(Client) { b32 valid; ClientHandle handle; ClientStore *store; @@ -114,7 +105,7 @@ struct Client { u64 first_tick; u64 last_tick; u64 num_ticks; - Snapshot *first_free_snapshot; + struct Snapshot *first_free_snapshot; /* Tick -> snapshot lookup */ u64 num_snapshot_lookup_bins; @@ -143,11 +134,11 @@ Client *sim_client_from_handle(ClientStore *store, ClientHandle handle); * Snapshot * ========================== */ -typedef enum SyncFlag { +typedef i32 SyncFlag; enum { SIM_SYNC_FLAG_NOSYNC_PREDICTABLES = 1 << 0 -} SyncFlag; +}; -typedef enum ControlFlag { +typedef i32 ControlFlag; enum { SIM_CONTROL_FLAG_FIRE = 1 << 0, SIM_CONTROL_FLAG_FIRE_ALT = 1 << 1, @@ -163,36 +154,32 @@ typedef enum ControlFlag { SIM_CONTROL_FLAG_TILE_TEST = 1 << 10, SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 11, SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 12, -} ControlFlag; +}; -typedef struct ControlData ControlData; -struct ControlData { +Struct(ControlData) { V2 move; /* Movement direction vector (speed of 0 -> 1) */ V2 focus; /* Focus direction vector (where does the controller want to look) */ V2 dbg_cursor; /* Where is the user's cursor in the world (used for things like editing the world) */ u32 flags; }; -typedef enum CmdKind { +typedef i32 CmdKind; enum { SIM_CMD_KIND_INVALID, SIM_CMD_KIND_CONTROL, SIM_CMD_KIND_CHAT -} CmdKind; +}; -typedef enum TileKind { +typedef i32 TileKind; enum { SIM_TILE_KIND_NONE, SIM_TILE_KIND_WALL, NUM_SIM_TILE_KINDS -} TileKind; +}; STATIC_ASSERT(NUM_SIM_TILE_KINDS < 256); /* Tile kind must fit in 8 bits */ -struct sim_ent_bin; - -typedef struct Snapshot Snapshot; -struct Snapshot { +Struct(Snapshot) { b32 valid; u64 tick; Client *client; @@ -218,12 +205,12 @@ struct Snapshot { EntId local_player; /* Id lookup */ - struct sim_ent_bin *id_bins; + struct EntBin *id_bins; u64 num_id_bins; /* Entities */ Arena *ents_arena; - struct sim_ent *ents; + struct Ent *ents; u32 first_free_ent; u32 num_ents_allocated; u32 num_ents_reserved; diff --git a/src/sim/sim_ent.c b/src/sim/sim_ent.c index 52a6182c..c95f61af 100644 --- a/src/sim/sim_ent.c +++ b/src/sim/sim_ent.c @@ -3,12 +3,12 @@ #define SIM_ENT_COLLISION_DEBUG_BASIS_UID (MakeUID(0x302c01182013bb02, 0x570bd270399d11a5)) #define SIM_ENT_TILE_CHUNK_BASIS_UID (MakeUID(0x3ce42de071dd226b, 0x9b566f7df30c813a)) -INTERNAL u32 index_from_ent(Snapshot *ss, struct sim_ent *ent) +INTERNAL u32 index_from_ent(Snapshot *ss, Ent *ent) { return ent - ss->ents; } -INTERNAL struct sim_ent *ent_from_index(Snapshot *ss, u32 index) +INTERNAL Ent *ent_from_index(Snapshot *ss, u32 index) { if (index > 0 && index < ss->num_ents_reserved) { return &ss->ents[index]; @@ -21,19 +21,19 @@ INTERNAL struct sim_ent *ent_from_index(Snapshot *ss, u32 index) * Ent allocation * ========================== */ -struct sim_ent *sim_ent_alloc_raw(Snapshot *ss, struct sim_ent *parent, EntId id) +Ent *sim_ent_alloc_raw(Snapshot *ss, Ent *parent, EntId id) { ASSERT(parent->valid); ASSERT(ss->valid); ASSERT(ss == parent->ss); - struct sim_ent *ent; + Ent *ent; if (ss->first_free_ent > 0 && ss->first_free_ent < ss->num_ents_reserved) { /* Reuse from free list */ ent = &ss->ents[ss->first_free_ent]; ss->first_free_ent = ent->next_free; } else { /* Make new */ - ent = arena_push_no_zero(ss->ents_arena, struct sim_ent); + ent = arena_push_no_zero(ss->ents_arena, Ent); ++ss->num_ents_reserved; } *ent = *sim_ent_nil(); @@ -50,58 +50,58 @@ struct sim_ent *sim_ent_alloc_raw(Snapshot *ss, struct sim_ent *parent, EntId id } /* Allocates a new entity that will not sync */ -struct sim_ent *sim_ent_alloc_local(struct sim_ent *parent) +Ent *sim_ent_alloc_local(Ent *parent) { Snapshot *ss = parent->ss; - struct sim_ent *e = sim_ent_alloc_raw(ss, parent, sim_ent_random_id()); + Ent *e = sim_ent_alloc_raw(ss, parent, sim_ent_random_id()); e->owner = ss->local_player; return e; } -struct sim_ent *sim_ent_alloc_local_with_id(struct sim_ent *parent, EntId id) +Ent *sim_ent_alloc_local_with_id(Ent *parent, EntId id) { Snapshot *ss = parent->ss; - struct sim_ent *e = sim_ent_alloc_raw(ss, parent, id); + Ent *e = sim_ent_alloc_raw(ss, parent, id); e->owner = ss->local_player; return e; } /* Allocates a new entity to be synced to clients */ -struct sim_ent *sim_ent_alloc_sync_src(struct sim_ent *parent) +Ent *sim_ent_alloc_sync_src(Ent *parent) { Snapshot *ss = parent->ss; - struct sim_ent *e = sim_ent_alloc_raw(ss, parent, sim_ent_random_id()); + Ent *e = sim_ent_alloc_raw(ss, parent, sim_ent_random_id()); sim_ent_enable_prop(e, SEPROP_SYNC_SRC); e->owner = ss->local_player; return e; } -struct sim_ent *sim_ent_alloc_sync_src_with_id(struct sim_ent *parent, EntId id) +Ent *sim_ent_alloc_sync_src_with_id(Ent *parent, EntId id) { Snapshot *ss = parent->ss; - struct sim_ent *e = sim_ent_alloc_raw(ss, parent, id); + Ent *e = sim_ent_alloc_raw(ss, parent, id); sim_ent_enable_prop(e, SEPROP_SYNC_SRC); e->owner = ss->local_player; return e; } /* Allocates a new entity that will sync with incoming net src ents containing id, and coming from the specified owner */ -struct sim_ent *sim_ent_alloc_sync_dst(struct sim_ent *parent, EntId ent_id, EntId owner_id) +Ent *sim_ent_alloc_sync_dst(Ent *parent, EntId ent_id, EntId owner_id) { Snapshot *ss = parent->ss; - struct sim_ent *e = sim_ent_alloc_raw(ss, parent, ent_id); + Ent *e = sim_ent_alloc_raw(ss, parent, ent_id); sim_ent_enable_prop(e, SEPROP_SYNC_DST); e->owner = owner_id; return e; } -void sim_ent_release_raw(struct sim_ent *ent) +void sim_ent_release_raw(Ent *ent) { Snapshot *ss = ent->ss; /* Release children */ - struct sim_ent *child = sim_ent_from_id(ss, ent->first); + Ent *child = sim_ent_from_id(ss, ent->first); while (child->valid) { - struct sim_ent *next = sim_ent_from_id(ss, child->next); + Ent *next = sim_ent_from_id(ss, child->next); sim_ent_release_raw(child); child = next; } @@ -116,26 +116,26 @@ void sim_ent_release_raw(struct sim_ent *ent) --ss->num_ents_allocated; } -void sim_ent_release(struct sim_ent *ent) +void sim_ent_release(Ent *ent) { Snapshot *ss = ent->ss; - struct sim_ent *parent = sim_ent_from_id(ss, ent->parent); + Ent *parent = sim_ent_from_id(ss, ent->parent); if (parent->valid) { sim_ent_unlink_from_parent(ent); } sim_ent_release_raw(ent); } -void sim_ent_release_all_with_prop(Snapshot *ss, enum sim_ent_prop prop) +void sim_ent_release_all_with_prop(Snapshot *ss, EntProp prop) { TempArena scratch = scratch_begin_no_conflict(); - struct sim_ent **ents_to_release = arena_push_dry(scratch.arena, struct sim_ent *); + Ent **ents_to_release = arena_push_dry(scratch.arena, Ent *); u64 ents_to_release_count = 0; for (u64 ent_index = 0; ent_index < ss->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ss->ents[ent_index]; + Ent *ent = &ss->ents[ent_index]; if (ent->valid && sim_ent_has_prop(ent, prop)) { - *arena_push_no_zero(scratch.arena, struct sim_ent *) = ent; + *arena_push_no_zero(scratch.arena, Ent *) = ent; ++ents_to_release_count; } } @@ -144,7 +144,7 @@ void sim_ent_release_all_with_prop(Snapshot *ss, enum sim_ent_prop prop) /* TODO: Breadth first iteration to only release parent entities (since * child entities will be released along with parent anyway) */ for (u64 i = 0; i < ents_to_release_count; ++i) { - struct sim_ent *ent = ents_to_release[i]; + Ent *ent = ents_to_release[i]; if (ent->valid && !ent->is_root && !sim_ent_has_prop(ent, SEPROP_CMD) && !sim_ent_has_prop(ent, SEPROP_PLAYER)) { sim_ent_release(ent); } @@ -157,7 +157,7 @@ void sim_ent_release_all_with_prop(Snapshot *ss, enum sim_ent_prop prop) * Activate * ========================== */ -void sim_ent_activate(struct sim_ent *ent, u64 current_tick) +void sim_ent_activate(Ent *ent, u64 current_tick) { sim_ent_enable_prop(ent, SEPROP_ACTIVE); ent->activation_tick = current_tick; @@ -168,26 +168,26 @@ void sim_ent_activate(struct sim_ent *ent, u64 current_tick) * Ent id * ========================== */ -INTERNAL struct sim_ent_bin *bin_from_id(Snapshot *ss, EntId id) +INTERNAL EntBin *bin_from_id(Snapshot *ss, EntId id) { return &ss->id_bins[id.uid.lo % ss->num_id_bins]; } /* NOTE: This should only really happen during ent allocation (it doesn't make sense for an allocated ent's id to change) */ -void sim_ent_set_id(struct sim_ent *ent, EntId id) +void sim_ent_set_id(Ent *ent, EntId id) { Snapshot *ss = ent->ss; EntId old_id = ent->id; if (!sim_ent_id_eq(old_id, id)) { /* Release old from lookup */ if (!sim_ent_id_is_nil(old_id)) { - struct sim_ent_bin *bin = bin_from_id(ss, old_id); + EntBin *bin = bin_from_id(ss, old_id); u32 prev_index = 0; u32 next_index = 0; u32 search_index = bin->first; - struct sim_ent *prev = sim_ent_nil(); - struct sim_ent *next = sim_ent_nil(); - struct sim_ent *search = ent_from_index(ss, search_index); + Ent *prev = sim_ent_nil(); + Ent *next = sim_ent_nil(); + Ent *search = ent_from_index(ss, search_index); while (search->valid) { next_index = search->next_in_id_bin; next = ent_from_index(ss, next_index); @@ -220,15 +220,15 @@ void sim_ent_set_id(struct sim_ent *ent, EntId id) if (!sim_ent_id_is_nil(id)) { #if RTC { - struct sim_ent *existing = sim_ent_from_id(ss, id); + Ent *existing = sim_ent_from_id(ss, id); /* Collision should be extremely unlikely under normal circumstances, there's probably a logic error somewhere. */ ASSERT(!existing->valid); } #endif - struct sim_ent_bin *bin = bin_from_id(ss, id); + EntBin *bin = bin_from_id(ss, id); u32 ent_index = index_from_ent(ss, ent); - struct sim_ent *last = ent_from_index(ss, bin->last); + Ent *last = ent_from_index(ss, bin->last); if (last->valid) { last->next_in_id_bin = ent_index; ent->prev_in_id_bin = bin->last; @@ -244,12 +244,12 @@ void sim_ent_set_id(struct sim_ent *ent, EntId id) } -struct sim_ent *sim_ent_from_id(Snapshot *ss, EntId id) +Ent *sim_ent_from_id(Snapshot *ss, EntId id) { - struct sim_ent *res = sim_ent_nil(); + Ent *res = sim_ent_nil(); if (!sim_ent_id_is_nil(id) && ss->valid) { - struct sim_ent_bin *bin = bin_from_id(ss, id); - for (struct sim_ent *e = ent_from_index(ss, bin->first); e->valid; e = ent_from_index(ss, e->next_in_id_bin)) { + EntBin *bin = bin_from_id(ss, id); + for (Ent *e = ent_from_index(ss, bin->first); e->valid; e = ent_from_index(ss, e->next_in_id_bin)) { if (sim_ent_id_eq(e->id, id)) { res = e; break; @@ -301,12 +301,12 @@ EntId sim_ent_tile_chunk_id_from_tile_chunk_index(V2i32 chunk_index) * Ent query * ========================== */ -struct sim_ent *sim_ent_find_first_match_one(Snapshot *ss, enum sim_ent_prop prop) +Ent *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop) { u64 count = ss->num_ents_reserved; - struct sim_ent *entities = ss->ents; + Ent *entities = ss->ents; for (u64 ent_index = 0; ent_index < count; ++ent_index) { - struct sim_ent *ent = &entities[ent_index]; + Ent *ent = &entities[ent_index]; if (ent->valid && sim_ent_has_prop(ent, prop)) { return ent; } @@ -314,12 +314,12 @@ struct sim_ent *sim_ent_find_first_match_one(Snapshot *ss, enum sim_ent_prop pro return sim_ent_nil(); } -struct sim_ent *sim_ent_find_first_match_all(Snapshot *ss, struct sim_ent_prop_array props) +Ent *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props) { u64 count = ss->num_ents_reserved; - struct sim_ent *entities = ss->ents; + Ent *entities = ss->ents; for (u64 ent_index = 0; ent_index < count; ++ent_index) { - struct sim_ent *ent = &entities[ent_index]; + Ent *ent = &entities[ent_index]; if (ent->valid) { b32 all = 1; for (u64 i = 0; i < props.count; ++i) { @@ -340,11 +340,11 @@ struct sim_ent *sim_ent_find_first_match_all(Snapshot *ss, struct sim_ent_prop_a * Ent tree * ========================== */ -void sim_ent_link_parent(struct sim_ent *ent, struct sim_ent *parent) +void sim_ent_link_parent(Ent *ent, Ent *parent) { Snapshot *ss = ent->ss; - struct sim_ent *old_parent = sim_ent_from_id(ss, ent->parent); + Ent *old_parent = sim_ent_from_id(ss, ent->parent); if (old_parent->valid) { /* Unlink from current parent */ sim_ent_unlink_from_parent(ent); @@ -352,7 +352,7 @@ void sim_ent_link_parent(struct sim_ent *ent, struct sim_ent *parent) EntId ent_id = ent->id; EntId last_child_id = parent->last; - struct sim_ent *last_child = sim_ent_from_id(ss, last_child_id); + Ent *last_child = sim_ent_from_id(ss, last_child_id); if (last_child->valid) { ent->prev = last_child_id; last_child->next = ent_id; @@ -372,14 +372,14 @@ void sim_ent_link_parent(struct sim_ent *ent, struct sim_ent *parent) } /* NOTE: Entity will be dangling after calling this, should re-link to root ent. */ -void sim_ent_unlink_from_parent(struct sim_ent *ent) +void sim_ent_unlink_from_parent(Ent *ent) { Snapshot *ss = ent->ss; EntId parent_id = ent->parent; - struct sim_ent *parent = sim_ent_from_id(ss, parent_id); - struct sim_ent *prev = sim_ent_from_id(ss, ent->prev); - struct sim_ent *next = sim_ent_from_id(ss, ent->next); + Ent *parent = sim_ent_from_id(ss, parent_id); + Ent *prev = sim_ent_from_id(ss, ent->prev); + Ent *next = sim_ent_from_id(ss, ent->next); /* Unlink from parent & siblings */ if (prev->valid) { @@ -400,9 +400,9 @@ void sim_ent_unlink_from_parent(struct sim_ent *ent) * Ent xform * ========================== */ -INTERNAL void sim_ent_mark_child_xforms_dirty(Snapshot *ss, struct sim_ent *ent) +INTERNAL void sim_ent_mark_child_xforms_dirty(Snapshot *ss, Ent *ent) { - for (struct sim_ent *child = sim_ent_from_id(ss, ent->first); child->valid; child = sim_ent_from_id(ss, child->next)) { + for (Ent *child = sim_ent_from_id(ss, ent->first); child->valid; child = sim_ent_from_id(ss, child->next)) { if (child->_is_xform_dirty) { break; } else { @@ -412,14 +412,14 @@ INTERNAL void sim_ent_mark_child_xforms_dirty(Snapshot *ss, struct sim_ent *ent) } } -INTERNAL Xform sim_ent_get_xform_internal(Snapshot *ss, struct sim_ent *ent) +INTERNAL Xform sim_ent_get_xform_internal(Snapshot *ss, Ent *ent) { Xform xf; if (ent->_is_xform_dirty) { if (ent->is_top) { xf = ent->_local_xform; } else { - struct sim_ent *parent = sim_ent_from_id(ss, ent->parent); + Ent *parent = sim_ent_from_id(ss, ent->parent); xf = sim_ent_get_xform_internal(ss, parent); xf = xform_mul(xf, ent->_local_xform); ent->_xform = xf; @@ -433,7 +433,7 @@ INTERNAL Xform sim_ent_get_xform_internal(Snapshot *ss, struct sim_ent *ent) return xf; } -Xform sim_ent_get_xform(struct sim_ent *ent) +Xform sim_ent_get_xform(Ent *ent) { Xform xf; if (ent->_is_xform_dirty) { @@ -441,7 +441,7 @@ Xform sim_ent_get_xform(struct sim_ent *ent) xf = ent->_local_xform; } else { Snapshot *ss = ent->ss; - struct sim_ent *parent = sim_ent_from_id(ss, ent->parent); + Ent *parent = sim_ent_from_id(ss, ent->parent); xf = sim_ent_get_xform_internal(ss, parent); xf = xform_mul(xf, ent->_local_xform); ent->_xform = xf; @@ -455,12 +455,12 @@ Xform sim_ent_get_xform(struct sim_ent *ent) return xf; } -Xform sim_ent_get_local_xform(struct sim_ent *ent) +Xform sim_ent_get_local_xform(Ent *ent) { return ent->_local_xform; } -void sim_ent_set_xform(struct sim_ent *ent, Xform xf) +void sim_ent_set_xform(Ent *ent, Xform xf) { if (!xform_eq(xf, ent->_xform)) { Snapshot *ss = ent->ss; @@ -468,7 +468,7 @@ void sim_ent_set_xform(struct sim_ent *ent, Xform xf) if (ent->is_top) { ent->_local_xform = xf; } else { - struct sim_ent *parent = sim_ent_from_id(ss, ent->parent); + Ent *parent = sim_ent_from_id(ss, ent->parent); Xform parent_global = sim_ent_get_xform_internal(ss, parent); ent->_local_xform = xform_mul(xform_invert(parent_global), xf); } @@ -478,7 +478,7 @@ void sim_ent_set_xform(struct sim_ent *ent, Xform xf) } } -void sim_ent_set_local_xform(struct sim_ent *ent, Xform xf) +void sim_ent_set_local_xform(Ent *ent, Xform xf) { if (!xform_eq(xf, ent->_local_xform)) { ent->_local_xform = xf; @@ -491,21 +491,21 @@ void sim_ent_set_local_xform(struct sim_ent *ent, Xform xf) * Ent movement * ========================== */ -void sim_ent_set_linear_velocity(struct sim_ent *ent, V2 velocity) +void sim_ent_set_linear_velocity(Ent *ent, V2 velocity) { if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { ent->linear_velocity = v2_clamp_len(velocity, SIM_MAX_LINEAR_VELOCITY); } } -void sim_ent_set_angular_velocity(struct sim_ent *ent, f32 velocity) +void sim_ent_set_angular_velocity(Ent *ent, f32 velocity) { if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { ent->angular_velocity = clamp_f32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY); } } -void sim_ent_apply_linear_impulse(struct sim_ent *ent, V2 impulse, V2 point) +void sim_ent_apply_linear_impulse(Ent *ent, V2 impulse, V2 point) { if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { Xform xf = sim_ent_get_xform(ent); @@ -520,7 +520,7 @@ void sim_ent_apply_linear_impulse(struct sim_ent *ent, V2 impulse, V2 point) } } -void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, V2 impulse) +void sim_ent_apply_linear_impulse_to_center(Ent *ent, V2 impulse) { if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { Xform xf = sim_ent_get_xform(ent); @@ -531,14 +531,14 @@ void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, V2 impulse) } } -void sim_ent_apply_force_to_center(struct sim_ent *ent, V2 force) +void sim_ent_apply_force_to_center(Ent *ent, V2 force) { if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { ent->force = v2_add(ent->force, force); } } -void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse) +void sim_ent_apply_angular_impulse(Ent *ent, f32 impulse) { if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { Xform xf = sim_ent_get_xform(ent); @@ -548,7 +548,7 @@ void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse) } } -void sim_ent_apply_torque(struct sim_ent *ent, f32 torque) +void sim_ent_apply_torque(Ent *ent, f32 torque) { if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) { ent->torque += torque; @@ -559,21 +559,21 @@ void sim_ent_apply_torque(struct sim_ent *ent, f32 torque) * Tile * ========================== */ -struct sim_ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, V2i32 chunk_index) +Ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, V2i32 chunk_index) { EntId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index); - struct sim_ent *chunk_ent = sim_ent_from_id(ss, chunk_id); + Ent *chunk_ent = sim_ent_from_id(ss, chunk_id); return chunk_ent; } -struct sim_ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, V2i32 world_tile_index) +Ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, V2i32 world_tile_index) { V2i32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index); - struct sim_ent *chunk_ent = sim_tile_chunk_from_chunk_index(ss, chunk_index); + Ent *chunk_ent = sim_tile_chunk_from_chunk_index(ss, chunk_index); return chunk_ent; } -TileKind sim_get_chunk_tile(struct sim_ent *chunk_ent, V2i32 local_tile_index) +TileKind sim_get_chunk_tile(Ent *chunk_ent, V2i32 local_tile_index) { TileKind res = chunk_ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)]; return res; @@ -583,7 +583,7 @@ TileKind sim_get_chunk_tile(struct sim_ent *chunk_ent, V2i32 local_tile_index) * Ent lerp * ========================== */ -void sim_ent_lerp(struct sim_ent *e, struct sim_ent *e0, struct sim_ent *e1, f64 blend) +void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend) { if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && sim_ent_id_eq(e0->id, e1->id) @@ -624,7 +624,7 @@ void sim_ent_lerp(struct sim_ent *e, struct sim_ent *e0, struct sim_ent *e1, f64 * ========================== */ /* Walks a local & remote ent tree and allocates any missing net dst ents from remote src ents */ -void sim_ent_sync_alloc_tree(struct sim_ent *local_parent, struct sim_ent *remote, EntId remote_player) +void sim_ent_sync_alloc_tree(Ent *local_parent, Ent *remote, EntId remote_player) { __prof; if (sim_ent_has_prop(remote, SEPROP_SYNC_SRC)) { @@ -632,20 +632,20 @@ void sim_ent_sync_alloc_tree(struct sim_ent *local_parent, struct sim_ent *remot Snapshot *remote_ss = remote->ss; EntId id = remote->id; - struct sim_ent *local_ent = sim_ent_from_id(local_ss, id); + Ent *local_ent = sim_ent_from_id(local_ss, id); if (!local_ent->valid) { local_ent = sim_ent_alloc_sync_dst(local_parent, id, remote_player); } - for (struct sim_ent *remote_child = sim_ent_from_id(remote_ss, remote->first); remote_child->valid; remote_child = sim_ent_from_id(remote_ss, remote_child->next)) { + for (Ent *remote_child = sim_ent_from_id(remote_ss, remote->first); remote_child->valid; remote_child = sim_ent_from_id(remote_ss, remote_child->next)) { sim_ent_sync_alloc_tree(local_ent, remote_child, remote_player); } } } /* Copies data between two synced entities */ -void sim_ent_sync(struct sim_ent *local, struct sim_ent *remote) +void sim_ent_sync(Ent *local, Ent *remote) { - struct sim_ent old = *local; + Ent old = *local; MEMCPY_STRUCT(local, remote); /* Why would 2 ents w/ different uids ever be synced? */ @@ -687,7 +687,7 @@ void sim_ent_sync(struct sim_ent *local, struct sim_ent *remote) * Ent encode * ========================== */ -void sim_ent_encode(BitbuffWriter *bw, struct sim_ent *e0, struct sim_ent *e1) +void sim_ent_encode(BitbuffWriter *bw, Ent *e0, Ent *e1) { Snapshot *ss = e1->ss; /* FIXME: Things like xforms need to be retreived manually rather than memcopied. */ @@ -714,7 +714,7 @@ void sim_ent_encode(BitbuffWriter *bw, struct sim_ent *e0, struct sim_ent *e1) * Ent decode * ========================== */ -void sim_ent_decode(BitbuffReader *br, struct sim_ent *e) +void sim_ent_decode(BitbuffReader *br, Ent *e) { Snapshot *old_ss = e->ss; { @@ -739,7 +739,7 @@ void sim_ent_decode(BitbuffReader *br, struct sim_ent *e) * Ent encode * ========================== */ -void sim_ent_encode(BitbuffWriter *bw, struct sim_ent *e0, struct sim_ent *e1) +void sim_ent_encode(BitbuffWriter *bw, Ent *e0, Ent *e1) { Snapshot *ss = e1->ss; @@ -772,9 +772,9 @@ void sim_ent_encode(BitbuffWriter *bw, struct sim_ent *e0, struct sim_ent *e1) * Ent decode * ========================== */ -void sim_ent_decode(BitbuffReader *br, struct sim_ent *e) +void sim_ent_decode(BitbuffReader *br, Ent *e) { - struct sim_ent decoded = *e; + Ent decoded = *e; { u64 pos = 0; while (pos < sizeof(decoded)) { diff --git a/src/sim/sim_ent.h b/src/sim/sim_ent.h index 5b6e5fc4..856cdf11 100644 --- a/src/sim/sim_ent.h +++ b/src/sim/sim_ent.h @@ -1,7 +1,7 @@ #define SIM_ENT_NIL_ID ((EntId) { MakeUID(0, 0) }) #define SIM_ENT_ROOT_ID ((EntId) { MakeUID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) }) -enum sim_ent_prop { +typedef i32 EntProp; enum { SEPROP_ACTIVE, SEPROP_RELEASE, @@ -60,7 +60,7 @@ enum sim_ent_prop { SEPROP_COUNT }; -struct sim_ent { +Struct(Ent) { Snapshot *ss; /* ====================================================================== */ @@ -391,17 +391,17 @@ struct sim_ent { f32 shake; }; -struct sim_ent_array { - struct sim_ent *ents; +Struct(EntArray) { + Ent *ents; u64 count; }; -struct sim_ent_prop_array { - enum sim_ent_prop *props; +Struct(EntPropArray) { + EntProp *props; u64 count; }; -struct sim_ent_bin { +Struct(EntBin) { u32 first; u32 last; }; @@ -410,9 +410,9 @@ struct sim_ent_bin { * Nil * ========================== */ -INLINE struct sim_ent *sim_ent_nil(void) +INLINE Ent *sim_ent_nil(void) { - extern READONLY struct sim_ent **_g_sim_ent_nil; + extern READONLY Ent **_g_sim_ent_nil; return *_g_sim_ent_nil; } @@ -434,43 +434,43 @@ INLINE b32 sim_ent_id_is_nil(EntId id) * Property helpers * ========================== */ -INLINE void sim_ent_enable_prop(struct sim_ent *ent, enum sim_ent_prop prop) +INLINE void sim_ent_enable_prop(Ent *ent, EntProp prop) { u64 index = prop / 64; u64 bit = prop % 64; ent->props[index] |= ((u64)1 << bit); } -INLINE void sim_ent_disable_prop(struct sim_ent *ent, enum sim_ent_prop prop) +INLINE void sim_ent_disable_prop(Ent *ent, EntProp prop) { u64 index = prop / 64; u64 bit = prop % 64; ent->props[index] &= ~((u64)1 << bit); } -INLINE b32 sim_ent_has_prop(struct sim_ent *ent, enum sim_ent_prop prop) +INLINE b32 sim_ent_has_prop(Ent *ent, EntProp prop) { u64 index = prop / 64; u64 bit = prop % 64; return !!(ent->props[index] & ((u64)1 << bit)); } -INLINE b32 sim_ent_is_valid_and_active(struct sim_ent *ent) +INLINE b32 sim_ent_is_valid_and_active(Ent *ent) { return ent->valid && sim_ent_has_prop(ent, SEPROP_ACTIVE); } -INLINE b32 sim_ent_should_predict(struct sim_ent *ent) +INLINE b32 sim_ent_should_predict(Ent *ent) { return sim_ent_id_eq(ent->predictor, ent->ss->local_player); } -INLINE b32 sim_ent_is_owner(struct sim_ent *ent) +INLINE b32 sim_ent_is_owner(Ent *ent) { return sim_ent_id_eq(ent->owner, ent->ss->local_player); } -INLINE b32 sim_ent_should_simulate(struct sim_ent *ent) +INLINE b32 sim_ent_should_simulate(Ent *ent) { b32 res = 0; if (sim_ent_is_valid_and_active(ent)) { @@ -488,63 +488,63 @@ INLINE b32 sim_ent_should_simulate(struct sim_ent *ent) * ========================== */ /* Alloc */ -struct sim_ent *sim_ent_alloc_raw(Snapshot *ss, struct sim_ent *parent, EntId id); -struct sim_ent *sim_ent_alloc_local(struct sim_ent *parent); -struct sim_ent *sim_ent_alloc_local_with_id(struct sim_ent *parent, EntId id); -struct sim_ent *sim_ent_alloc_sync_src(struct sim_ent *parent); -struct sim_ent *sim_ent_alloc_sync_src_with_id(struct sim_ent *parent, EntId id); -struct sim_ent *sim_ent_alloc_sync_dst(struct sim_ent *parent, EntId ent_id, EntId owner_id); +Ent *sim_ent_alloc_raw(Snapshot *ss, Ent *parent, EntId id); +Ent *sim_ent_alloc_local(Ent *parent); +Ent *sim_ent_alloc_local_with_id(Ent *parent, EntId id); +Ent *sim_ent_alloc_sync_src(Ent *parent); +Ent *sim_ent_alloc_sync_src_with_id(Ent *parent, EntId id); +Ent *sim_ent_alloc_sync_dst(Ent *parent, EntId ent_id, EntId owner_id); -void sim_ent_release_raw(struct sim_ent *ent); -void sim_ent_release(struct sim_ent *ent); -void sim_ent_release_all_with_prop(Snapshot *ss, enum sim_ent_prop prop); +void sim_ent_release_raw(Ent *ent); +void sim_ent_release(Ent *ent); +void sim_ent_release_all_with_prop(Snapshot *ss, EntProp prop); /* Activate */ -void sim_ent_activate(struct sim_ent *ent, u64 current_tick); +void sim_ent_activate(Ent *ent, u64 current_tick); /* Id */ -void sim_ent_set_id(struct sim_ent *ent, EntId id); -struct sim_ent *sim_ent_from_id(Snapshot *ss, EntId id); +void sim_ent_set_id(Ent *ent, EntId id); +Ent *sim_ent_from_id(Snapshot *ss, EntId id); EntId sim_ent_random_id(void); EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId id0, EntId id1); EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1); EntId sim_ent_tile_chunk_id_from_tile_chunk_index(V2i32 chunk_start); /* Query */ -struct sim_ent *sim_ent_find_first_match_one(Snapshot *ss, enum sim_ent_prop prop); -struct sim_ent *sim_ent_find_first_match_all(Snapshot *ss, struct sim_ent_prop_array props); +Ent *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop); +Ent *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props); /* Tree */ -void sim_ent_link_parent(struct sim_ent *parent, struct sim_ent *child); -void sim_ent_unlink_from_parent(struct sim_ent *ent); +void sim_ent_link_parent(Ent *parent, Ent *child); +void sim_ent_unlink_from_parent(Ent *ent); /* Xform */ -Xform sim_ent_get_xform(struct sim_ent *ent); -Xform sim_ent_get_local_xform(struct sim_ent *ent); -void sim_ent_set_xform(struct sim_ent *ent, Xform xf); -void sim_ent_set_local_xform(struct sim_ent *ent, Xform xf); +Xform sim_ent_get_xform(Ent *ent); +Xform sim_ent_get_local_xform(Ent *ent); +void sim_ent_set_xform(Ent *ent, Xform xf); +void sim_ent_set_local_xform(Ent *ent, Xform xf); /* Movement */ -void sim_ent_set_linear_velocity(struct sim_ent *ent, V2 velocity); -void sim_ent_set_angular_velocity(struct sim_ent *ent, f32 velocity); -void sim_ent_apply_linear_impulse(struct sim_ent *ent, V2 impulse, V2 world_point); -void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, V2 impulse); -void sim_ent_apply_force_to_center(struct sim_ent *ent, V2 force); -void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse); -void sim_ent_apply_torque(struct sim_ent *ent, f32 torque); +void sim_ent_set_linear_velocity(Ent *ent, V2 velocity); +void sim_ent_set_angular_velocity(Ent *ent, f32 velocity); +void sim_ent_apply_linear_impulse(Ent *ent, V2 impulse, V2 world_point); +void sim_ent_apply_linear_impulse_to_center(Ent *ent, V2 impulse); +void sim_ent_apply_force_to_center(Ent *ent, V2 force); +void sim_ent_apply_angular_impulse(Ent *ent, f32 impulse); +void sim_ent_apply_torque(Ent *ent, f32 torque); /* Tile */ -struct sim_ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, V2i32 chunk_index); -struct sim_ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, V2i32 world_tile_index); -TileKind sim_get_chunk_tile(struct sim_ent *chunk_ent, V2i32 local_tile_index); +Ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, V2i32 chunk_index); +Ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, V2i32 world_tile_index); +TileKind sim_get_chunk_tile(Ent *chunk_ent, V2i32 local_tile_index); /* Lerp */ -void sim_ent_lerp(struct sim_ent *e, struct sim_ent *e0, struct sim_ent *e1, f64 blend); +void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend); /* Sync */ -void sim_ent_sync_alloc_tree(struct sim_ent *local_parent, struct sim_ent *remote, EntId remote_player); -void sim_ent_sync(struct sim_ent *local, struct sim_ent *remote); +void sim_ent_sync_alloc_tree(Ent *local_parent, Ent *remote, EntId remote_player); +void sim_ent_sync(Ent *local, Ent *remote); /* Encode / decode */ -void sim_ent_encode(BitbuffWriter *bw, struct sim_ent *e0, struct sim_ent *e1); -void sim_ent_decode(BitbuffReader *br, struct sim_ent *e); +void sim_ent_encode(BitbuffWriter *bw, Ent *e0, Ent *e1); +void sim_ent_decode(BitbuffReader *br, Ent *e); diff --git a/src/sim/sim_phys.c b/src/sim/sim_phys.c index 8a194447..a9522bc2 100644 --- a/src/sim/sim_phys.c +++ b/src/sim/sim_phys.c @@ -5,7 +5,7 @@ * Contact * ========================== */ -INTERNAL b32 can_contact(struct sim_ent *e0, struct sim_ent *e1) +INTERNAL b32 can_contact(Ent *e0, Ent *e1) { b32 res = 0; res = e0 != e1 && @@ -23,11 +23,11 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_ EntId local_player = ss->local_player; phys_collision_callback_func *collision_callback = ctx->collision_callback; - struct sim_ent *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID); + Ent *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID); u64 tick = ss->tick; for (u64 check0_index = 0; check0_index < ss->num_ents_reserved; ++check0_index) { - struct sim_ent *check0 = &ss->ents[check0_index]; + Ent *check0 = &ss->ents[check0_index]; if (!sim_ent_is_valid_and_active(check0)) continue; if (!(sim_ent_has_prop(check0, SEPROP_SOLID) || sim_ent_has_prop(check0, SEPROP_SENSOR))) continue; if (check0->local_collider.count <= 0) continue; @@ -39,15 +39,15 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_ SpaceIter iter = space_iter_begin_aabb(space, aabb); SpaceEntry *space_entry; while ((space_entry = space_iter_next(&iter)) != 0) { - struct sim_ent *check1 = sim_ent_from_id(ss, space_entry->ent); + Ent *check1 = sim_ent_from_id(ss, space_entry->ent); if (!sim_ent_is_valid_and_active(check1)) continue; if (!(sim_ent_has_prop(check1, SEPROP_SOLID) || sim_ent_has_prop(check1, SEPROP_SENSOR))) continue; if (check1->local_collider.count <= 0) continue; if (!can_contact(check0, check1)) continue; /* Deterministic order based on entity id */ - struct sim_ent *e0; - struct sim_ent *e1; + Ent *e0; + Ent *e1; Xform e0_xf; Xform e1_xf; CLD_Shape e0_collider; @@ -69,7 +69,7 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_ } EntId constraint_id = sim_ent_contact_constraint_id_from_contacting_ids(local_player, e0->id, e1->id); - struct sim_ent *constraint_ent = sim_ent_from_id(ss, constraint_id); + Ent *constraint_ent = sim_ent_from_id(ss, constraint_id); if (constraint_ent->valid) { if (constraint_ent->contact_constraint_data.last_phys_iteration >= phys_iteration) { @@ -229,7 +229,7 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_ #if COLLIDER_DEBUG && COLLIDER_DEBUG_DETAILED { EntId dbg_ent_id = sim_ent_collision_debug_id_from_ids(local_player, e0->id, e1->id); - struct sim_ent *dbg_ent = sim_ent_from_id(ss, dbg_ent_id); + Ent *dbg_ent = sim_ent_from_id(ss, dbg_ent_id); if (!dbg_ent->valid) { /* FIXME: Entity never released */ dbg_ent = sim_ent_alloc_local_with_id(root, dbg_ent_id); @@ -271,15 +271,15 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration) Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *constraint_ent = &ss->ents[sim_ent_index]; + Ent *constraint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(constraint_ent)) continue; if (!sim_ent_has_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT)) continue; ContactConstraint *constraint = &constraint_ent->contact_constraint_data; u32 num_points = constraint->num_points; - struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1); + Ent *e0 = sim_ent_from_id(ss, constraint->e0); + Ent *e1 = sim_ent_from_id(ss, constraint->e1); if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) { V2 normal = constraint->normal; V2 tangent = v2_perp(normal); @@ -355,13 +355,13 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration) #if COLLIDER_DEBUG /* Remove collision debug ents */ for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *dbg_ent = &ss->ents[sim_ent_index]; + Ent *dbg_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(dbg_ent)) continue; if (!sim_ent_has_prop(dbg_ent, SEPROP_COLLISION_DEBUG)) continue; CollisionDebugData *dbg = &dbg_ent->collision_debug_data; - struct sim_ent *e0 = sim_ent_from_id(ss, dbg->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, dbg->e1); + Ent *e0 = sim_ent_from_id(ss, dbg->e0); + Ent *e1 = sim_ent_from_id(ss, dbg->e1); if (!(sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) || !(sim_ent_has_prop(e0, SEPROP_SOLID) || sim_ent_has_prop(e0, SEPROP_SENSOR)) || @@ -380,15 +380,15 @@ void phys_warm_start_contacts(PhysStepCtx *ctx) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *constraint_ent = &ss->ents[sim_ent_index]; + Ent *constraint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(constraint_ent)) continue; if (!sim_ent_has_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT)) continue; ContactConstraint *constraint = &constraint_ent->contact_constraint_data; u32 num_points = constraint->num_points; - struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1); + Ent *e0 = sim_ent_from_id(ss, constraint->e0); + Ent *e1 = sim_ent_from_id(ss, constraint->e1); if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve && !constraint->wrong_dir) { f32 inv_m0 = constraint->inv_m0; @@ -432,14 +432,14 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *constraint_ent = &ss->ents[sim_ent_index]; + Ent *constraint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(constraint_ent)) continue; if (!sim_ent_has_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT)) continue; ContactConstraint *constraint = &constraint_ent->contact_constraint_data; - struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1); + Ent *e0 = sim_ent_from_id(ss, constraint->e0); + Ent *e1 = sim_ent_from_id(ss, constraint->e1); V2 v0 = e0->linear_velocity; V2 v1 = e1->linear_velocity; @@ -570,14 +570,14 @@ void phys_prepare_motor_joints(PhysStepCtx *ctx) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_MOTOR_JOINT)) continue; MotorJoint *joint = &joint_ent->motor_joint_data; - struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1); + Ent *e0 = sim_ent_from_id(ss, joint->e0); + Ent *e1 = sim_ent_from_id(ss, joint->e1); if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) { Xform e0_xf = sim_ent_get_xform(e0); @@ -634,14 +634,14 @@ void phys_warm_start_motor_joints(PhysStepCtx *ctx) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_MOTOR_JOINT)) continue; MotorJoint *joint = &joint_ent->motor_joint_data; - struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1); + Ent *e0 = sim_ent_from_id(ss, joint->e0); + Ent *e1 = sim_ent_from_id(ss, joint->e1); Xform e0_xf = sim_ent_get_xform(e0); Xform e1_xf = sim_ent_get_xform(e1); @@ -666,14 +666,14 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_MOTOR_JOINT)) continue; MotorJoint *joint = &joint_ent->motor_joint_data; - struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1); + Ent *e0 = sim_ent_from_id(ss, joint->e0); + Ent *e1 = sim_ent_from_id(ss, joint->e1); Xform e0_xf = sim_ent_get_xform(e0); Xform e1_xf = sim_ent_get_xform(e1); @@ -772,12 +772,12 @@ void phys_prepare_mouse_joints(PhysStepCtx *ctx) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_MOUSE_JOINT)) continue; MouseJoint *joint = &joint_ent->mouse_joint_data; - struct sim_ent *ent = sim_ent_from_id(ss, joint->target); + Ent *ent = sim_ent_from_id(ss, joint->target); if (sim_ent_should_simulate(ent)) { Xform xf = sim_ent_get_xform(ent); @@ -819,12 +819,12 @@ void phys_warm_start_mouse_joints(PhysStepCtx *ctx) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_MOUSE_JOINT)) continue; MouseJoint *joint = &joint_ent->mouse_joint_data; - struct sim_ent *ent = sim_ent_from_id(ss, joint->target); + Ent *ent = sim_ent_from_id(ss, joint->target); if (sim_ent_should_simulate(ent)) { f32 inv_m = joint->inv_m; f32 inv_i = joint->inv_i; @@ -841,12 +841,12 @@ void phys_solve_mouse_joints(PhysStepCtx *ctx, f32 dt) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_MOUSE_JOINT)) continue; MouseJoint *joint = &joint_ent->mouse_joint_data; - struct sim_ent *ent = sim_ent_from_id(ss, joint->target); + Ent *ent = sim_ent_from_id(ss, joint->target); if (sim_ent_should_simulate(ent)) { V2 v = ent->linear_velocity; f32 w = ent->angular_velocity; @@ -937,15 +937,15 @@ void phys_prepare_weld_joints(PhysStepCtx *ctx) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_WELD_JOINT)) continue; /* TODO: Lookup and disable collision for any contacts between e0 & e1? */ WeldJoint *joint = &joint_ent->weld_joint_data; - struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1); + Ent *e0 = sim_ent_from_id(ss, joint->e0); + Ent *e1 = sim_ent_from_id(ss, joint->e1); if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) { Xform e0_xf = sim_ent_get_xform(e0); Xform e1_xf = sim_ent_get_xform(e1); @@ -986,14 +986,14 @@ void phys_warm_start_weld_joints(PhysStepCtx *ctx) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_WELD_JOINT)) continue; WeldJoint *joint = &joint_ent->weld_joint_data; #if 0 - struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0); + Ent *e0 = sim_ent_from_id(ss, joint->e0); if (sim_ent_should_simulate(e0)) { f32 inv_m = joint->inv_m0; f32 inv_i = joint->inv_i0; @@ -1005,7 +1005,7 @@ void phys_warm_start_weld_joints(PhysStepCtx *ctx) #endif #if 1 - struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1); + Ent *e1 = sim_ent_from_id(ss, joint->e1); if (sim_ent_should_simulate(e1)) { f32 inv_m = joint->inv_m1; f32 inv_i = joint->inv_i1; @@ -1023,13 +1023,13 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *joint_ent = &ss->ents[sim_ent_index]; + Ent *joint_ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(joint_ent)) continue; if (!sim_ent_has_prop(joint_ent, SEPROP_WELD_JOINT)) continue; WeldJoint *joint = &joint_ent->weld_joint_data; - struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0); - struct sim_ent *e1 = sim_ent_from_id(ss, joint->e1); + Ent *e0 = sim_ent_from_id(ss, joint->e0); + Ent *e1 = sim_ent_from_id(ss, joint->e1); if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) { Xform xf0 = sim_ent_get_xform(e0); Xform xf1 = sim_ent_get_xform(e1); @@ -1086,7 +1086,7 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt) * Integration * ========================== */ -INTERNAL Xform get_derived_xform(struct sim_ent *ent, f32 dt) +INTERNAL Xform get_derived_xform(Ent *ent, f32 dt) { Xform xf = sim_ent_get_xform(ent); @@ -1103,7 +1103,7 @@ void phys_integrate_forces(PhysStepCtx *ctx, f32 dt) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *ent = &ss->ents[sim_ent_index]; + Ent *ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(ent)) continue; b32 is_dynamic = sim_ent_has_prop(ent, SEPROP_DYNAMIC); @@ -1145,7 +1145,7 @@ void phys_integrate_velocities(PhysStepCtx *ctx, f32 dt) __prof; Snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *ent = &ss->ents[sim_ent_index]; + Ent *ent = &ss->ents[sim_ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SEPROP_DYNAMIC) && !sim_ent_has_prop(ent, SEPROP_KINEMATIC)) continue; @@ -1166,7 +1166,7 @@ f32 phys_determine_earliest_toi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u3 f32 smallest_t = 1; for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) { - struct sim_ent *e0 = &ss->ents[e0_index]; + Ent *e0 = &ss->ents[e0_index]; if (!sim_ent_should_simulate(e0)) continue; if (!(sim_ent_has_prop(e0, SEPROP_SOLID) || sim_ent_has_prop(e0, SEPROP_SENSOR))) continue; if (!sim_ent_has_prop(e0, SEPROP_TOI)) continue; @@ -1184,7 +1184,7 @@ f32 phys_determine_earliest_toi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u3 SpaceIter iter = space_iter_begin_aabb(space, combined_aabb); SpaceEntry *entry; while ((entry = space_iter_next(&iter)) != 0) { - struct sim_ent *e1 = sim_ent_from_id(ss, entry->ent); + Ent *e1 = sim_ent_from_id(ss, entry->ent); if (!sim_ent_should_simulate(e1)) continue; if (!(sim_ent_has_prop(e1, SEPROP_SOLID) || sim_ent_has_prop(e1, SEPROP_SENSOR))) continue; if (e1->local_collider.count <= 0) continue; @@ -1215,7 +1215,7 @@ void phys_update_aabbs(PhysStepCtx *ctx) Snapshot *ss = ctx->sim_step_ctx->world; Space *space = ctx->sim_step_ctx->accel->space; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *ent = &ss->ents[sim_ent_index]; + Ent *ent = &ss->ents[sim_ent_index]; if (!sim_ent_is_valid_and_active(ent)) continue; if (ent->local_collider.count > 0) { Xform xf = sim_ent_get_xform(ent); diff --git a/src/sim/sim_step.c b/src/sim/sim_step.c index 3abd2b11..8184b629 100644 --- a/src/sim/sim_step.c +++ b/src/sim/sim_step.c @@ -20,7 +20,7 @@ void sim_accel_reset(Snapshot *ss, SimAccel *accel) /* Reset ent space handles */ for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *ent = &ss->ents[sim_ent_index]; + Ent *ent = &ss->ents[sim_ent_index]; if (ent->valid) { MEMZERO_STRUCT(&ent->space_handle); } @@ -33,9 +33,9 @@ void sim_accel_reset(Snapshot *ss, SimAccel *accel) /* TODO: Remove this */ -INTERNAL struct sim_ent *test_spawn_smg(struct sim_ent *parent) +INTERNAL Ent *test_spawn_smg(Ent *parent) { - struct sim_ent *e = sim_ent_alloc_sync_src(parent); + Ent *e = sim_ent_alloc_sync_src(parent); e->sprite = sprite_tag_from_path(LIT("sprite/gun.ase")); sim_ent_enable_prop(e, SEPROP_ATTACHED); @@ -49,9 +49,9 @@ INTERNAL struct sim_ent *test_spawn_smg(struct sim_ent *parent) return e; } -INTERNAL struct sim_ent *test_spawn_launcher(struct sim_ent *parent) +INTERNAL Ent *test_spawn_launcher(Ent *parent) { - struct sim_ent *e = sim_ent_alloc_sync_src(parent); + Ent *e = sim_ent_alloc_sync_src(parent); e->sprite = sprite_tag_from_path(LIT("sprite/gun.ase")); sim_ent_enable_prop(e, SEPROP_ATTACHED); @@ -65,9 +65,9 @@ INTERNAL struct sim_ent *test_spawn_launcher(struct sim_ent *parent) return e; } -INTERNAL struct sim_ent *test_spawn_chucker(struct sim_ent *parent) +INTERNAL Ent *test_spawn_chucker(Ent *parent) { - struct sim_ent *chucker = sim_ent_alloc_sync_src(parent); + Ent *chucker = sim_ent_alloc_sync_src(parent); chucker->sprite = sprite_tag_from_path(LIT("sprite/gun.ase")); sim_ent_enable_prop(chucker, SEPROP_ATTACHED); @@ -80,7 +80,7 @@ INTERNAL struct sim_ent *test_spawn_chucker(struct sim_ent *parent) /* Chucker zone */ { - struct sim_ent *zone = sim_ent_alloc_sync_src(chucker); + Ent *zone = sim_ent_alloc_sync_src(chucker); sim_ent_enable_prop(zone, SEPROP_CHUCKER_ZONE); @@ -100,13 +100,13 @@ INTERNAL struct sim_ent *test_spawn_chucker(struct sim_ent *parent) return chucker; } -INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent) +INTERNAL Ent *test_spawn_employee(Ent *parent) { /* Player */ - struct sim_ent *employee = sim_ent_nil(); + Ent *employee = sim_ent_nil(); { - struct sim_ent *e = sim_ent_alloc_sync_src(parent); + Ent *e = sim_ent_alloc_sync_src(parent); V2 pos = V2FromXY(1, -1); @@ -174,7 +174,7 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent) (UNUSED)test_spawn_launcher; (UNUSED)test_spawn_chucker; - struct sim_ent *e = test_spawn_chucker(employee); + Ent *e = test_spawn_chucker(employee); employee->equipped = e->id; sim_ent_enable_prop(e, SEPROP_LIGHT_TEST); @@ -184,9 +184,9 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent) return employee; } -INTERNAL struct sim_ent *test_spawn_camera(struct sim_ent *parent, struct sim_ent *follow) +INTERNAL Ent *test_spawn_camera(Ent *parent, Ent *follow) { - struct sim_ent *camera_ent = sim_ent_nil(); + Ent *camera_ent = sim_ent_nil(); if (follow->valid) { camera_ent = sim_ent_alloc_sync_src(parent); sim_ent_set_xform(camera_ent, XFORM_IDENT); @@ -203,9 +203,9 @@ INTERNAL struct sim_ent *test_spawn_camera(struct sim_ent *parent, struct sim_en return camera_ent; } -INTERNAL struct sim_ent *test_spawn_explosion(struct sim_ent *parent, V2 pos, f32 strength, f32 radius) +INTERNAL Ent *test_spawn_explosion(Ent *parent, V2 pos, f32 strength, f32 radius) { - struct sim_ent *ent = sim_ent_alloc_sync_src(parent); + Ent *ent = sim_ent_alloc_sync_src(parent); sim_ent_set_xform(ent, XFORM_POS(pos)); sim_ent_enable_prop(ent, SEPROP_EXPLOSION); @@ -219,7 +219,7 @@ INTERNAL struct sim_ent *test_spawn_explosion(struct sim_ent *parent, V2 pos, f3 return ent; } -INTERNAL void test_teleport(struct sim_ent *ent, V2 pos) +INTERNAL void test_teleport(Ent *ent, V2 pos) { //++ent->continuity_gen; Xform xf = sim_ent_get_xform(ent); @@ -227,28 +227,28 @@ INTERNAL void test_teleport(struct sim_ent *ent, V2 pos) sim_ent_set_xform(ent, xf); } -INTERNAL void test_spawn_entities1(struct sim_ent *parent, V2 pos) +INTERNAL void test_spawn_entities1(Ent *parent, V2 pos) { (UNUSED)pos; /* Enemy */ { - struct sim_ent *e = test_spawn_employee(parent); + Ent *e = test_spawn_employee(parent); Xform xf = sim_ent_get_xform(e); xf.og = pos; sim_ent_set_xform(e, xf); } } -INTERNAL void test_spawn_entities2(struct sim_ent *parent, V2 pos) +INTERNAL void test_spawn_entities2(Ent *parent, V2 pos) { (UNUSED)pos; /* Small Box */ #if 1 { - //struct sim_ent *e = sim_ent_alloc_local(parent); - struct sim_ent *e = sim_ent_alloc_sync_src(parent); + //Ent *e = sim_ent_alloc_local(parent); + Ent *e = sim_ent_alloc_sync_src(parent); f32 rot = 0; V2 size = V2FromXY(0.125, 0.125); @@ -290,7 +290,7 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, V2 pos) /* Tiny box */ #if 0 { - struct sim_ent *e = sim_ent_alloc_sync_src(parent); + Ent *e = sim_ent_alloc_sync_src(parent); f32 r = PI / 4; V2 size = V2FromXY(0.5, 0.25); @@ -311,14 +311,14 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, V2 pos) #endif } -INTERNAL void test_spawn_entities3(struct sim_ent *parent, V2 pos) +INTERNAL void test_spawn_entities3(Ent *parent, V2 pos) { (UNUSED)pos; /* Heavy box */ { - //struct sim_ent *e = sim_ent_alloc_local(parent); - struct sim_ent *e = sim_ent_alloc_sync_src(parent); + //Ent *e = sim_ent_alloc_local(parent); + Ent *e = sim_ent_alloc_sync_src(parent); f32 r = 0; V2 size = V2FromXY(1, 1); @@ -336,12 +336,12 @@ INTERNAL void test_spawn_entities3(struct sim_ent *parent, V2 pos) } } -INTERNAL void test_spawn_entities4(struct sim_ent *parent, V2 pos) +INTERNAL void test_spawn_entities4(Ent *parent, V2 pos) { (UNUSED)pos; /* Light box */ - struct sim_ent *e = sim_ent_alloc_sync_src(parent); + Ent *e = sim_ent_alloc_sync_src(parent); f32 r = 0; V2 size = V2FromXY(2, 1); @@ -361,7 +361,7 @@ INTERNAL void test_spawn_entities4(struct sim_ent *parent, V2 pos) INTERNAL void test_spawn_tile(Snapshot *world, V2 world_pos) { #if 0 - struct sim_ent *e = sim_ent_alloc_sync_src(parent); + Ent *e = sim_ent_alloc_sync_src(parent); i32 sign_x = (world_pos.x >= 0) - (world_pos.x < 0); i32 sign_y = (world_pos.y >= 0) - (world_pos.y < 0); @@ -408,8 +408,8 @@ INTERNAL void test_spawn_tile(Snapshot *world, V2 world_pos) INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort_x, arg_a, arg_b, udata) { (UNUSED)udata; - struct sim_ent *a = *(struct sim_ent **)arg_a; - struct sim_ent *b = *(struct sim_ent **)arg_b; + Ent *a = *(Ent **)arg_a; + Ent *b = *(Ent **)arg_b; i32 a_x = a->tile_chunk_index.x; i32 b_x = b->tile_chunk_index.x; @@ -421,8 +421,8 @@ INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort_x, arg_a, arg_b, udata) INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort_y, arg_a, arg_b, udata) { (UNUSED)udata; - struct sim_ent *a = *(struct sim_ent **)arg_a; - struct sim_ent *b = *(struct sim_ent **)arg_b; + Ent *a = *(Ent **)arg_a; + Ent *b = *(Ent **)arg_b; i32 a_y = a->tile_chunk_index.y; i32 b_y = b->tile_chunk_index.y; @@ -435,29 +435,29 @@ INTERNAL void test_generate_walls(Snapshot *world) { __prof; TempArena scratch = scratch_begin_no_conflict(); - struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); + Ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); /* Release existing walls and gather tile chunks. * NOTE: We sort tile chunks before iterating so that chunk-edge tiles only * need to check for adjacent walls to merge with in one direction */ - struct sim_ent **x_sorted_tile_chunks = 0; - struct sim_ent **y_sorted_tile_chunks = 0; + Ent **x_sorted_tile_chunks = 0; + Ent **y_sorted_tile_chunks = 0; u64 sorted_tile_chunks_count = 0; { - x_sorted_tile_chunks = arena_push_dry(scratch.arena, struct sim_ent *); + x_sorted_tile_chunks = arena_push_dry(scratch.arena, Ent *); for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!ent->valid) continue; if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) { /* Append chunk to array */ - *arena_push_no_zero(scratch.arena, struct sim_ent *) = ent; + *arena_push_no_zero(scratch.arena, Ent *) = ent; ++sorted_tile_chunks_count; } else if (sim_ent_has_prop(ent, SEPROP_WALL)) { /* Release existing wall */ sim_ent_enable_prop(ent, SEPROP_RELEASE); } } - y_sorted_tile_chunks = arena_push_array_no_zero(scratch.arena, struct sim_ent *, sorted_tile_chunks_count); + y_sorted_tile_chunks = arena_push_array_no_zero(scratch.arena, Ent *, sorted_tile_chunks_count); MEMCPY(y_sorted_tile_chunks, x_sorted_tile_chunks, sizeof(*x_sorted_tile_chunks) * sorted_tile_chunks_count); /* NOTE: We sort x & y separately because it's possible that a wall @@ -482,10 +482,10 @@ INTERNAL void test_generate_walls(Snapshot *world) /* Generate horizontal wall nodes */ for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) { - struct sim_ent *chunk = x_sorted_tile_chunks[sorted_index]; + Ent *chunk = x_sorted_tile_chunks[sorted_index]; V2i32 chunk_index = chunk->tile_chunk_index; - struct sim_ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x, chunk_index.y - 1)); - struct sim_ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x, chunk_index.y + 1)); + Ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x, chunk_index.y - 1)); + Ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x, chunk_index.y + 1)); /* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */ i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + !bottom_chunk->valid; i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + 1; @@ -571,10 +571,10 @@ INTERNAL void test_generate_walls(Snapshot *world) /* Generate vertical wall nodes */ for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) { - struct sim_ent *chunk = y_sorted_tile_chunks[sorted_index]; + Ent *chunk = y_sorted_tile_chunks[sorted_index]; V2i32 chunk_index = chunk->tile_chunk_index; - struct sim_ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x - 1, chunk_index.y)); - struct sim_ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x + 1, chunk_index.y)); + Ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x - 1, chunk_index.y)); + Ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2i32FromXY(chunk_index.x + 1, chunk_index.y)); /* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */ i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + 1; i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + !right_chunk->valid; @@ -661,7 +661,7 @@ INTERNAL void test_generate_walls(Snapshot *world) /* Create wall entities */ for (struct wall_node *node = first_wall; node; node = node->next) { - struct sim_ent *wall_ent = sim_ent_alloc_sync_src(root); + Ent *wall_ent = sim_ent_alloc_sync_src(root); sim_ent_enable_prop(wall_ent, SEPROP_WALL); V2 start = sim_pos_from_world_tile_index(node->start); @@ -699,7 +699,7 @@ INTERNAL void test_clear_level(SimStepCtx *ctx) { Snapshot *world = ctx->world; for (u64 j = 0; j < world->num_ents_reserved; ++j) { - struct sim_ent *ent = &world->ents[j]; + Ent *ent = &world->ents[j]; if (ent->valid) { sim_ent_enable_prop(ent, SEPROP_RELEASE); } @@ -713,9 +713,9 @@ INTERNAL void test_clear_level(SimStepCtx *ctx) INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) { Snapshot *world = step_ctx->world; - struct sim_ent *e0 = sim_ent_from_id(world, data->e0); - struct sim_ent *e1 = sim_ent_from_id(world, data->e1); - struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); + Ent *e0 = sim_ent_from_id(world, data->e0); + Ent *e1 = sim_ent_from_id(world, data->e1); + Ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); b32 skip_solve = 0; if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) { @@ -724,16 +724,16 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) V2 normal = data->normal; /* Impact normal */ V2 vrel = data->vrel; /* Impact velocity */ - struct sim_ent *bullet = e0; - struct sim_ent *target = e1; - struct sim_ent *src = sim_ent_from_id(world, bullet->bullet_src); + Ent *bullet = e0; + Ent *target = e1; + Ent *src = sim_ent_from_id(world, bullet->bullet_src); /* Process collision if bullet already spent or * target share same top level parent */ if (!bullet->bullet_has_hit && !sim_ent_id_eq(src->top, target->top) && sim_ent_has_prop(target, SEPROP_SOLID)) { V2 point = data->point; /* Update tracer */ - struct sim_ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer); + Ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer); if (sim_ent_should_simulate(tracer)) { Xform xf = sim_ent_get_xform(tracer); xf.og = point; @@ -749,7 +749,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) /* TODO: Remove this */ { Xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, TAU)); - struct sim_ent *decal = sim_ent_alloc_sync_src(root); + Ent *decal = sim_ent_alloc_sync_src(root); decal->sprite = sprite_tag_from_path(LIT("sprite/blood.ase")); decal->sprite_tint = RGBA32_F(1, 1, 1, 0.25f); decal->layer = SIM_LAYER_FLOOR_DECALS; @@ -783,8 +783,8 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) /* Explosion blast collision */ if (sim_ent_has_prop(e0, SEPROP_EXPLOSION)) { - struct sim_ent *exp = e0; - struct sim_ent *victim = e1; + Ent *exp = e0; + Ent *victim = e1; Xform xf = sim_ent_get_xform(exp); @@ -862,7 +862,7 @@ void sim_step(SimStepCtx *ctx) S_Scope *sprite_frame_scope = sprite_scope_begin(); - struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); + Ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); root->owner = world->client->player_id; /* ========================== * @@ -874,7 +874,7 @@ void sim_step(SimStepCtx *ctx) for (u64 client_index = 0; client_index < client_store->num_clients_reserved; ++client_index) { Client *client = &client_store->clients[client_index]; if (client->valid && client != master_client && client != world_client && client != publish_client) { - struct sim_ent *player = sim_ent_from_id(world, client->player_id); + Ent *player = sim_ent_from_id(world, client->player_id); /* Create player if necessary */ if (is_master && !player->valid) { @@ -892,7 +892,7 @@ void sim_step(SimStepCtx *ctx) player->owner = player->id; sim_ent_enable_prop(player, SEPROP_PLAYER_IS_MASTER); } - logf_info("Created player with id %F for sim client %F. is_master: %F", FMT_UID(player->id.uid), FMT_HANDLE(client->handle), FMT_UINT(sim_ent_has_prop(player, SEPROP_PLAYER_IS_MASTER))); + P_LogInfoF("Created player with id %F for sim client %F. is_master: %F", FMT_UID(player->id.uid), FMT_HANDLE(client->handle), FMT_UINT(sim_ent_has_prop(player, SEPROP_PLAYER_IS_MASTER))); } /* Update rtt */ @@ -914,7 +914,7 @@ void sim_step(SimStepCtx *ctx) /* Mark all incoming ents as sync dsts */ for (u64 i = 0; i < world->num_ents_reserved; ++i) { - struct sim_ent *ent = &world->ents[i]; + Ent *ent = &world->ents[i]; if (ent->valid && sim_ent_has_prop(ent, SEPROP_SYNC_SRC) && !sim_ent_id_eq(ent->owner, world_client->player_id)) { sim_ent_disable_prop(ent, SEPROP_SYNC_SRC); sim_ent_enable_prop(ent, SEPROP_SYNC_DST); @@ -923,7 +923,7 @@ void sim_step(SimStepCtx *ctx) /* Mark incoming cmds with correct client */ for (u64 i = 0; i < world->num_ents_reserved; ++i) { - struct sim_ent *ent = &world->ents[i]; + Ent *ent = &world->ents[i]; if (ent->valid && sim_ent_has_prop(ent, SEPROP_CMD) && sim_ent_has_prop(ent, SEPROP_SYNC_DST)) { ent->cmd_player = ent->owner; } @@ -932,7 +932,7 @@ void sim_step(SimStepCtx *ctx) /* Mark any locally created CMDs as sync sources */ if (!is_master) { for (u64 i = 0; i < world->num_ents_reserved; ++i) { - struct sim_ent *ent = &world->ents[i]; + Ent *ent = &world->ents[i]; if (sim_ent_is_valid_and_active(ent) && sim_ent_has_prop(ent, SEPROP_CMD)) { if (!sim_ent_id_is_nil(ent->cmd_player) && sim_ent_id_eq(ent->cmd_player, world->local_player)) { sim_ent_enable_prop(ent, SEPROP_SYNC_SRC); @@ -954,7 +954,7 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!ent->valid) continue; if (sim_ent_has_prop(ent, SEPROP_SYNC_DST) && !sim_ent_is_owner(ent) && !sim_ent_should_predict(ent)) continue; @@ -971,11 +971,11 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *cmd_ent = &world->ents[ent_index]; + Ent *cmd_ent = &world->ents[ent_index]; if (!is_master && !sim_ent_should_simulate(cmd_ent)) continue; if (sim_ent_has_prop(cmd_ent, SEPROP_CMD)) { - struct sim_ent *player = sim_ent_from_id(world, cmd_ent->cmd_player); + Ent *player = sim_ent_from_id(world, cmd_ent->cmd_player); if (sim_ent_should_simulate(player)) { b32 persist_cmd = 0; if (!is_master && !sim_ent_id_eq(player->id, world->local_player)) { @@ -1019,7 +1019,7 @@ void sim_step(SimStepCtx *ctx) } } if (flags & SIM_CONTROL_FLAG_DELETE) { - struct sim_ent *ent = sim_ent_from_id(world, player->player_hovered_ent); + Ent *ent = sim_ent_from_id(world, player->player_hovered_ent); if (ent->valid) { sim_ent_enable_prop(ent, SEPROP_RELEASE); } @@ -1028,7 +1028,7 @@ void sim_step(SimStepCtx *ctx) test_clear_level(ctx); } if (flags & SIM_CONTROL_FLAG_SPAWN1_TEST) { - logf_debug("Spawn test 1"); + P_LogDebugF("Spawn test 1"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) { @@ -1038,7 +1038,7 @@ void sim_step(SimStepCtx *ctx) } } if (flags & SIM_CONTROL_FLAG_SPAWN2_TEST) { - logf_debug("Spawn test 2"); + P_LogDebugF("Spawn test 2"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) { @@ -1048,7 +1048,7 @@ void sim_step(SimStepCtx *ctx) } } if (flags & SIM_CONTROL_FLAG_SPAWN3_TEST) { - logf_debug("Spawn test 3"); + P_LogDebugF("Spawn test 3"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) { @@ -1058,7 +1058,7 @@ void sim_step(SimStepCtx *ctx) } } if (flags & SIM_CONTROL_FLAG_SPAWN4_TEST) { - logf_debug("Spawn test 4"); + P_LogDebugF("Spawn test 4"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) { @@ -1071,7 +1071,7 @@ void sim_step(SimStepCtx *ctx) test_generate_walls(world); } if (flags & SIM_CONTROL_FLAG_EXPLODE_TEST) { - logf_debug("Explosion test"); + P_LogDebugF("Explosion test"); test_spawn_explosion(root, player->player_cursor_pos, 100, 2); } } @@ -1090,7 +1090,7 @@ void sim_step(SimStepCtx *ctx) struct sim_data_key msg_key = cmd_ent->cmd_chat_msg; String msg = sim_data_from_key(sim_data_store, msg_key); if (msg.len > 0) { - struct sim_ent *chat_ent = sim_ent_alloc_sync_src(root); + Ent *chat_ent = sim_ent_alloc_sync_src(root); sim_ent_enable_prop(chat_ent, SEPROP_CHAT); chat_ent->chat_player = player->id; chat_ent->chat_msg = msg_key; @@ -1118,11 +1118,11 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) { - struct sim_ent *player = sim_ent_from_id(world, ent->controlling_player); + Ent *player = sim_ent_from_id(world, ent->controlling_player); if (player->valid) { ent->control = player->player_control; } @@ -1135,11 +1135,11 @@ void sim_step(SimStepCtx *ctx) if (is_master) { for (u64 i = 0; i < world->num_ents_reserved; ++i) { - struct sim_ent *ent = &world->ents[i]; + Ent *ent = &world->ents[i]; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SEPROP_PLAYER)) { /* FIXME: Ents never released when client disconnects */ - struct sim_ent *control_ent = sim_ent_from_id(world, ent->player_control_ent); + Ent *control_ent = sim_ent_from_id(world, ent->player_control_ent); if (!control_ent->valid) { control_ent = test_spawn_employee(root); control_ent->predictor = ent->id; @@ -1147,13 +1147,13 @@ void sim_step(SimStepCtx *ctx) ent->player_control_ent = control_ent->id; control_ent->controlling_player = ent->id; } - struct sim_ent *camera_ent = sim_ent_from_id(world, ent->player_camera_ent); + Ent *camera_ent = sim_ent_from_id(world, ent->player_camera_ent); if (!camera_ent->valid) { camera_ent = test_spawn_camera(root, control_ent); camera_ent->predictor = ent->id; ent->player_camera_ent = camera_ent->id; } - struct sim_ent *camera_follow = sim_ent_from_id(world, camera_ent->camera_follow); + Ent *camera_follow = sim_ent_from_id(world, camera_ent->camera_follow); if (!camera_follow->valid) { camera_ent->camera_follow = control_ent->id; } @@ -1166,7 +1166,7 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (sprite_tag_is_nil(ent->sprite)) continue; @@ -1268,11 +1268,11 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SEPROP_ATTACHED)) continue; - struct sim_ent *parent = sim_ent_from_id(world, ent->parent); + Ent *parent = sim_ent_from_id(world, ent->parent); S_Tag parent_sprite = parent->sprite; S_Sheet *parent_sheet = sprite_sheet_from_tag_await(sprite_frame_scope, parent_sprite); @@ -1293,20 +1293,20 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) { ControlData *control = &ent->control; u32 flags = control->flags; if (flags & SIM_CONTROL_FLAG_FIRE) { - struct sim_ent *equipped = sim_ent_from_id(world, ent->equipped); + Ent *equipped = sim_ent_from_id(world, ent->equipped); if (equipped->valid) { ++equipped->num_primary_triggers; } } if (flags & SIM_CONTROL_FLAG_FIRE_ALT) { - struct sim_ent *equipped = sim_ent_from_id(world, ent->equipped); + Ent *equipped = sim_ent_from_id(world, ent->equipped); if (equipped->valid) { ++equipped->num_secondary_triggers; } @@ -1322,7 +1322,7 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; b32 primary_triggered = ent->num_primary_triggers > 0; @@ -1359,7 +1359,7 @@ void sim_step(SimStepCtx *ctx) V2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir); /* Spawn bullet */ - struct sim_ent *bullet; + Ent *bullet; { bullet = sim_ent_alloc_sync_src(root); @@ -1384,7 +1384,7 @@ void sim_step(SimStepCtx *ctx) /* Spawn tracer */ { - struct sim_ent *tracer = sim_ent_alloc_sync_src(root); + Ent *tracer = sim_ent_alloc_sync_src(root); tracer->tracer_fade_duration = 0.025f; tracer->layer = SIM_LAYER_TRACERS; sim_ent_enable_prop(tracer, SEPROP_TRACER); @@ -1406,7 +1406,7 @@ void sim_step(SimStepCtx *ctx) V2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir); /* Spawn bullet */ - struct sim_ent *bullet; + Ent *bullet; { bullet = sim_ent_alloc_sync_src(root); @@ -1430,7 +1430,7 @@ void sim_step(SimStepCtx *ctx) /* Spawn tracer */ { - struct sim_ent *tracer = sim_ent_alloc_sync_src(root); + Ent *tracer = sim_ent_alloc_sync_src(root); tracer->tracer_fade_duration = 0.025f; tracer->layer = SIM_LAYER_TRACERS; sim_ent_enable_prop(tracer, SEPROP_TRACER); @@ -1445,12 +1445,12 @@ void sim_step(SimStepCtx *ctx) if (primary_triggered) { } if (secondary_triggered) { - struct sim_ent *zone = sim_ent_from_id(world, ent->chucker_zone); - struct sim_ent *target = sim_ent_from_id(world, zone->chucker_zone_ent); - struct sim_ent *old_joint_ent = sim_ent_from_id(world, ent->chucker_joint); + Ent *zone = sim_ent_from_id(world, ent->chucker_zone); + Ent *target = sim_ent_from_id(world, zone->chucker_zone_ent); + Ent *old_joint_ent = sim_ent_from_id(world, ent->chucker_joint); if (sim_ent_is_valid_and_active(target) && zone->chucker_zone_ent_tick == world->tick - 1) { if (!sim_ent_id_eq(old_joint_ent->weld_joint_data.e1, target->id)) { - struct sim_ent *joint_ent = sim_ent_alloc_sync_src(root); + Ent *joint_ent = sim_ent_alloc_sync_src(root); sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE); Xform xf0 = sim_ent_get_xform(ent); @@ -1483,11 +1483,11 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) { - struct sim_ent *joint_ent = sim_ent_from_id(world, ent->move_joint); + Ent *joint_ent = sim_ent_from_id(world, ent->move_joint); if (is_master && !sim_ent_is_valid_and_active(joint_ent)) { joint_ent = sim_ent_alloc_sync_src(root); joint_ent->predictor = ent->predictor; @@ -1520,7 +1520,7 @@ void sim_step(SimStepCtx *ctx) #if SIM_PLAYER_AIM for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) { @@ -1528,7 +1528,7 @@ void sim_step(SimStepCtx *ctx) Xform sprite_xf = xform_mul(xf, ent->sprite_local_xform); /* Retrieve / create aim joint */ - struct sim_ent *joint_ent = sim_ent_from_id(world, ent->aim_joint); + Ent *joint_ent = sim_ent_from_id(world, ent->aim_joint); if (is_master && !sim_ent_is_valid_and_active(joint_ent)) { joint_ent = sim_ent_alloc_sync_src(root); joint_ent->predictor = ent->predictor; @@ -1618,11 +1618,11 @@ void sim_step(SimStepCtx *ctx) #if 1 for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SEPROP_DYNAMIC)) continue; - struct sim_ent *joint_ent = sim_ent_from_id(world, ent->ground_friction_joint); + Ent *joint_ent = sim_ent_from_id(world, ent->ground_friction_joint); MotorJointDesc def = phys_motor_joint_def_init(); def.e0 = root->id; @@ -1649,7 +1649,7 @@ void sim_step(SimStepCtx *ctx) if (is_master) { for (u64 i = 0; i < world->num_ents_reserved; ++i) { - struct sim_ent *player = &world->ents[i]; + Ent *player = &world->ents[i]; if (!sim_ent_should_simulate(player)) continue; if (!sim_ent_has_prop(player, SEPROP_PLAYER)) continue; @@ -1657,8 +1657,8 @@ void sim_step(SimStepCtx *ctx) b32 start_dragging = player->player_dbg_drag_start; b32 stop_dragging = player->player_dbg_drag_stop; - struct sim_ent *joint_ent = sim_ent_from_id(world, player->player_dbg_drag_joint_ent); - struct sim_ent *target_ent = sim_ent_from_id(world, joint_ent->mouse_joint_data.target); + Ent *joint_ent = sim_ent_from_id(world, player->player_dbg_drag_joint_ent); + Ent *target_ent = sim_ent_from_id(world, joint_ent->mouse_joint_data.target); if (stop_dragging) { target_ent = sim_ent_nil(); @@ -1714,7 +1714,7 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SEPROP_EXPLOSION)) continue; @@ -1727,7 +1727,7 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SEPROP_TRACER)) continue; @@ -1751,12 +1751,12 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SEPROP_BULLET)) continue; if (ent->activation_tick == world->tick) { - struct sim_ent *src = sim_ent_from_id(world, ent->bullet_src); + Ent *src = sim_ent_from_id(world, ent->bullet_src); Xform src_xf = sim_ent_get_xform(src); /* Activate collision */ @@ -1771,7 +1771,7 @@ void sim_step(SimStepCtx *ctx) /* Add shooter velocity to bullet */ { /* TODO: Add angular velocity as well? */ - struct sim_ent *top = sim_ent_from_id(ss_blended, src->top); + Ent *top = sim_ent_from_id(ss_blended, src->top); impulse = v2_add(impulse, v2_mul(top->linear_velocity, dt)); } #endif @@ -1783,7 +1783,7 @@ void sim_step(SimStepCtx *ctx) sim_ent_set_linear_velocity(ent, vel); /* Initialize tracer */ - struct sim_ent *tracer = sim_ent_from_id(world, ent->bullet_tracer); + Ent *tracer = sim_ent_from_id(world, ent->bullet_tracer); if (sim_ent_should_simulate(tracer)) { sim_ent_set_xform(tracer, xf); sim_ent_enable_prop(tracer, SEPROP_KINEMATIC); @@ -1796,7 +1796,7 @@ void sim_step(SimStepCtx *ctx) /* Spawn quake */ { - struct sim_ent *quake = sim_ent_alloc_sync_src(root); + Ent *quake = sim_ent_alloc_sync_src(root); sim_ent_set_xform(quake, XFORM_POS(pos)); quake->quake_intensity = 0.2f; quake->quake_fade = quake->quake_intensity / 0.1f; @@ -1810,7 +1810,7 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SEPROP_CAMERA)) continue; @@ -1818,7 +1818,7 @@ void sim_step(SimStepCtx *ctx) /* Camera follow */ { - struct sim_ent *follow = sim_ent_from_id(world, ent->camera_follow); + Ent *follow = sim_ent_from_id(world, ent->camera_follow); f32 aspect_ratio = 1.0; { @@ -1851,7 +1851,7 @@ void sim_step(SimStepCtx *ctx) /* TODO: Update based on distance to quake */ ent->shake = 0; for (u64 quake_ent_index = 0; quake_ent_index < world->num_ents_reserved; ++quake_ent_index) { - struct sim_ent *quake = &world->ents[quake_ent_index]; + Ent *quake = &world->ents[quake_ent_index]; if (!sim_ent_should_simulate(quake)) continue; if (!sim_ent_has_prop(quake, SEPROP_QUAKE)) continue; ent->shake += quake->quake_intensity; @@ -1866,7 +1866,7 @@ void sim_step(SimStepCtx *ctx) * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; + Ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SEPROP_QUAKE)) continue; @@ -1883,20 +1883,20 @@ void sim_step(SimStepCtx *ctx) { TempArena temp = arena_temp_begin(scratch.arena); - struct sim_ent **stack = arena_push_no_zero(temp.arena, struct sim_ent *); + Ent **stack = arena_push_no_zero(temp.arena, Ent *); u64 stack_count = 1; *stack = root; while (stack_count > 0) { - struct sim_ent *parent; - arena_pop(temp.arena, struct sim_ent *, &parent); + Ent *parent; + arena_pop(temp.arena, Ent *, &parent); --stack_count; i32 parent_layer = parent->final_layer; - for (struct sim_ent *child = sim_ent_from_id(world, parent->first); child->valid; child = sim_ent_from_id(world, child->next)) { + for (Ent *child = sim_ent_from_id(world, parent->first); child->valid; child = sim_ent_from_id(world, child->next)) { if (sim_ent_should_simulate(child)) { child->final_layer = parent_layer + child->layer; - *arena_push_no_zero(temp.arena, struct sim_ent *) = child; + *arena_push_no_zero(temp.arena, Ent *) = child; ++stack_count; } } @@ -1924,7 +1924,7 @@ void sim_step(SimStepCtx *ctx) /* Mark all synced ents as both sync dsts & sync srcs */ for (u64 ent_index = 2; ent_index < pub_world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &pub_world->ents[ent_index]; + Ent *ent = &pub_world->ents[ent_index]; if (ent->valid) { sim_ent_enable_prop(ent, SEPROP_SYNC_DST); sim_ent_enable_prop(ent, SEPROP_SYNC_SRC); diff --git a/src/sound/sound_core.c b/src/sound/sound_core.c index 9008b3b1..75dac599 100644 --- a/src/sound/sound_core.c +++ b/src/sound/sound_core.c @@ -43,24 +43,24 @@ INTERNAL struct sound_task_params *sound_task_params_alloc(void) { struct sound_task_params *p = 0; { - P_Lock lock = snc_lock_e(&G.params.mutex); + P_Lock lock = P_LockE(&G.params.mutex); if (G.params.head_free) { p = G.params.head_free; G.params.head_free = p->next_free; } else { p = arena_push(G.params.arena, struct sound_task_params); } - snc_unlock(&lock); + P_Unlock(&lock); } return p; } INTERNAL void sound_task_params_release(struct sound_task_params *p) { - P_Lock lock = snc_lock_e(&G.params.mutex); + P_Lock lock = P_LockE(&G.params.mutex); p->next_free = G.params.head_free; G.params.head_free = p; - snc_unlock(&lock); + P_Unlock(&lock); } /* ========================== * @@ -76,7 +76,7 @@ INTERNAL P_JobDef(sound_load_asset_job, job) AC_Asset *asset = params->asset; u32 flags = params->flags; - logf_info("Loading sound \"%F\"", FMT_STR(path)); + P_LogInfoF("Loading sound \"%F\"", FMT_STR(path)); i64 start_ns = P_TimeNs(); String error_msg = LIT("Unknown error"); @@ -120,10 +120,10 @@ INTERNAL P_JobDef(sound_load_asset_job, job) sound->pcm.samples = samples; MEMCPY(sound->pcm.samples, decoded.pcm.samples, decoded.pcm.count * sizeof(*decoded.pcm.samples)); - logf_success("Loaded sound \"%F\" in %F seconds", FMT_STR(path), FMT_FLOAT(SECONDS_FROM_NS(P_TimeNs() - start_ns))); + P_LogSuccessF("Loaded sound \"%F\" in %F seconds", FMT_STR(path), FMT_FLOAT(SECONDS_FROM_NS(P_TimeNs() - start_ns))); asset_cache_mark_ready(asset, sound); } else { - logf_error("Error loading sound \"%F\": %F", FMT_STR(path), FMT_STR(error_msg)); + P_LogErrorF("Error loading sound \"%F\": %F", FMT_STR(path), FMT_STR(error_msg)); /* Store */ SND_Sound *sound = 0; diff --git a/src/sprite/sprite_core.c b/src/sprite/sprite_core.c index f1ba712d..6dd48121 100644 --- a/src/sprite/sprite_core.c +++ b/src/sprite/sprite_core.c @@ -245,13 +245,13 @@ INTERNAL P_ExitFuncDef(sprite_shutdown) __prof; /* Signal evictor shutdown */ { - P_Lock lock = snc_lock_e(&G.evictor_scheduler_mutex); + P_Lock lock = P_LockE(&G.evictor_scheduler_mutex); G.evictor_scheduler_shutdown = 1; - snc_cv_signal(&G.evictor_scheduler_shutdown_cv, I32_MAX); - snc_unlock(&lock); + P_SignalCv(&G.evictor_scheduler_shutdown_cv, I32_MAX); + P_Unlock(&lock); } /* Wait for evictor shutdown */ - snc_counter_wait(&G.shutdown_counter); + P_WaitOnCounter(&G.shutdown_counter); } /* ========================== * @@ -290,14 +290,14 @@ INTERNAL void push_load_job(struct cache_ref ref, S_Tag tag) { struct load_cmd *cmd = 0; { - P_Lock lock = snc_lock_e(&G.load_cmds_mutex); + P_Lock lock = P_LockE(&G.load_cmds_mutex); if (G.first_free_load_cmd) { cmd = G.first_free_load_cmd; G.first_free_load_cmd = cmd->next_free; } else { cmd = arena_push_no_zero(G.load_cmds_arena, struct load_cmd); } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(cmd); @@ -324,7 +324,7 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, S_Tag tag) atomic32_fetch_set(&e->state, CACHE_ENTRY_STATE_WORKING); String path = tag.path; - logf_info("Loading sprite texture [%F] \"%F\"", FMT_HEX(e->hash.v), FMT_STR(path)); + P_LogInfoF("Loading sprite texture [%F] \"%F\"", FMT_HEX(e->hash.v), FMT_STR(path)); b32 success = 0; i64 start_ns = P_TimeNs(); @@ -343,7 +343,7 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, S_Tag tag) if (resource_exists(&texture_rs)) { decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs)); } else { - logf_error("Sprite texture for \"%F\" not found", FMT_STR(path)); + P_LogErrorF("Sprite texture for \"%F\" not found", FMT_STR(path)); } resource_close(&texture_rs); } @@ -366,7 +366,7 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, S_Tag tag) atomic64_fetch_add(&G.cache.memory_usage.v, e->memory_usage); if (success) { - logf_success("Loaded sprite texture [%F] \"%F\" in %F seconds (cache size: %F bytes).", + P_LogSuccessF("Loaded sprite texture [%F] \"%F\" in %F seconds (cache size: %F bytes).", FMT_HEX(e->hash.v), FMT_STR(path), FMT_FLOAT(SECONDS_FROM_NS(P_TimeNs() - start_ns)), @@ -377,7 +377,7 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, S_Tag tag) #if RESOURCE_RELOADING struct cache_bin *bin = &G.cache.bins[e->hash.v % CACHE_BINS_COUNT]; - P_Lock bin_lock = snc_lock_e(&bin->mutex); + P_Lock bin_lock = P_LockE(&bin->mutex); { for (struct cache_entry *old_entry = bin->first; old_entry; old_entry = old_entry->next_in_bin) { if (old_entry != e && old_entry->hash.v == e->hash.v) { @@ -386,7 +386,7 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, S_Tag tag) } e->load_time_ns = P_TimeNs(); } - snc_unlock(&bin_lock); + P_Unlock(&bin_lock); #endif scratch_end(scratch); @@ -647,7 +647,7 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, S_Tag tag) atomic32_fetch_set(&e->state, CACHE_ENTRY_STATE_WORKING); String path = tag.path; - logf_info("Loading sprite sheet [%F] \"%F\"", FMT_HEX(e->hash.v), FMT_STR(path)); + P_LogInfoF("Loading sprite sheet [%F] \"%F\"", FMT_HEX(e->hash.v), FMT_STR(path)); b32 success = 0; i64 start_ns = P_TimeNs(); @@ -663,7 +663,7 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, S_Tag tag) if (resource_exists(&sheet_rs)) { decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs)); } else { - logf_error("Sprite sheet for \"%F\" not found", FMT_STR(path)); + P_LogErrorF("Sprite sheet for \"%F\" not found", FMT_STR(path)); } resource_close(&sheet_rs); } @@ -687,7 +687,7 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, S_Tag tag) atomic64_fetch_add(&G.cache.memory_usage.v, e->memory_usage); if (success) { - logf_success("Loaded sprite sheet [%F] \"%F\" in %F seconds (cache size: %F bytes).", + P_LogSuccessF("Loaded sprite sheet [%F] \"%F\" in %F seconds (cache size: %F bytes).", FMT_HEX(e->hash.v), FMT_STR(path), FMT_FLOAT(SECONDS_FROM_NS(P_TimeNs() - start_ns)), @@ -698,7 +698,7 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, S_Tag tag) #if RESOURCE_RELOADING struct cache_bin *bin = &G.cache.bins[e->hash.v % CACHE_BINS_COUNT]; - P_Lock bin_lock = snc_lock_e(&bin->mutex); + P_Lock bin_lock = P_LockE(&bin->mutex); { for (struct cache_entry *old_entry = bin->first; old_entry; old_entry = old_entry->next_in_bin) { if (old_entry != e && old_entry->hash.v == e->hash.v) { @@ -707,7 +707,7 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, S_Tag tag) } e->load_time_ns = P_TimeNs(); } - snc_unlock(&bin_lock); + P_Unlock(&bin_lock); #endif scratch_end(scratch); @@ -771,7 +771,7 @@ INTERNAL struct sprite_scope_cache_ref *scope_ensure_ref_unsafe(S_Scope *scope, INTERNAL struct sprite_scope_cache_ref *scope_ensure_ref_from_entry(S_Scope *scope, struct cache_entry *e, P_Lock *bin_lock) { /* Guaranteed safe if caller has lock on entry's bin, since entry may not have an existing reference and could otherwise be evicted while ensuring this reference */ - snc_assert_locked_e_or_s(bin_lock, &G.cache.bins[e->hash.v % CACHE_BINS_COUNT].mutex); + P_AssertLockedES(bin_lock, &G.cache.bins[e->hash.v % CACHE_BINS_COUNT].mutex); return scope_ensure_ref_unsafe(scope, e); } @@ -788,7 +788,7 @@ S_Scope *sprite_scope_begin(void) struct sprite_scope_cache_ref **bins = 0; struct sprite_scope_cache_ref *pool = 0; { - P_Lock lock = snc_lock_e(&G.scopes_mutex); + P_Lock lock = P_LockE(&G.scopes_mutex); { if (G.first_free_scope) { res = G.first_free_scope; @@ -801,7 +801,7 @@ S_Scope *sprite_scope_begin(void) pool = arena_push_array_no_zero(G.scopes_arena, struct sprite_scope_cache_ref, MAX_SCOPE_REFERENCES); } } - snc_unlock(&lock); + P_Unlock(&lock); } MEMZERO_STRUCT(res); MEMZERO(bins, sizeof(*bins) * CACHE_BINS_COUNT); @@ -820,12 +820,12 @@ void sprite_scope_end(S_Scope *scope) } /* Release scope */ - P_Lock lock = snc_lock_e(&G.scopes_mutex); + P_Lock lock = P_LockE(&G.scopes_mutex); { scope->next_free = G.first_free_scope; G.first_free_scope = scope; } - snc_unlock(&lock); + P_Unlock(&lock); } /* ========================== * @@ -837,7 +837,7 @@ INTERNAL struct sprite_scope_cache_ref *cache_lookup(S_Scope *scope, struct cach struct sprite_scope_cache_ref *scope_ref = 0; struct cache_bin *bin = &G.cache.bins[hash.v % CACHE_BINS_COUNT]; - snc_assert_locked_e_or_s(bin_lock, &bin->mutex); /* Lock required for iterating bin */ + P_AssertLockedES(bin_lock, &bin->mutex); /* Lock required for iterating bin */ #if RESOURCE_RELOADING /* If resource reloading is enabled, then we want to find the @@ -892,16 +892,16 @@ INTERNAL struct sprite_scope_cache_ref *cache_entry_from_tag(S_Scope *scope, S_T /* Search in cache */ if (!force_new) { - P_Lock bin_lock = snc_lock_s(&bin->mutex); + P_Lock bin_lock = P_LockS(&bin->mutex); { scope_ref = cache_lookup(scope, hash, &bin_lock); } - snc_unlock(&bin_lock); + P_Unlock(&bin_lock); } /* If not in cache, allocate new entry */ if (!scope_ref) { - P_Lock bin_lock = snc_lock_e(&bin->mutex); + P_Lock bin_lock = P_LockE(&bin->mutex); { /* Search cache one more time in case an entry was allocated between locks */ if (!force_new) { @@ -912,14 +912,14 @@ INTERNAL struct sprite_scope_cache_ref *cache_entry_from_tag(S_Scope *scope, S_T /* Cache entry still absent, allocate new entry */ struct cache_entry *entry = 0; { - P_Lock pool_lock = snc_lock_e(&G.cache.entry_pool_mutex); + P_Lock pool_lock = P_LockE(&G.cache.entry_pool_mutex); if (G.cache.entry_pool_first_free) { entry = G.cache.entry_pool_first_free; G.cache.entry_pool_first_free = entry->next_free; } else { entry = arena_push_no_zero(G.cache.arena, struct cache_entry); } - snc_unlock(&pool_lock); + P_Unlock(&pool_lock); } MEMZERO_STRUCT(entry); @@ -941,7 +941,7 @@ INTERNAL struct sprite_scope_cache_ref *cache_entry_from_tag(S_Scope *scope, S_T scope_ref = scope_ensure_ref_from_entry(scope, entry, &bin_lock); } } - snc_unlock(&bin_lock); + P_Unlock(&bin_lock); } } @@ -1126,13 +1126,13 @@ INTERNAL P_JobDef(sprite_load_job, job) } /* Free cmd */ - P_Lock lock = snc_lock_e(&G.load_cmds_mutex); + P_Lock lock = P_LockE(&G.load_cmds_mutex); { sprite_scope_end(cmd->scope); cmd->next_free = G.first_free_load_cmd; G.first_free_load_cmd = cmd; } - snc_unlock(&lock); + P_Unlock(&lock); } /* ========================== * @@ -1146,14 +1146,14 @@ INTERNAL void reload_if_exists(S_Scope *scope, S_Tag tag, enum cache_entry_kind struct cache_entry_hash hash = cache_entry_hash_from_tag_hash(tag.hash, kind); struct cache_bin *bin = &G.cache.bins[hash.v % CACHE_BINS_COUNT]; struct sprite_scope_cache_ref *existing_ref = 0; - P_Lock bin_lock = snc_lock_s(&bin->mutex); + P_Lock bin_lock = P_LockS(&bin->mutex); { existing_ref = cache_lookup(scope, hash, &bin_lock); } - snc_unlock(&bin_lock); + P_Unlock(&bin_lock); if (existing_ref) { - logf_info("Sprite resource file \"%F\" has changed for sprite [%F].", FMT_STR(tag.path), FMT_HEX(hash.v)); + P_LogInfoF("Sprite resource file \"%F\" has changed for sprite [%F].", FMT_STR(tag.path), FMT_HEX(hash.v)); struct sprite_scope_cache_ref *scope_ref = cache_entry_from_tag(scope, tag, kind, 1); push_load_job(scope_ref->ref, tag); } @@ -1229,7 +1229,7 @@ INTERNAL P_JobDef(sprite_evictor_job, _) __profn("Evictor scan"); for (u64 i = 0; i < CACHE_BINS_COUNT; ++i) { struct cache_bin *bin = &G.cache.bins[i]; - P_Lock bin_lock = snc_lock_s(&bin->mutex); + P_Lock bin_lock = P_LockS(&bin->mutex); { struct cache_entry *n = bin->first; while (n) { @@ -1258,7 +1258,7 @@ INTERNAL P_JobDef(sprite_evictor_job, _) n = n->next_in_bin; } } - snc_unlock(&bin_lock); + P_Unlock(&bin_lock); } } @@ -1282,7 +1282,7 @@ INTERNAL P_JobDef(sprite_evictor_job, _) struct cache_entry *entry = en->cache_entry; i32 last_ref_cycle = en->last_ref_cycle; b32 cache_over_budget_target = atomic64_fetch(&G.cache.memory_usage.v) > (i64)CACHE_MEMORY_BUDGET_TARGET; - P_Lock bin_lock = snc_lock_e(&bin->mutex); + P_Lock bin_lock = P_LockE(&bin->mutex); { u64 refcount_uncast = atomic64_fetch(&entry->refcount_struct.v); struct cache_refcount refcount = *(struct cache_refcount *)&refcount_uncast; @@ -1313,7 +1313,7 @@ INTERNAL P_JobDef(sprite_evictor_job, _) stop_evicting = 1; } } - snc_unlock(&bin_lock); + P_Unlock(&bin_lock); } } @@ -1333,13 +1333,13 @@ INTERNAL P_JobDef(sprite_evictor_job, _) /* Add evicted nodes to free list */ { __profn("Evictor free list append"); - P_Lock pool_lock = snc_lock_e(&G.cache.entry_pool_mutex); + P_Lock pool_lock = P_LockE(&G.cache.entry_pool_mutex); for (struct evict_node *en = first_evicted; en; en = en->next_evicted) { struct cache_entry *n = en->cache_entry; n->next_free = G.cache.entry_pool_first_free; G.cache.entry_pool_first_free = n; } - snc_unlock(&pool_lock); + P_Unlock(&pool_lock); } } } @@ -1349,14 +1349,14 @@ INTERNAL P_JobDef(sprite_evictor_job, _) /* Evictor sleep */ { - P_Lock lock = snc_lock_e(&G.evictor_scheduler_mutex); + P_Lock lock = P_LockE(&G.evictor_scheduler_mutex); { if (!G.evictor_scheduler_shutdown) { - snc_cv_wait_time(&G.evictor_scheduler_shutdown_cv, &lock, EVICTOR_CYCLE_INTERVAL_NS); + P_WaitOnCvTime(&G.evictor_scheduler_shutdown_cv, &lock, EVICTOR_CYCLE_INTERVAL_NS); } shutdown = G.evictor_scheduler_shutdown; } - snc_unlock(&lock); + P_Unlock(&lock); } } } diff --git a/src/user/user_core.c b/src/user/user_core.c index 105f25fa..56cad70b 100644 --- a/src/user/user_core.c +++ b/src/user/user_core.c @@ -61,7 +61,7 @@ GLOBAL struct { Arena *console_logs_arena; struct console_log *first_console_log; struct console_log *last_console_log; - i32 console_log_color_indices[LOG_LEVEL_COUNT]; + i32 console_log_color_indices[P_LogLevel_Count]; f32 console_logs_height; b32 debug_console; @@ -174,7 +174,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[P_Btn_Count] = { * ========================== */ INTERNAL P_ExitFuncDef(user_shutdown); -INTERNAL LOG_EVENT_CALLBACK_FUNC_DEF(debug_console_log_callback, log); +INTERNAL P_LogEventCallbackFuncDef(debug_console_log_callback, log); INTERNAL P_JobDef(user_update_job, _); INTERNAL P_JobDef(local_sim_job , _); @@ -225,8 +225,8 @@ struct user_startup_receipt user_startup(F_StartupReceipt *font_sr, G.render_sig = gp_render_sig_alloc(); G.console_logs_arena = arena_alloc(GIBI(64)); - //log_register_callback(debug_console_log_callback, LOG_LEVEL_SUCCESS); - log_register_callback(debug_console_log_callback, LOG_LEVEL_DEBUG); + //P_RegisterLogCallback(debug_console_log_callback, P_LogLevel_Success); + P_RegisterLogCallback(debug_console_log_callback, P_LogLevel_Debug); G.window = P_AllocWindow(); G.swapchain = gp_swapchain_alloc(G.window, V2i32FromXY(100, 100)); @@ -244,7 +244,7 @@ INTERNAL P_ExitFuncDef(user_shutdown) { __prof; atomic32_fetch_set(&G.shutdown, 1); - snc_counter_wait(&G.shutdown_job_counters); + P_WaitOnCounter(&G.shutdown_job_counters); P_ReleaseWindow(G.window); } @@ -275,7 +275,7 @@ INTERNAL void debug_draw_xform(Xform xf, u32 color_x, u32 color_y) //draw_quad(G.render_sig, quad, color); } -INTERNAL void debug_draw_movement(struct sim_ent *ent) +INTERNAL void debug_draw_movement(Ent *ent) { f32 thickness = 2.f; f32 arrow_len = 15.f; @@ -293,7 +293,7 @@ INTERNAL void debug_draw_movement(struct sim_ent *ent) } } -INTERNAL String get_ent_debug_text(Arena *arena, struct sim_ent *ent) +INTERNAL String get_ent_debug_text(Arena *arena, Ent *ent) { TempArena scratch = scratch_begin(arena); Snapshot *ss = ent->ss; @@ -363,7 +363,7 @@ INTERNAL String get_ent_debug_text(Arena *arena, struct sim_ent *ent) /* Children */ if (!sim_ent_id_is_nil(ent->first) || !sim_ent_id_is_nil(ent->last)) { - struct sim_ent *child = sim_ent_from_id(ss, ent->first); + Ent *child = sim_ent_from_id(ss, ent->first); if (!sim_ent_id_eq(ent->first, ent->last) || !child->valid) { res.len += string_format(arena, LIT("first child: [%F]\n"), FMT_UID(ent->first.uid)).len; res.len += string_format(arena, LIT("last child: [%F]\n"), FMT_UID(ent->last.uid)).len; @@ -385,10 +385,10 @@ INTERNAL String get_ent_debug_text(Arena *arena, struct sim_ent *ent) * Debug console * ========================== */ -INTERNAL LOG_EVENT_CALLBACK_FUNC_DEF(debug_console_log_callback, log) +INTERNAL P_LogEventCallbackFuncDef(debug_console_log_callback, log) { __prof; - P_Lock lock = snc_lock_e(&G.console_logs_mutex); + P_Lock lock = P_LockE(&G.console_logs_mutex); { struct console_log *clog = arena_push(G.console_logs_arena, struct console_log); clog->level = log.level; @@ -408,7 +408,7 @@ INTERNAL LOG_EVENT_CALLBACK_FUNC_DEF(debug_console_log_callback, log) } G.last_console_log = clog; } - snc_unlock(&lock); + P_Unlock(&lock); } INTERNAL void draw_debug_console(i32 level, b32 minimized) @@ -422,14 +422,14 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized) f32 spacing = 0; f32 bg_margin = 5; - LOCAL_PERSIST u32 colors[LOG_LEVEL_COUNT][2] = ZI; + LOCAL_PERSIST u32 colors[P_LogLevel_Count][2] = ZI; MEMSET(colors, 0xFF, sizeof(colors)); #if 1 - colors[LOG_LEVEL_DEBUG][0] = RGB32_F(0.4, 0.1, 0.4); colors[LOG_LEVEL_DEBUG][1] = RGB32_F(0.5, 0.2, 0.5); - colors[LOG_LEVEL_INFO][0] = RGB32_F(0.4, 0.4, 0.4); colors[LOG_LEVEL_INFO][1] = RGB32_F(0.5, 0.5, 0.5); - colors[LOG_LEVEL_SUCCESS][0] = RGB32_F(0.1, 0.3, 0.1); colors[LOG_LEVEL_SUCCESS][1] = RGB32_F(0.2, 0.4, 0.2); - colors[LOG_LEVEL_WARNING][0] = RGB32_F(0.4, 0.4, 0.1); colors[LOG_LEVEL_WARNING][1] = RGB32_F(0.5, 0.5, 0.2); - colors[LOG_LEVEL_ERROR][0] = RGB32_F(0.4, 0.1, 0.1); colors[LOG_LEVEL_ERROR][1] = RGB32_F(0.5, 0.2, 0.2); + colors[P_LogLevel_Debug][0] = RGB32_F(0.4, 0.1, 0.4); colors[P_LogLevel_Debug][1] = RGB32_F(0.5, 0.2, 0.5); + colors[P_LogLevel_Info][0] = RGB32_F(0.4, 0.4, 0.4); colors[P_LogLevel_Info][1] = RGB32_F(0.5, 0.5, 0.5); + colors[P_LogLevel_Success][0] = RGB32_F(0.1, 0.3, 0.1); colors[P_LogLevel_Success][1] = RGB32_F(0.2, 0.4, 0.2); + colors[P_LogLevel_Warning][0] = RGB32_F(0.4, 0.4, 0.1); colors[P_LogLevel_Warning][1] = RGB32_F(0.5, 0.5, 0.2); + colors[P_LogLevel_Error][0] = RGB32_F(0.4, 0.1, 0.1); colors[P_LogLevel_Error][1] = RGB32_F(0.5, 0.2, 0.2); #else u32 info_colors[2] = { RGB32_F(0.4, 0.4, 0.4), RGB32_F(0.5, 0.5, 0.5) }; u32 success_colors[2] = { RGB32_F(0.1, 0.3, 0.1), RGB32_F(0.2, 0.4, 0.2) }; @@ -449,7 +449,7 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized) i64 now_ns = P_TimeNs(); F_Font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f); if (font) { - P_Lock lock = snc_lock_e(&G.console_logs_mutex); + P_Lock lock = P_LockE(&G.console_logs_mutex); { for (struct console_log *log = G.last_console_log; log; log = log->prev) { f32 opacity = 0.75; @@ -496,7 +496,7 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized) } } } - snc_unlock(&lock); + P_Unlock(&lock); } if (bounds_top < F32_INFINITY && bounds_bottom > -F32_INFINITY) { G.console_logs_height = bounds_bottom - bounds_top; @@ -511,8 +511,8 @@ INTERNAL void draw_debug_console(i32 level, b32 minimized) INTERNAL SORT_COMPARE_FUNC_DEF(ent_draw_order_cmp, arg_a, arg_b, udata) { (UNUSED)udata; - struct sim_ent *a = *(struct sim_ent **)arg_a; - struct sim_ent *b = *(struct sim_ent **)arg_b; + Ent *a = *(Ent **)arg_a; + Ent *b = *(Ent **)arg_b; i32 res = 0; @@ -570,7 +570,7 @@ INTERNAL void user_update(P_Window *window) { __profn("Pull snapshot"); - P_Lock lock = snc_lock_e(&G.local_to_user_client_mutex); + P_Lock lock = P_LockE(&G.local_to_user_client_mutex); u64 old_last_tick = G.user_unblended_client->last_tick; u64 last_tick = G.local_to_user_client->last_tick; if (last_tick > old_last_tick) { @@ -580,7 +580,7 @@ INTERNAL void user_update(P_Window *window) G.average_local_to_user_snapshot_publish_dt_ns -= G.average_local_to_user_snapshot_publish_dt_ns / 50; G.average_local_to_user_snapshot_publish_dt_ns += G.local_to_user_client_publish_dt_ns / 50; } - snc_unlock(&lock); + P_Unlock(&lock); } /* ========================== * @@ -743,15 +743,15 @@ INTERNAL void user_update(P_Window *window) * Find local entities * ========================== */ - struct sim_ent *local_player = sim_ent_from_id(G.ss_blended, G.ss_blended->local_player); - struct sim_ent *local_control = sim_ent_from_id(G.ss_blended, local_player->player_control_ent); - struct sim_ent *local_camera = sim_ent_from_id(G.ss_blended, local_player->player_camera_ent); + Ent *local_player = sim_ent_from_id(G.ss_blended, G.ss_blended->local_player); + Ent *local_control = sim_ent_from_id(G.ss_blended, local_player->player_control_ent); + Ent *local_camera = sim_ent_from_id(G.ss_blended, local_player->player_camera_ent); /* ========================== * * Find hovered entity * ========================== */ - struct sim_ent *hovered_ent = sim_ent_nil(); + Ent *hovered_ent = sim_ent_nil(); { Xform mouse_xf = xform_from_pos(G.world_cursor); CLD_Shape mouse_shape = ZI; @@ -759,7 +759,7 @@ INTERNAL void user_update(P_Window *window) mouse_shape.count = 1; mouse_shape.radius = 0.01f; for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &G.ss_blended->ents[ent_index]; + Ent *ent = &G.ss_blended->ents[ent_index]; if (!sim_ent_is_valid_and_active(ent)) continue; CLD_Shape ent_collider = ent->local_collider; @@ -794,7 +794,7 @@ INTERNAL void user_update(P_Window *window) if (G.bind_states[USER_BIND_KIND_DEBUG_TOGGLE_TOPMOST].num_presses > 0) { P_ToggleWindowTopmost(window); - logf_success("Toggle topmost"); + P_LogSuccessF("Toggle topmost"); } if (G.bind_states[USER_BIND_KIND_DEBUG_CONSOLE].num_presses > 0) { @@ -814,11 +814,11 @@ INTERNAL void user_update(P_Window *window) } } if (!sim_ent_id_is_nil(G.debug_following)) { - struct sim_ent *follow_ent = sim_ent_from_id(G.ss_blended, G.debug_following); - struct sim_ent *follow_camera = sim_ent_nil(); + Ent *follow_ent = sim_ent_from_id(G.ss_blended, G.debug_following); + Ent *follow_camera = sim_ent_nil(); for (u64 i = 0; i < G.ss_blended->num_ents_reserved; ++i) { - struct sim_ent *ent = &G.ss_blended->ents[i]; - struct sim_ent *ent_camera_follow = sim_ent_from_id(G.ss_blended, ent->camera_follow); + Ent *ent = &G.ss_blended->ents[i]; + Ent *ent_camera_follow = sim_ent_from_id(G.ss_blended, ent->camera_follow); if (ent_camera_follow->valid && ent_camera_follow == follow_ent) { follow_camera = ent; break; @@ -837,7 +837,7 @@ INTERNAL void user_update(P_Window *window) * ========================== */ for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &G.ss_blended->ents[ent_index]; + Ent *ent = &G.ss_blended->ents[ent_index]; if (!sim_ent_is_valid_and_active(ent)) continue; /* How much time between camera shakes */ @@ -1042,7 +1042,7 @@ INTERNAL void user_update(P_Window *window) /* Alloc entries from new sim chunks */ for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) { - struct sim_ent *chunk_ent = &G.ss_blended->ents[ent_index]; + Ent *chunk_ent = &G.ss_blended->ents[ent_index]; if (sim_ent_is_valid_and_active(chunk_ent) && sim_ent_has_prop(chunk_ent, SEPROP_TILE_CHUNK)) { struct user_tile_cache_entry *entry = user_tile_cache_entry_from_chunk_pos(chunk_ent->tile_chunk_pos); if (!entry->valid) { @@ -1056,7 +1056,7 @@ INTERNAL void user_update(P_Window *window) for (u64 entry_index = 0; entry_index < G.tile_cache.num_reserved_entries; ++entry_index) { struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index]; if (entry->valid) { - struct sim_ent *chunk_ent = sim_ent_from_chunk_pos(entry->pos); + Ent *chunk_ent = sim_ent_from_chunk_pos(entry->pos); if (!chunk_ent->valid) { user_tile_cache_entry_release(entry); } @@ -1071,7 +1071,7 @@ INTERNAL void user_update(P_Window *window) struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index]; if (entry->valid) { V2i32 chunk_pos = entry->pos; - struct sim_ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos); + Ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos); if (entry->applied_dirty_gen != chunk_ent->dirty_gen) { entry->applied_dirty_gen = chunk_ent->dirty_gen; /* TODO: Autotiling */ @@ -1095,7 +1095,7 @@ INTERNAL void user_update(P_Window *window) struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index]; if (entry->valid) { V2i32 chunk_pos = entry->pos; - struct sim_ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos); + Ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos); if (entry->applied_dirty_gen != chunk_ent->dirty_gen) { entry->applied_dirty_gen = chunk_ent->dirty_gen; @@ -1112,14 +1112,14 @@ INTERNAL void user_update(P_Window *window) V2i32 chunk_pos_bl = V2i32FromXY(chunk_pos.x - 1, chunk_pos.y + 1); V2i32 chunk_pos_b = V2i32FromXY(chunk_pos.x, chunk_pos.y + 1); V2i32 chunk_pos_br = V2i32FromXY(chunk_pos.x + 1, chunk_pos.y + 1); - struct sim_ent *chunk_ent_tl = sim_ent_from_chunk_pos(chunk_pos_tl); - struct sim_ent *chunk_ent_t = sim_ent_from_chunk_pos(chunk_pos_t); - struct sim_ent *chunk_ent_tr = sim_ent_from_chunk_pos(chunk_pos_tr); - struct sim_ent *chunk_ent_l = sim_ent_from_chunk_pos(chunk_pos_l); - struct sim_ent *chunk_ent_r = sim_ent_from_chunk_pos(chunk_pos_r); - struct sim_ent *chunk_ent_bl = sim_ent_from_chunk_pos(chunk_pos_bl); - struct sim_ent *chunk_ent_b = sim_ent_from_chunk_pos(chunk_pos_b); - struct sim_ent *chunk_ent_br = sim_ent_from_chunk_pos(chunk_pos_br); + Ent *chunk_ent_tl = sim_ent_from_chunk_pos(chunk_pos_tl); + Ent *chunk_ent_t = sim_ent_from_chunk_pos(chunk_pos_t); + Ent *chunk_ent_tr = sim_ent_from_chunk_pos(chunk_pos_tr); + Ent *chunk_ent_l = sim_ent_from_chunk_pos(chunk_pos_l); + Ent *chunk_ent_r = sim_ent_from_chunk_pos(chunk_pos_r); + Ent *chunk_ent_bl = sim_ent_from_chunk_pos(chunk_pos_bl); + Ent *chunk_ent_b = sim_ent_from_chunk_pos(chunk_pos_b); + Ent *chunk_ent_br = sim_ent_from_chunk_pos(chunk_pos_br); String data = sim_ent_get_chunk_tile_data(chunk_ent); @@ -1134,16 +1134,16 @@ INTERNAL void user_update(P_Window *window) * Sort drawable entities * ========================== */ - struct sim_ent **sorted = arena_push_dry(scratch.arena, struct sim_ent *); + Ent **sorted = arena_push_dry(scratch.arena, Ent *); u64 sorted_count = 0; { /* Copy valid entities */ { __profn("Build ents list for sorting"); for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &G.ss_blended->ents[ent_index]; + Ent *ent = &G.ss_blended->ents[ent_index]; if (sim_ent_is_valid_and_active(ent)) { - *arena_push_no_zero(scratch.arena, struct sim_ent *) = ent; + *arena_push_no_zero(scratch.arena, Ent *) = ent; ++sorted_count; } } @@ -1162,13 +1162,13 @@ INTERNAL void user_update(P_Window *window) { __profn("Draw entities"); for (u64 sorted_index = 0; sorted_index < sorted_count; ++sorted_index) { - struct sim_ent *ent = sorted[sorted_index]; + Ent *ent = sorted[sorted_index]; if (!sim_ent_is_valid_and_active(ent)) continue; //if (sprite_tag_is_nil(ent->sprite)) continue; S_Tag sprite = ent->sprite; - struct sim_ent *parent = sim_ent_from_id(G.ss_blended, ent->parent); + Ent *parent = sim_ent_from_id(G.ss_blended, ent->parent); Xform xf = sim_ent_get_xform(ent); Xform parent_xf = sim_ent_get_xform(parent); @@ -1340,7 +1340,7 @@ INTERNAL void user_update(P_Window *window) /* Draw weld joint */ #if 0 if (sim_ent_has_prop(ent, SEPROP_WELD_JOINT)) { - struct sim_ent *e1 = sim_ent_from_id(G.ss_blended, ent->weld_joint_data.e1); + Ent *e1 = sim_ent_from_id(G.ss_blended, ent->weld_joint_data.e1); Xform e1_xf = sim_ent_get_xform(e1); u32 color = COLOR_YELLOW; @@ -1355,7 +1355,7 @@ INTERNAL void user_update(P_Window *window) /* Draw mouse joint */ if (sim_ent_has_prop(ent, SEPROP_MOUSE_JOINT)) { - struct sim_ent *target = sim_ent_from_id(G.ss_blended, ent->mouse_joint_data.target); + Ent *target = sim_ent_from_id(G.ss_blended, ent->mouse_joint_data.target); Xform target_xf = sim_ent_get_xform(target); u32 color = COLOR_WHITE; V2 point_start = xform_mul_v2(target_xf, ent->mouse_joint_data.point_local_start); @@ -1405,8 +1405,8 @@ INTERNAL void user_update(P_Window *window) /* Draw contact constraint */ if (sim_ent_has_prop(ent, SEPROP_CONTACT_CONSTRAINT)) { ContactConstraint *data = &ent->contact_constraint_data; - struct sim_ent *e0 = sim_ent_from_id(G.ss_blended, data->e0); - struct sim_ent *e1 = sim_ent_from_id(G.ss_blended, data->e1); + Ent *e0 = sim_ent_from_id(G.ss_blended, data->e0); + Ent *e1 = sim_ent_from_id(G.ss_blended, data->e1); (UNUSED)e0; (UNUSED)e1; @@ -1475,8 +1475,8 @@ INTERNAL void user_update(P_Window *window) if (sim_ent_has_prop(ent, SEPROP_COLLISION_DEBUG)) { CollisionDebugData *data = &ent->collision_debug_data; CLD_CollisionResult collider_res = data->res; - struct sim_ent *e0 = sim_ent_from_id(G.ss_blended, data->e0); - struct sim_ent *e1 = sim_ent_from_id(G.ss_blended, data->e1); + Ent *e0 = sim_ent_from_id(G.ss_blended, data->e0); + Ent *e1 = sim_ent_from_id(G.ss_blended, data->e1); CLD_Shape e0_collider = e0->local_collider; CLD_Shape e1_collider = e1->local_collider; (UNUSED)e0_collider; @@ -1848,7 +1848,7 @@ INTERNAL void user_update(P_Window *window) /* Set user sim control */ { - P_Lock lock = snc_lock_e(&G.user_sim_cmd_mutex); + P_Lock lock = P_LockE(&G.user_sim_cmd_mutex); /* Reset flags */ if (G.user_sim_cmd_gen != G.last_user_sim_cmd_gen) { @@ -1860,7 +1860,7 @@ INTERNAL void user_update(P_Window *window) G.user_sim_cmd_control = control; G.user_sim_cmd_control.flags |= old_flags; G.user_hovered_ent = hovered_ent->id; - snc_unlock(&lock); + P_Unlock(&lock); } } @@ -1899,7 +1899,7 @@ INTERNAL void user_update(P_Window *window) * ========================== */ if (G.debug_draw && hovered_ent->valid) { - struct sim_ent *ent = hovered_ent; + Ent *ent = hovered_ent; V2 pos = v2_add(G.ui_cursor, V2FromXY(15, 15)); F_Font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f); @@ -2037,11 +2037,11 @@ INTERNAL void user_update(P_Window *window) { #if DEVELOPER b32 console_minimized = !G.debug_console; - i32 console_level = console_minimized ? LOG_LEVEL_SUCCESS: LOG_LEVEL_DEBUG; + i32 console_level = console_minimized ? P_LogLevel_Success: P_LogLevel_Debug; draw_debug_console(console_level, console_minimized); #else if (G.debug_draw) { - draw_debug_console(LOG_LEVEL_INFO, 0); + draw_debug_console(P_LogLevel_Info, 0); } #endif } @@ -2095,7 +2095,7 @@ INTERNAL P_JobDef(user_update_job, _) } { __profn("Frame limiter wait"); - sys_sleep_frame(time_ns, 1000000000 / FPS_LIMIT); + P_SleepFrame(time_ns, 1000000000 / FPS_LIMIT); time_ns = P_TimeNs(); } } @@ -2121,9 +2121,9 @@ INTERNAL void generate_user_input_cmds(Client *user_input_client, u64 tick) { Snapshot *prev_user_input_ss = sim_snapshot_from_tick(user_input_client, user_input_client->last_tick); Snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, tick); - struct sim_ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID); + Ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID); /* Find / create local control cmd ent */ - struct sim_ent *control_cmd = sim_ent_find_first_match_one(user_input_ss, SEPROP_CMD); + Ent *control_cmd = sim_ent_find_first_match_one(user_input_ss, SEPROP_CMD); if (!control_cmd->valid) { control_cmd = sim_ent_alloc_sync_src(user_input_root); control_cmd->cmd_kind = SIM_CMD_KIND_CONTROL; @@ -2132,7 +2132,7 @@ INTERNAL void generate_user_input_cmds(Client *user_input_client, u64 tick) sim_ent_activate(control_cmd, user_input_ss->tick); } { - P_Lock lock = snc_lock_e(&G.user_sim_cmd_mutex); + P_Lock lock = P_LockE(&G.user_sim_cmd_mutex); /* Update control cmd */ { control_cmd->cmd_control = G.user_sim_cmd_control; @@ -2141,13 +2141,13 @@ INTERNAL void generate_user_input_cmds(Client *user_input_client, u64 tick) #if 0 /* Create chat cmd */ if (G.user_sim_cmd_chat.len > 0) { - struct sim_ent *chat_cmd = sim_ent_alloc_sync_src(user_input_root); + Ent *chat_cmd = sim_ent_alloc_sync_src(user_input_root); chat_cmd->cmd_kind = SIM_CMD_KIND_CHAT; //chat_cmd->chat_msg = ZI } #endif ++G.user_sim_cmd_gen; - snc_unlock(&lock); + P_Unlock(&lock); } } @@ -2260,7 +2260,7 @@ INTERNAL P_JobDef(local_sim_job, _) TempArena scratch = scratch_begin_no_conflict(); { __profn("Sim sleep"); - sys_sleep_frame(real_time_ns, step_dt_ns * compute_timescale); + P_SleepFrame(real_time_ns, step_dt_ns * compute_timescale); } { __profn("Sim update"); @@ -2406,7 +2406,7 @@ INTERNAL P_JobDef(local_sim_job, _) /* Assume all incoming ents want to be sync srcs */ for (u64 i = 0; i < ss->num_ents_reserved; ++i) { - struct sim_ent *ent = &ss->ents[i]; + Ent *ent = &ss->ents[i]; if (ent->valid && sim_ent_has_prop(ent, SEPROP_SYNC_DST)) { sim_ent_disable_prop(ent, SEPROP_SYNC_DST); sim_ent_enable_prop(ent, SEPROP_SYNC_SRC); @@ -2590,25 +2590,25 @@ INTERNAL P_JobDef(local_sim_job, _) #if 0 DEBUGBREAKABLE; - logf_debug("*************************************************"); - logf_debug("local_client->last_tick: %F", FMT_UINT(local_client->last_tick)); - logf_debug("master_sim_predicted_time_ns: %F", FMT_SINT(master_sim_predicted_time_ns)); - logf_debug("tick_progress: %F", FMT_FLOAT(tick_progress)); - logf_debug("sim_publish_timescale: %F", FMT_FLOAT(sim_publish_timescale)); - logf_debug("last_tick_from_master_received_at_ns: %F", FMT_SINT(last_tick_from_master_received_at_ns)); - logf_debug("average_master_receive_dt_ns: %F", FMT_SINT(average_master_receive_dt_ns)); - logf_debug("next_tick_expected_ns: %F", FMT_SINT(next_tick_expected_ns)); - logf_debug("master_blend_time_target_ns: %F", FMT_SINT(master_blend_time_target_ns)); - logf_debug("blend_time_target_diff_ns: %F", FMT_SINT(blend_time_target_diff_ns)); - logf_debug("master_blend_time_ns: %F", FMT_SINT(master_blend_time_ns)); - logf_debug("left_snapshot->tick: %F", FMT_UINT(left_snapshot->tick)); - logf_debug("right_snapshot->tick: %F", FMT_UINT(right_snapshot->tick)); - logf_debug("master_ss->tick: %F", FMT_UINT(master_ss->tick)); + P_LogDebugF("*************************************************"); + P_LogDebugF("local_client->last_tick: %F", FMT_UINT(local_client->last_tick)); + P_LogDebugF("master_sim_predicted_time_ns: %F", FMT_SINT(master_sim_predicted_time_ns)); + P_LogDebugF("tick_progress: %F", FMT_FLOAT(tick_progress)); + P_LogDebugF("sim_publish_timescale: %F", FMT_FLOAT(sim_publish_timescale)); + P_LogDebugF("last_tick_from_master_received_at_ns: %F", FMT_SINT(last_tick_from_master_received_at_ns)); + P_LogDebugF("average_master_receive_dt_ns: %F", FMT_SINT(average_master_receive_dt_ns)); + P_LogDebugF("next_tick_expected_ns: %F", FMT_SINT(next_tick_expected_ns)); + P_LogDebugF("master_blend_time_target_ns: %F", FMT_SINT(master_blend_time_target_ns)); + P_LogDebugF("blend_time_target_diff_ns: %F", FMT_SINT(blend_time_target_diff_ns)); + P_LogDebugF("master_blend_time_ns: %F", FMT_SINT(master_blend_time_ns)); + P_LogDebugF("left_snapshot->tick: %F", FMT_UINT(left_snapshot->tick)); + P_LogDebugF("right_snapshot->tick: %F", FMT_UINT(right_snapshot->tick)); + P_LogDebugF("master_ss->tick: %F", FMT_UINT(master_ss->tick)); #endif } if (master_ss->valid) { - struct sim_ent *master_player = sim_ent_find_first_match_one(master_ss, SEPROP_PLAYER_IS_MASTER); + Ent *master_player = sim_ent_find_first_match_one(master_ss, SEPROP_PLAYER_IS_MASTER); /* Update ent id from master */ { @@ -2750,7 +2750,7 @@ INTERNAL P_JobDef(local_sim_job, _) Snapshot *local_ss = sim_snapshot_from_tick(local_client, local_client->last_tick); if (local_ss->valid) { /* TODO: Double buffer */ - P_Lock lock = snc_lock_e(&G.local_to_user_client_mutex); + P_Lock lock = P_LockE(&G.local_to_user_client_mutex); sim_snapshot_alloc(G.local_to_user_client, local_ss, local_ss->tick); i64 publish_ns = P_TimeNs(); if (last_publish_to_user_ns == 0) { @@ -2760,7 +2760,7 @@ INTERNAL P_JobDef(local_sim_job, _) G.local_to_user_client_publish_time_ns = publish_ns; last_publish_to_user_ns = publish_ns; sim_snapshot_release_ticks_in_range(G.local_to_user_client, 0, local_ss->tick - 1); - snc_unlock(&lock); + P_Unlock(&lock); } } diff --git a/src/watch/watch_core.c b/src/watch/watch_core.c index cea2447c..94fae300 100644 --- a/src/watch/watch_core.c +++ b/src/watch/watch_core.c @@ -50,17 +50,17 @@ INTERNAL P_ExitFuncDef(watch_shutdown) atomic32_fetch_set(&G.watch_shutdown, 1); { - P_Lock lock = snc_lock_e(&G.watch_dispatcher_mutex); - snc_cv_signal(&G.watch_dispatcher_cv, I32_MAX); + P_Lock lock = P_LockE(&G.watch_dispatcher_mutex); + P_SignalCv(&G.watch_dispatcher_cv, I32_MAX); P_WakeWatch(G.watch); - snc_unlock(&lock); + P_Unlock(&lock); } - snc_counter_wait(&G.watch_jobs_counter); + P_WaitOnCounter(&G.watch_jobs_counter); } void watch_register_callback(watch_callback *callback) { - P_Lock lock = snc_lock_e(&G.watch_callbacks_mutex); + P_Lock lock = P_LockE(&G.watch_callbacks_mutex); { if (G.num_watch_callbacks < countof(G.watch_callbacks)) { G.watch_callbacks[G.num_watch_callbacks++] = callback; @@ -68,7 +68,7 @@ void watch_register_callback(watch_callback *callback) P_Panic(LIT("Max resource watch callbacks reached")); } } - snc_unlock(&lock); + P_Unlock(&lock); } INTERNAL P_JobDef(watch_monitor_job, _) @@ -85,7 +85,7 @@ INTERNAL P_JobDef(watch_monitor_job, _) TempArena temp = arena_temp_begin(scratch.arena); P_WatchInfoList info_list = P_ReadWatchWait(temp.arena, G.watch); if (info_list.first && !atomic32_fetch(&G.watch_shutdown)) { - P_Lock lock = snc_lock_e(&G.watch_dispatcher_mutex); + P_Lock lock = P_LockE(&G.watch_dispatcher_mutex); { for (P_WatchInfo *info = info_list.first; info; info = info->next) { String name_src = info->name; @@ -108,8 +108,8 @@ INTERNAL P_JobDef(watch_monitor_job, _) } } } - snc_cv_signal(&G.watch_dispatcher_cv, I32_MAX); - snc_unlock(&lock); + P_SignalCv(&G.watch_dispatcher_cv, I32_MAX); + P_Unlock(&lock); } arena_temp_end(temp); } @@ -157,7 +157,7 @@ INTERNAL P_JobDef(watch_dispatcher_job, _) /* Pull watch events from queue */ { - P_Lock lock = snc_lock_e(&G.watch_dispatcher_mutex); + P_Lock lock = P_LockE(&G.watch_dispatcher_mutex); for (struct watch_event *src_event = G.first_watch_event; src_event; src_event = src_event->next) { struct watch_event *e = arena_push(scratch.arena, struct watch_event); e->name = string_copy(scratch.arena, src_event->name); @@ -171,13 +171,13 @@ INTERNAL P_JobDef(watch_dispatcher_job, _) G.first_watch_event = 0; G.last_watch_event = 0; arena_reset(G.watch_events_arena); - snc_unlock(&lock); + P_Unlock(&lock); } /* Build callbacks array */ u64 num_callbacks = 0; watch_callback **callbacks = 0; - P_Lock callbacks_lock = snc_lock_s(&G.watch_callbacks_mutex); + P_Lock callbacks_lock = P_LockS(&G.watch_callbacks_mutex); { num_callbacks = G.num_watch_callbacks; callbacks = arena_push_array_no_zero(scratch.arena, watch_callback *, num_callbacks); @@ -185,7 +185,7 @@ INTERNAL P_JobDef(watch_dispatcher_job, _) callbacks[i] = G.watch_callbacks[i]; } } - snc_unlock(&callbacks_lock); + P_Unlock(&callbacks_lock); /* Run callbacks */ { @@ -206,7 +206,7 @@ INTERNAL P_JobDef(watch_dispatcher_job, _) sig.callbacks = callbacks; P_Counter counter = ZI; P_Run(num_callbacks, watch_callback_job, &sig, P_Pool_Background, P_Priority_Low, &counter); - snc_counter_wait(&counter); + P_WaitOnCounter(&counter); } } } @@ -215,15 +215,15 @@ INTERNAL P_JobDef(watch_dispatcher_job, _) } /* Wait for event */ - P_Lock lock = snc_lock_s(&G.watch_dispatcher_mutex); + P_Lock lock = P_LockS(&G.watch_dispatcher_mutex); { shutdown = atomic32_fetch(&G.watch_shutdown); while (!shutdown && !G.first_watch_event) { - snc_cv_wait(&G.watch_dispatcher_cv, &lock); + P_WaitOnCv(&G.watch_dispatcher_cv, &lock); shutdown = atomic32_fetch(&G.watch_shutdown); } } - snc_unlock(&lock); + P_Unlock(&lock); } }