diff --git a/Single-Header/dn_single_header.cpp b/Single-Header/dn_single_header.cpp index 6e1e02a..4df4f2b 100644 --- a/Single-Header/dn_single_header.cpp +++ b/Single-Header/dn_single_header.cpp @@ -1,4 +1,4 @@ -// Generated by the DN single header generator 2025-11-20 22:39:16 +// Generated by the DN single header generator 2025-11-30 21:32:49 #define DN_BASE_INC_CPP @@ -1691,6 +1691,23 @@ DN_API DN_Str8 DN_Str8FromFmtPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, return result; } +DN_API DN_Str8x16 DN_Str8x16FromFmt(DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_Str8x16 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + va_end(args); + return result; +} + +DN_API DN_Str8x16 DN_Str8x16FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x16 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x32 DN_Str8x32FromFmt(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; @@ -5141,9 +5158,12 @@ DN_API void DN_OS_TLSInit(DN_OSTLS *tls, DN_OSTLSInitArgs args) return; DN_U64 reserve = args.reserve ? args.reserve : DN_Kilobytes(64); - DN_U64 commit = args.commit ? args.commit : DN_Kilobytes(4); DN_U64 err_sink_reserve = args.err_sink_reserve ? args.err_sink_reserve : DN_Kilobytes(64); + + #if !defined(DN_PLATFORM_EMSCRIPTEN) + DN_U64 commit = args.commit ? args.commit : DN_Kilobytes(4); DN_U64 err_sink_commit = args.err_sink_commit ? args.err_sink_commit : DN_Kilobytes(4); + #endif // TODO: We shouldn't have the no alloc track flag here but the initial TLS // init on OS init happens before CORE init. CORE init is the one responsible @@ -5151,8 +5171,22 @@ DN_API void DN_OS_TLSInit(DN_OSTLS *tls, DN_OSTLSInitArgs args) for (DN_ForItCArray(it, DN_Arena, tls->arenas)) { DN_Arena *arena = it.data; switch (DN_Cast(DN_OSTLSArena) it.index) { - default: *arena = DN_ArenaFromVMem(reserve, commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break; - case DN_OSTLSArena_ErrorSink: *arena = DN_ArenaFromVMem(err_sink_reserve, err_sink_commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break; + default: { + #if defined(DN_PLATFORM_EMSCRIPTEN) + *arena = DN_ArenaFromHeap(reserve, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); + #else + *arena = DN_ArenaFromVMem(reserve, commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); + #endif + } break; + + case DN_OSTLSArena_ErrorSink: { + #if defined(DN_PLATFORM_EMSCRIPTEN) + *arena = DN_ArenaFromHeap(err_sink_reserve, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); + #else + *arena = DN_ArenaFromVMem(err_sink_reserve, err_sink_commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); + #endif + } break; + case DN_OSTLSArena_Count: DN_InvalidCodePath; break; } } @@ -7019,6 +7053,10 @@ static DN_U32 DN_OS_MemConvertPageToOSFlags_(DN_U32 protect) DN_API void *DN_OS_MemReserve(DN_USize size, DN_MemCommit commit, DN_U32 page_flags) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory, you should use DN_OS_MemAlloc"); + #endif + unsigned long os_page_flags = DN_OS_MemConvertPageToOSFlags_(page_flags); if (commit == DN_MemCommit_Yes) @@ -7034,6 +7072,9 @@ DN_API void *DN_OS_MemReserve(DN_USize size, DN_MemCommit commit, DN_U32 page_fl DN_API bool DN_OS_MemCommit(void *ptr, DN_USize size, DN_U32 page_flags) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory"); + #endif bool result = false; if (!ptr || size == 0) return false; @@ -7047,17 +7088,26 @@ DN_API bool DN_OS_MemCommit(void *ptr, DN_USize size, DN_U32 page_flags) DN_API void DN_OS_MemDecommit(void *ptr, DN_USize size) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory"); + #endif mprotect(ptr, size, PROT_NONE); madvise(ptr, size, MADV_FREE); } DN_API void DN_OS_MemRelease(void *ptr, DN_USize size) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory"); + #endif munmap(ptr, size); } DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory"); + #endif if (!ptr || size == 0) return 0; @@ -7142,7 +7192,8 @@ DN_API DN_U64 DN_OS_DateUnixTimeSFromLocalDate(DN_Date date) DN_API DN_U64 DN_OS_DateLocalUnixTimeSFromUnixTimeS(DN_U64 unix_ts_s) { struct tm tm_local; - void *ret = localtime_r(&unix_ts_s, &tm_local); + time_t unix_ts = unix_ts_s; + void *ret = localtime_r(&unix_ts, &tm_local); DN_Assert(ret); long local_offset_seconds = tm_local.tm_gmtoff; @@ -10972,6 +11023,7 @@ struct DN_Str8 DN_USize size; // The number of bytes in the string }; +struct DN_Str8x16 { char data[16]; DN_USize size; }; struct DN_Str8x32 { char data[32]; DN_USize size; }; struct DN_Str8x64 { char data[64]; DN_USize size; }; struct DN_Str8x128 { char data[128]; DN_USize size; }; @@ -13739,6 +13791,8 @@ DN_API DN_Str8 DN_Str8FromFmtArena (DN_Arena *arena, DN DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type); +DN_API DN_Str8x16 DN_Str8x16FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x16 DN_Str8x16FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8x32 DN_Str8x32FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); @@ -18755,11 +18809,6 @@ DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); -DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; -DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; -DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; -DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; - #define DN_V4F32_From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V4F32_From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} #define DN_V4F32_FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} @@ -19694,19 +19743,19 @@ DN_API DN_V3F32 DN_V3_Normalise(DN_V3F32 a) DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32) { - DN_U8 r = (DN_U8)((u32 & DN_V4_R_MASK_U32) >> 24); - DN_U8 g = (DN_U8)((u32 & DN_V4_G_MASK_U32) >> 16); - DN_U8 b = (DN_U8)((u32 & DN_V4_B_MASK_U32) >> 8); + DN_U8 r = (DN_U8)((u32 & 0x00FF0000) >> 16); + DN_U8 g = (DN_U8)((u32 & 0x0000FF00) >> 8); + DN_U8 b = (DN_U8)((u32 & 0x000000FF) >> 0); DN_V4F32 result = DN_V4F32_FromRGBU8(r, g, b); return result; } DN_API DN_V4F32 DN_V4F32_FromRGBAU32(DN_U32 u32) { - DN_U8 r = (DN_U8)((u32 & DN_V4_R_MASK_U32) >> 24); - DN_U8 g = (DN_U8)((u32 & DN_V4_G_MASK_U32) >> 16); - DN_U8 b = (DN_U8)((u32 & DN_V4_B_MASK_U32) >> 8); - DN_U8 a = (DN_U8)((u32 & DN_V4_A_MASK_U32) >> 0); + DN_U8 r = (DN_U8)((u32 & 0xFF000000) >> 24); + DN_U8 g = (DN_U8)((u32 & 0x00FF0000) >> 16); + DN_U8 b = (DN_U8)((u32 & 0x0000FF00) >> 8); + DN_U8 a = (DN_U8)((u32 & 0x000000FF) >> 0); DN_V4F32 result = DN_V4F32_FromRGBAU8(r, g, b, a); return result; } @@ -20652,32 +20701,36 @@ struct DN_BinPack DN_USize read_index; }; -DN_API void DN_BinPack_U64 (DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item); -DN_API void DN_BinPack_U32 (DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item); -DN_API void DN_BinPack_U16 (DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item); -DN_API void DN_BinPack_U8 (DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item); -DN_API void DN_BinPack_I64 (DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item); -DN_API void DN_BinPack_I32 (DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item); -DN_API void DN_BinPack_I16 (DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item); -DN_API void DN_BinPack_I8 (DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item); -DN_API void DN_BinPack_F64 (DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item); -DN_API void DN_BinPack_F32 (DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item); -#if defined(DN_MATH_H) -DN_API void DN_BinPack_V2 (DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item); -DN_API void DN_BinPack_V4 (DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item); +DN_API bool DN_BinPackIsEndOfReadStream(DN_BinPack const *pack); +DN_API void DN_BinPackUSize (DN_BinPack *pack, DN_BinPackMode mode, DN_USize *item); +DN_API void DN_BinPackU64 (DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item); +DN_API void DN_BinPackU32 (DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item); +DN_API void DN_BinPackU16 (DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item); +DN_API void DN_BinPackU8 (DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item); +DN_API void DN_BinPackI64 (DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item); +DN_API void DN_BinPackI32 (DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item); +DN_API void DN_BinPackI16 (DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item); +DN_API void DN_BinPackI8 (DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item); +DN_API void DN_BinPackF64 (DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item); +DN_API void DN_BinPackF32 (DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item); +#if defined (DN_MATH_H) +DN_API void DN_BinPackV2 (DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item); +DN_API void DN_BinPackV4 (DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item); #endif -DN_API void DN_BinPack_Bool (DN_BinPack *pack, DN_BinPackMode mode, bool *item); -DN_API void DN_BinPack_Str8FromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string); -DN_API void DN_BinPack_Str8FromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string); -DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size); -DN_API void DN_BinPack_BytesFromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size); -DN_API void DN_BinPack_CArray (DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size); -DN_API DN_Str8 DN_BinPack_Build (DN_BinPack const *pack, DN_Arena *arena); +DN_API void DN_BinPackBool (DN_BinPack *pack, DN_BinPackMode mode, bool *item); +DN_API void DN_BinPackStr8FromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string); +DN_API void DN_BinPackStr8FromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string); +DN_API DN_Str8 DN_BinPackStr8FromBuffer (DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max); +DN_API void DN_BinPackBytesFromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size); +DN_API void DN_BinPackBytesFromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size); +DN_API void DN_BinPackCArray (DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size); +DN_API void DN_BinPackCBuffer (DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max); +DN_API DN_Str8 DN_BinPackBuild (DN_BinPack const *pack, DN_Arena *arena); #endif // !defined(DN_BIN_PACK_H) #endif -DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) +DN_API void DN_BinPackU64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) { DN_U64 const VALUE_MASK = 0b0111'1111; DN_U8 const CONTINUE_BIT = 0b1000'0000; @@ -20702,7 +20755,7 @@ DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) } } -DN_API void DN_BinPack_VarInt_(DN_BinPack *pack, DN_BinPackMode mode, void *item, DN_USize size) +DN_API void DN_BinPackVarInt_(DN_BinPack *pack, DN_BinPackMode mode, void *item, DN_USize size) { DN_U64 value = 0; DN_AssertF(size <= sizeof(value), @@ -20712,81 +20765,92 @@ DN_API void DN_BinPack_VarInt_(DN_BinPack *pack, DN_BinPackMode mode, void *item if (mode == DN_BinPackMode_Serialise) // Read `item` into U64 `value` DN_Memcpy(&value, item, size); - DN_BinPack_U64(pack, mode, &value); + DN_BinPackU64(pack, mode, &value); if (mode == DN_BinPackMode_Deserialise) // Write U64 `value` into `item` DN_Memcpy(item, &value, size); } -DN_API void DN_BinPack_U32(DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item) +DN_API bool DN_BinPackIsEndOfReadStream(DN_BinPack const *pack) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + bool result = pack->read_index == pack->read.size; + return result; } -DN_API void DN_BinPack_U16(DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item) +DN_API void DN_BinPackUSize(DN_BinPack *pack, DN_BinPackMode mode, DN_USize *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_U8(DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item) +DN_API void DN_BinPackU32(DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_I64(DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item) +DN_API void DN_BinPackU16(DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_I32(DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item) +DN_API void DN_BinPackU8(DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_I16(DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item) +DN_API void DN_BinPackI64(DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_I8(DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item) +DN_API void DN_BinPackI32(DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_F64(DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item) +DN_API void DN_BinPackI16(DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_F32(DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item) +DN_API void DN_BinPackI8(DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); +} + +DN_API void DN_BinPackF64(DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item) +{ + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); +} + +DN_API void DN_BinPackF32(DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item) +{ + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } #if defined(DN_MATH_H) -DN_API void DN_BinPack_V2(DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item) +DN_API void DN_BinPackV2(DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item) { - DN_BinPack_F32(pack, mode, &item->x); - DN_BinPack_F32(pack, mode, &item->y); + DN_BinPackF32(pack, mode, &item->x); + DN_BinPackF32(pack, mode, &item->y); } -DN_API void DN_BinPack_V4(DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item) +DN_API void DN_BinPackV4(DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item) { - DN_BinPack_F32(pack, mode, &item->x); - DN_BinPack_F32(pack, mode, &item->y); - DN_BinPack_F32(pack, mode, &item->z); - DN_BinPack_F32(pack, mode, &item->w); + DN_BinPackF32(pack, mode, &item->x); + DN_BinPackF32(pack, mode, &item->y); + DN_BinPackF32(pack, mode, &item->z); + DN_BinPackF32(pack, mode, &item->w); } #endif -DN_API void DN_BinPack_Bool(DN_BinPack *pack, DN_BinPackMode mode, bool *item) +DN_API void DN_BinPackBool(DN_BinPack *pack, DN_BinPackMode mode, bool *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_Str8FromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string) +DN_API void DN_BinPackStr8FromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string) { - DN_BinPack_VarInt_(pack, mode, &string->size, sizeof(string->size)); + DN_BinPackVarInt_(pack, mode, &string->size, sizeof(string->size)); if (mode == DN_BinPackMode_Serialise) { DN_Str8BuilderAppendBytesCopy(&pack->writer, string->data, string->size); } else { @@ -20796,9 +20860,9 @@ DN_API void DN_BinPack_Str8FromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPa } } -DN_API void DN_BinPack_Str8FromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string) +DN_API void DN_BinPackStr8FromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string) { - DN_BinPack_VarInt_(pack, mode, &string->size, sizeof(string->size)); + DN_BinPackVarInt_(pack, mode, &string->size, sizeof(string->size)); if (mode == DN_BinPackMode_Serialise) { DN_Str8BuilderAppendBytesCopy(&pack->writer, string->data, string->size); } else { @@ -20808,25 +20872,32 @@ DN_API void DN_BinPack_Str8FromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackM } } -DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size) +DN_API DN_Str8 DN_BinPackStr8FromBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max) +{ + DN_BinPackCBuffer(pack, mode, ptr, size, max); + DN_Str8 result = DN_Str8FromPtr(ptr, *size); + return result; +} + +DN_API void DN_BinPackBytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size) { DN_Str8 string = DN_Str8FromPtr(*ptr, *size); - DN_BinPack_Str8FromArena(pack, arena, mode, &string); + DN_BinPackStr8FromArena(pack, arena, mode, &string); *ptr = string.data; *size = string.size; } -DN_API void DN_BinPack_BytesFromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size) +DN_API void DN_BinPackBytesFromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size) { DN_Str8 string = DN_Str8FromPtr(*ptr, *size); - DN_BinPack_Str8FromPool(pack, pool, mode, &string); + DN_BinPackStr8FromPool(pack, pool, mode, &string); *ptr = string.data; *size = string.size; } -DN_API void DN_BinPack_CArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size) +DN_API void DN_BinPackCArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size) { - DN_BinPack_VarInt_(pack, mode, &size, sizeof(size)); + DN_BinPackVarInt_(pack, mode, &size, sizeof(size)); if (mode == DN_BinPackMode_Serialise) { DN_Str8BuilderAppendBytesCopy(&pack->writer, ptr, size); } else { @@ -20837,7 +20908,24 @@ DN_API void DN_BinPack_CArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr, } } -DN_API DN_Str8 DN_BinPack_Build(DN_BinPack const *pack, DN_Arena *arena) +DN_API void DN_BinPackCBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max) +{ + if (mode == DN_BinPackMode_Serialise) { + DN_BinPackUSize(pack, mode, size); + DN_Str8BuilderAppendBytesCopy(&pack->writer, ptr, *size); + } else { + DN_U64 size_u64 = 0; + DN_BinPackU64(pack, mode, &size_u64); + DN_Assert(size_u64 < DN_USIZE_MAX); + DN_Assert(size_u64 <= max); + + *size = DN_Min(size_u64, max); + DN_Memcpy(ptr, pack->read.data + pack->read_index, *size); + pack->read_index += size_u64; + } +} + +DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena) { DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena); return result; @@ -21759,11 +21847,6 @@ DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); -DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; -DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; -DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; -DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; - #define DN_V4F32_From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V4F32_From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} #define DN_V4F32_FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} diff --git a/Single-Header/dn_single_header.h b/Single-Header/dn_single_header.h index e49c3c1..abcb21a 100644 --- a/Single-Header/dn_single_header.h +++ b/Single-Header/dn_single_header.h @@ -1,4 +1,4 @@ -// Generated by the DN single header generator 2025-11-20 22:39:16 +// Generated by the DN single header generator 2025-11-30 21:32:49 #if !defined(DN_BASE_INC_H) #define DN_BASE_INC_H @@ -396,6 +396,7 @@ struct DN_Str8 DN_USize size; // The number of bytes in the string }; +struct DN_Str8x16 { char data[16]; DN_USize size; }; struct DN_Str8x32 { char data[32]; DN_USize size; }; struct DN_Str8x64 { char data[64]; DN_USize size; }; struct DN_Str8x128 { char data[128]; DN_USize size; }; @@ -3163,6 +3164,8 @@ DN_API DN_Str8 DN_Str8FromFmtArena (DN_Arena *arena, DN DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type); +DN_API DN_Str8x16 DN_Str8x16FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x16 DN_Str8x16FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8x32 DN_Str8x32FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); @@ -8089,6 +8092,7 @@ struct DN_Str8 DN_USize size; // The number of bytes in the string }; +struct DN_Str8x16 { char data[16]; DN_USize size; }; struct DN_Str8x32 { char data[32]; DN_USize size; }; struct DN_Str8x64 { char data[64]; DN_USize size; }; struct DN_Str8x128 { char data[128]; DN_USize size; }; @@ -10856,6 +10860,8 @@ DN_API DN_Str8 DN_Str8FromFmtArena (DN_Arena *arena, DN DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type); +DN_API DN_Str8x16 DN_Str8x16FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x16 DN_Str8x16FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8x32 DN_Str8x32FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); @@ -15686,11 +15692,6 @@ DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); -DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; -DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; -DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; -DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; - #define DN_V4F32_From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V4F32_From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} #define DN_V4F32_FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} @@ -15873,27 +15874,31 @@ struct DN_BinPack DN_USize read_index; }; -DN_API void DN_BinPack_U64 (DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item); -DN_API void DN_BinPack_U32 (DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item); -DN_API void DN_BinPack_U16 (DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item); -DN_API void DN_BinPack_U8 (DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item); -DN_API void DN_BinPack_I64 (DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item); -DN_API void DN_BinPack_I32 (DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item); -DN_API void DN_BinPack_I16 (DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item); -DN_API void DN_BinPack_I8 (DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item); -DN_API void DN_BinPack_F64 (DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item); -DN_API void DN_BinPack_F32 (DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item); -#if defined(DN_MATH_H) -DN_API void DN_BinPack_V2 (DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item); -DN_API void DN_BinPack_V4 (DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item); +DN_API bool DN_BinPackIsEndOfReadStream(DN_BinPack const *pack); +DN_API void DN_BinPackUSize (DN_BinPack *pack, DN_BinPackMode mode, DN_USize *item); +DN_API void DN_BinPackU64 (DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item); +DN_API void DN_BinPackU32 (DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item); +DN_API void DN_BinPackU16 (DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item); +DN_API void DN_BinPackU8 (DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item); +DN_API void DN_BinPackI64 (DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item); +DN_API void DN_BinPackI32 (DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item); +DN_API void DN_BinPackI16 (DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item); +DN_API void DN_BinPackI8 (DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item); +DN_API void DN_BinPackF64 (DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item); +DN_API void DN_BinPackF32 (DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item); +#if defined (DN_MATH_H) +DN_API void DN_BinPackV2 (DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item); +DN_API void DN_BinPackV4 (DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item); #endif -DN_API void DN_BinPack_Bool (DN_BinPack *pack, DN_BinPackMode mode, bool *item); -DN_API void DN_BinPack_Str8FromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string); -DN_API void DN_BinPack_Str8FromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string); -DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size); -DN_API void DN_BinPack_BytesFromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size); -DN_API void DN_BinPack_CArray (DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size); -DN_API DN_Str8 DN_BinPack_Build (DN_BinPack const *pack, DN_Arena *arena); +DN_API void DN_BinPackBool (DN_BinPack *pack, DN_BinPackMode mode, bool *item); +DN_API void DN_BinPackStr8FromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string); +DN_API void DN_BinPackStr8FromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string); +DN_API DN_Str8 DN_BinPackStr8FromBuffer (DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max); +DN_API void DN_BinPackBytesFromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size); +DN_API void DN_BinPackBytesFromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size); +DN_API void DN_BinPackCArray (DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size); +DN_API void DN_BinPackCBuffer (DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max); +DN_API DN_Str8 DN_BinPackBuild (DN_BinPack const *pack, DN_Arena *arena); #endif // !defined(DN_BIN_PACK_H) #if !defined(DN_CSV_H) @@ -16248,11 +16253,6 @@ DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); -DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; -DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; -DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; -DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; - #define DN_V4F32_From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V4F32_From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} #define DN_V4F32_FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} diff --git a/Source/Base/dn_base.cpp b/Source/Base/dn_base.cpp index f974e7f..4cadb73 100644 --- a/Source/Base/dn_base.cpp +++ b/Source/Base/dn_base.cpp @@ -1686,6 +1686,23 @@ DN_API DN_Str8 DN_Str8FromFmtPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, return result; } +DN_API DN_Str8x16 DN_Str8x16FromFmt(DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_Str8x16 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + va_end(args); + return result; +} + +DN_API DN_Str8x16 DN_Str8x16FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x16 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x32 DN_Str8x32FromFmt(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; diff --git a/Source/Base/dn_base.h b/Source/Base/dn_base.h index b45fb2d..ac8e404 100644 --- a/Source/Base/dn_base.h +++ b/Source/Base/dn_base.h @@ -178,6 +178,7 @@ struct DN_Str8 DN_USize size; // The number of bytes in the string }; +struct DN_Str8x16 { char data[16]; DN_USize size; }; struct DN_Str8x32 { char data[32]; DN_USize size; }; struct DN_Str8x64 { char data[64]; DN_USize size; }; struct DN_Str8x128 { char data[128]; DN_USize size; }; @@ -1017,6 +1018,8 @@ DN_API DN_Str8 DN_Str8FromFmtArena (DN_Arena *arena, DN DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type); +DN_API DN_Str8x16 DN_Str8x16FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x16 DN_Str8x16FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8x32 DN_Str8x32FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); diff --git a/Source/Extra/dn_bin_pack.cpp b/Source/Extra/dn_bin_pack.cpp index 1e6d6f4..6bb1bca 100644 --- a/Source/Extra/dn_bin_pack.cpp +++ b/Source/Extra/dn_bin_pack.cpp @@ -4,7 +4,7 @@ #include "dn_bin_pack.h" #endif -DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) +DN_API void DN_BinPackU64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) { DN_U64 const VALUE_MASK = 0b0111'1111; DN_U8 const CONTINUE_BIT = 0b1000'0000; @@ -29,7 +29,7 @@ DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) } } -DN_API void DN_BinPack_VarInt_(DN_BinPack *pack, DN_BinPackMode mode, void *item, DN_USize size) +DN_API void DN_BinPackVarInt_(DN_BinPack *pack, DN_BinPackMode mode, void *item, DN_USize size) { DN_U64 value = 0; DN_AssertF(size <= sizeof(value), @@ -39,81 +39,92 @@ DN_API void DN_BinPack_VarInt_(DN_BinPack *pack, DN_BinPackMode mode, void *item if (mode == DN_BinPackMode_Serialise) // Read `item` into U64 `value` DN_Memcpy(&value, item, size); - DN_BinPack_U64(pack, mode, &value); + DN_BinPackU64(pack, mode, &value); if (mode == DN_BinPackMode_Deserialise) // Write U64 `value` into `item` DN_Memcpy(item, &value, size); } -DN_API void DN_BinPack_U32(DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item) +DN_API bool DN_BinPackIsEndOfReadStream(DN_BinPack const *pack) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + bool result = pack->read_index == pack->read.size; + return result; } -DN_API void DN_BinPack_U16(DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item) +DN_API void DN_BinPackUSize(DN_BinPack *pack, DN_BinPackMode mode, DN_USize *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_U8(DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item) +DN_API void DN_BinPackU32(DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_I64(DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item) +DN_API void DN_BinPackU16(DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_I32(DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item) +DN_API void DN_BinPackU8(DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_I16(DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item) +DN_API void DN_BinPackI64(DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_I8(DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item) +DN_API void DN_BinPackI32(DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_F64(DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item) +DN_API void DN_BinPackI16(DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_F32(DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item) +DN_API void DN_BinPackI8(DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); +} + +DN_API void DN_BinPackF64(DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item) +{ + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); +} + +DN_API void DN_BinPackF32(DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item) +{ + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } #if defined(DN_MATH_H) -DN_API void DN_BinPack_V2(DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item) +DN_API void DN_BinPackV2(DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item) { - DN_BinPack_F32(pack, mode, &item->x); - DN_BinPack_F32(pack, mode, &item->y); + DN_BinPackF32(pack, mode, &item->x); + DN_BinPackF32(pack, mode, &item->y); } -DN_API void DN_BinPack_V4(DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item) +DN_API void DN_BinPackV4(DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item) { - DN_BinPack_F32(pack, mode, &item->x); - DN_BinPack_F32(pack, mode, &item->y); - DN_BinPack_F32(pack, mode, &item->z); - DN_BinPack_F32(pack, mode, &item->w); + DN_BinPackF32(pack, mode, &item->x); + DN_BinPackF32(pack, mode, &item->y); + DN_BinPackF32(pack, mode, &item->z); + DN_BinPackF32(pack, mode, &item->w); } #endif -DN_API void DN_BinPack_Bool(DN_BinPack *pack, DN_BinPackMode mode, bool *item) +DN_API void DN_BinPackBool(DN_BinPack *pack, DN_BinPackMode mode, bool *item) { - DN_BinPack_VarInt_(pack, mode, item, sizeof(*item)); + DN_BinPackVarInt_(pack, mode, item, sizeof(*item)); } -DN_API void DN_BinPack_Str8FromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string) +DN_API void DN_BinPackStr8FromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string) { - DN_BinPack_VarInt_(pack, mode, &string->size, sizeof(string->size)); + DN_BinPackVarInt_(pack, mode, &string->size, sizeof(string->size)); if (mode == DN_BinPackMode_Serialise) { DN_Str8BuilderAppendBytesCopy(&pack->writer, string->data, string->size); } else { @@ -123,9 +134,9 @@ DN_API void DN_BinPack_Str8FromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPa } } -DN_API void DN_BinPack_Str8FromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string) +DN_API void DN_BinPackStr8FromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string) { - DN_BinPack_VarInt_(pack, mode, &string->size, sizeof(string->size)); + DN_BinPackVarInt_(pack, mode, &string->size, sizeof(string->size)); if (mode == DN_BinPackMode_Serialise) { DN_Str8BuilderAppendBytesCopy(&pack->writer, string->data, string->size); } else { @@ -135,25 +146,32 @@ DN_API void DN_BinPack_Str8FromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackM } } -DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size) +DN_API DN_Str8 DN_BinPackStr8FromBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max) +{ + DN_BinPackCBuffer(pack, mode, ptr, size, max); + DN_Str8 result = DN_Str8FromPtr(ptr, *size); + return result; +} + +DN_API void DN_BinPackBytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size) { DN_Str8 string = DN_Str8FromPtr(*ptr, *size); - DN_BinPack_Str8FromArena(pack, arena, mode, &string); + DN_BinPackStr8FromArena(pack, arena, mode, &string); *ptr = string.data; *size = string.size; } -DN_API void DN_BinPack_BytesFromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size) +DN_API void DN_BinPackBytesFromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size) { DN_Str8 string = DN_Str8FromPtr(*ptr, *size); - DN_BinPack_Str8FromPool(pack, pool, mode, &string); + DN_BinPackStr8FromPool(pack, pool, mode, &string); *ptr = string.data; *size = string.size; } -DN_API void DN_BinPack_CArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size) +DN_API void DN_BinPackCArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size) { - DN_BinPack_VarInt_(pack, mode, &size, sizeof(size)); + DN_BinPackVarInt_(pack, mode, &size, sizeof(size)); if (mode == DN_BinPackMode_Serialise) { DN_Str8BuilderAppendBytesCopy(&pack->writer, ptr, size); } else { @@ -164,7 +182,24 @@ DN_API void DN_BinPack_CArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr, } } -DN_API DN_Str8 DN_BinPack_Build(DN_BinPack const *pack, DN_Arena *arena) +DN_API void DN_BinPackCBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max) +{ + if (mode == DN_BinPackMode_Serialise) { + DN_BinPackUSize(pack, mode, size); + DN_Str8BuilderAppendBytesCopy(&pack->writer, ptr, *size); + } else { + DN_U64 size_u64 = 0; + DN_BinPackU64(pack, mode, &size_u64); + DN_Assert(size_u64 < DN_USIZE_MAX); + DN_Assert(size_u64 <= max); + + *size = DN_Min(size_u64, max); + DN_Memcpy(ptr, pack->read.data + pack->read_index, *size); + pack->read_index += size_u64; + } +} + +DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena) { DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena); return result; diff --git a/Source/Extra/dn_bin_pack.h b/Source/Extra/dn_bin_pack.h index 86864dd..3f678dd 100644 --- a/Source/Extra/dn_bin_pack.h +++ b/Source/Extra/dn_bin_pack.h @@ -22,26 +22,30 @@ struct DN_BinPack DN_USize read_index; }; -DN_API void DN_BinPack_U64 (DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item); -DN_API void DN_BinPack_U32 (DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item); -DN_API void DN_BinPack_U16 (DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item); -DN_API void DN_BinPack_U8 (DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item); -DN_API void DN_BinPack_I64 (DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item); -DN_API void DN_BinPack_I32 (DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item); -DN_API void DN_BinPack_I16 (DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item); -DN_API void DN_BinPack_I8 (DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item); -DN_API void DN_BinPack_F64 (DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item); -DN_API void DN_BinPack_F32 (DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item); -#if defined(DN_MATH_H) -DN_API void DN_BinPack_V2 (DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item); -DN_API void DN_BinPack_V4 (DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item); +DN_API bool DN_BinPackIsEndOfReadStream(DN_BinPack const *pack); +DN_API void DN_BinPackUSize (DN_BinPack *pack, DN_BinPackMode mode, DN_USize *item); +DN_API void DN_BinPackU64 (DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item); +DN_API void DN_BinPackU32 (DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item); +DN_API void DN_BinPackU16 (DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item); +DN_API void DN_BinPackU8 (DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item); +DN_API void DN_BinPackI64 (DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item); +DN_API void DN_BinPackI32 (DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item); +DN_API void DN_BinPackI16 (DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item); +DN_API void DN_BinPackI8 (DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item); +DN_API void DN_BinPackF64 (DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item); +DN_API void DN_BinPackF32 (DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item); +#if defined (DN_MATH_H) +DN_API void DN_BinPackV2 (DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item); +DN_API void DN_BinPackV4 (DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item); #endif -DN_API void DN_BinPack_Bool (DN_BinPack *pack, DN_BinPackMode mode, bool *item); -DN_API void DN_BinPack_Str8FromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string); -DN_API void DN_BinPack_Str8FromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string); -DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size); -DN_API void DN_BinPack_BytesFromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size); -DN_API void DN_BinPack_CArray (DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size); -DN_API DN_Str8 DN_BinPack_Build (DN_BinPack const *pack, DN_Arena *arena); +DN_API void DN_BinPackBool (DN_BinPack *pack, DN_BinPackMode mode, bool *item); +DN_API void DN_BinPackStr8FromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string); +DN_API void DN_BinPackStr8FromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string); +DN_API DN_Str8 DN_BinPackStr8FromBuffer (DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max); +DN_API void DN_BinPackBytesFromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size); +DN_API void DN_BinPackBytesFromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size); +DN_API void DN_BinPackCArray (DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size); +DN_API void DN_BinPackCBuffer (DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_USize *size, DN_USize max); +DN_API DN_Str8 DN_BinPackBuild (DN_BinPack const *pack, DN_Arena *arena); #endif // !defined(DN_BIN_PACK_H) diff --git a/Source/Extra/dn_math.cpp b/Source/Extra/dn_math.cpp index 6daead8..9d34f83 100644 --- a/Source/Extra/dn_math.cpp +++ b/Source/Extra/dn_math.cpp @@ -834,19 +834,19 @@ DN_API DN_V3F32 DN_V3_Normalise(DN_V3F32 a) DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32) { - DN_U8 r = (DN_U8)((u32 & DN_V4_R_MASK_U32) >> 24); - DN_U8 g = (DN_U8)((u32 & DN_V4_G_MASK_U32) >> 16); - DN_U8 b = (DN_U8)((u32 & DN_V4_B_MASK_U32) >> 8); + DN_U8 r = (DN_U8)((u32 & 0x00FF0000) >> 16); + DN_U8 g = (DN_U8)((u32 & 0x0000FF00) >> 8); + DN_U8 b = (DN_U8)((u32 & 0x000000FF) >> 0); DN_V4F32 result = DN_V4F32_FromRGBU8(r, g, b); return result; } DN_API DN_V4F32 DN_V4F32_FromRGBAU32(DN_U32 u32) { - DN_U8 r = (DN_U8)((u32 & DN_V4_R_MASK_U32) >> 24); - DN_U8 g = (DN_U8)((u32 & DN_V4_G_MASK_U32) >> 16); - DN_U8 b = (DN_U8)((u32 & DN_V4_B_MASK_U32) >> 8); - DN_U8 a = (DN_U8)((u32 & DN_V4_A_MASK_U32) >> 0); + DN_U8 r = (DN_U8)((u32 & 0xFF000000) >> 24); + DN_U8 g = (DN_U8)((u32 & 0x00FF0000) >> 16); + DN_U8 b = (DN_U8)((u32 & 0x0000FF00) >> 8); + DN_U8 a = (DN_U8)((u32 & 0x000000FF) >> 0); DN_V4F32 result = DN_V4F32_FromRGBAU8(r, g, b, a); return result; } diff --git a/Source/Extra/dn_math.h b/Source/Extra/dn_math.h index 9430b72..6d365d5 100644 --- a/Source/Extra/dn_math.h +++ b/Source/Extra/dn_math.h @@ -265,11 +265,6 @@ DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); -DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; -DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; -DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; -DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; - #define DN_V4F32_From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V4F32_From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} #define DN_V4F32_FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} diff --git a/Source/Extra/dn_net_curl.cpp b/Source/Extra/dn_net_curl.cpp index 58958d6..3dc910f 100644 --- a/Source/Extra/dn_net_curl.cpp +++ b/Source/Extra/dn_net_curl.cpp @@ -141,8 +141,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread) } DN_Assert(req->type == DN_NETRequestType_WS); - DN_Assert(req->response.state == DN_NETResponseState_WSOpen); - DN_Assert(DN_NET_CurlRequestIsInList(curl->thread_request_list, req)); + DN_Assert(req->response.state >= DN_NETResponseState_WSOpen && req->response.state <= DN_NETResponseState_WSPong); DN_USize sent = 0; CURLcode send_result = curl_ws_send(curl_req->handle, payload.data, payload.size, &sent, 0, curlws_flag); diff --git a/Source/Extra/dn_net_emscripten.cpp b/Source/Extra/dn_net_emscripten.cpp index d46e1e1..fa6fc9d 100644 --- a/Source/Extra/dn_net_emscripten.cpp +++ b/Source/Extra/dn_net_emscripten.cpp @@ -21,7 +21,6 @@ struct DN_NETEmcWSEvent struct DN_NETEmcCore { DN_Pool pool; - DN_NETRequest *request_list; // Current requests being executed DN_NETRequest *response_list; // Responses received that are to be deqeued via wait for response DN_NETRequest *free_list; // Request pool that new requests will use before allocating }; @@ -51,6 +50,7 @@ static DN_NETEmcWSEvent *DN_NET_EmcAllocWSEvent_(DN_NETRequest *request) // NOTE: Allocate the event and attach to the request DN_NETEmcRequest *emc_request = DN_Cast(DN_NETEmcRequest *) request->context[1]; DN_NETEmcWSEvent *result = DN_ArenaNew(&request->arena, DN_NETEmcWSEvent, DN_ZMem_Yes); + DN_Assert(result); if (result) { if (!emc_request->first_event) emc_request->first_event = result; @@ -63,17 +63,23 @@ static DN_NETEmcWSEvent *DN_NET_EmcAllocWSEvent_(DN_NETRequest *request) static void DN_NET_EmcOnRequestDone_(DN_NETCore *net, DN_NETRequest *request) { - // NOTE: This may be call multiple times if we get multiple responses when we yield to the javascript event loop - if (!request->next) { - DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context; - request->next = emc->response_list; + // NOTE: This may be call multiple times on the same request if we get multiple responses when we + // yield to the javascript event loop, e.g. the application received multiple WS payloads before + // it waited and consequently consumed the response from the payload. + // + // So if the next pointer is already set, then it should be that the request is already enqueued. + DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context; + if (!request->next && !request->prev && request != emc->response_list) { + request->prev = nullptr; + request->next = emc->response_list; + if (emc->response_list) + emc->response_list->prev = request; emc->response_list = request; } DN_OS_SemaphoreIncrement(&net->completion_sem, 1); DN_OS_SemaphoreIncrement(&request->completion_sem, 1); } -// TODO: Need to enqueue the results since they can accumulate when you yield to the javascript event loop static bool DN_NET_EmcWSOnOpen(int eventType, EmscriptenWebSocketOpenEvent const *event, void *user_data) { DN_NETRequest *req = DN_Cast(DN_NETRequest *) user_data; @@ -90,10 +96,8 @@ static bool DN_NET_EmcWSOnMessage(int eventType, const EmscriptenWebSocketMessag DN_NETCore *net = DN_Cast(DN_NETCore *) req->context[0]; DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req); net_event->state = event->isText ? DN_NETResponseState_WSText : DN_NETResponseState_WSBinary; - if (event->numBytes > 0) { - DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context; - net_event->payload = DN_Str8FromPtrPool(&emc->pool, event->data, event->numBytes); - } + if (event->numBytes > 0) + net_event->payload = DN_Str8FromPtrArena(&req->arena, event->data, event->numBytes); DN_NET_EmcOnRequestDone_(net, req); return true; } @@ -112,10 +116,9 @@ static bool DN_NET_EmcWSOnClose(int eventType, EmscriptenWebSocketCloseEvent con { DN_NETRequest *req = DN_Cast(DN_NETRequest *) user_data; DN_NETCore *net = DN_Cast(DN_NETCore *) req->context[0]; - DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context; DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req); net_event->state = DN_NETResponseState_WSClose; - net_event->payload = DN_Str8FromFmtPool(&emc->pool, "Websocket closed '%.*s': (%u) %s (was %s close)", DN_Str8PrintFmt(req->url), event->code, event->reason, event->wasClean ? "clean" : "unclean"); + net_event->payload = DN_Str8FromFmtArena(&req->arena, "Websocket closed '%.*s': (%u) %s (was %s close)", DN_Str8PrintFmt(req->url), event->code, event->reason, event->wasClean ? "clean" : "unclean"); DN_NET_EmcOnRequestDone_(net, req); return true; } @@ -157,22 +160,38 @@ void DN_NET_EmcDeinit(DN_NETCore *net) // TODO: Track all the request handles and clean it up } -DN_NETRequestHandle DN_NET_EmcDoHTTP(DN_NETCore *net, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args) +static DN_NETRequest *DN_NET_EmcAllocRequest_(DN_NETCore *net) { // NOTE: Allocate request DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context; - DN_NETRequest *req = emc->free_list; - if (req) { + DN_NETRequest *result = emc->free_list; + if (result) { emc->free_list = emc->free_list->next; - req->next = nullptr; + result->next = nullptr; + DN_Assert(result->prev == nullptr); + if (emc->free_list) { + DN_Assert(emc->free_list->prev == nullptr); + } } else { - req = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes); + // NOTE: Setup the request's arena here. WASM doesn't have the concept of virtual memory + // so we use malloc to initialise it. + result = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes); + if (result) + result->arena = DN_ArenaFromHeap(DN_Megabytes(1), DN_ArenaFlags_Nil); } - DN_NETRequestHandle result = DN_NET_SetupRequest_(req, url, method, args, DN_NETRequestType_HTTP); - // NOTE: Setup some emscripten specific data into our request context - req->context[0] = DN_Cast(DN_UPtr) net; + if (result) { + result->context[0] = DN_Cast(DN_UPtr) net; + } + + return result; +} + +DN_NETRequestHandle DN_NET_EmcDoHTTP(DN_NETCore *net, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args) +{ + DN_NETRequest *req = DN_NET_EmcAllocRequest_(net); + DN_NETRequestHandle result = DN_NET_SetupRequest_(req, url, method, args, DN_NETRequestType_HTTP); // NOTE: Setup the HTTP request via Emscripten emscripten_fetch_attr_t fetch_attribs = {}; @@ -236,23 +255,12 @@ DN_NETRequestHandle DN_NET_EmcDoHTTP(DN_NETCore *net, DN_Str8 url, DN_Str8 metho DN_NETRequestHandle DN_NET_EmcDoWS(DN_NETCore *net, DN_Str8 url) { DN_Assert(emscripten_websocket_is_supported()); - - // NOTE: Allocate request - DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context; - DN_NETRequest *req = emc->free_list; - if (req) { - emc->free_list = emc->free_list->next; - req->next = nullptr; - } else { - req = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes); - } - + DN_NETRequest *req = DN_NET_EmcAllocRequest_(net); DN_NETRequestHandle result = DN_NET_SetupRequest_(req, url, /*method=*/DN_Str8Lit(""), /*args=*/nullptr, DN_NETRequestType_WS); if (!req) return result; // NOTE: Setup some emscripten specific data into our request context - req->context[0] = DN_Cast(DN_UPtr) net; req->context[1] = DN_Cast(DN_UPtr) DN_ArenaNew(&req->arena, DN_NETEmcRequest, DN_ZMem_Yes); req->start_response_arena_pos = DN_ArenaPos(&req->arena); @@ -307,44 +315,79 @@ void DN_NET_EmcDoWSSend(DN_NETRequestHandle handle, DN_Str8 data, DN_NETWSSend s static DN_NETResponse DN_NET_EmcHandleFinishedRequest_(DN_NETCore *net, DN_NETEmcCore *emc, DN_NETRequestHandle handle, DN_NETRequest *request, DN_Arena *arena) { // NOTE: Generate the response, copy out the strings into the user given memory - DN_NETResponse result = request->response; - bool end_request = true; + DN_NETEmcRequest *emc_request = DN_Cast(DN_NETEmcRequest *) request->context[1]; + DN_NETResponse result = request->response; + bool end_request = true; + bool dequeue_request = true; if (request->type == DN_NETRequestType_HTTP) { result.body = DN_Str8FromStr8Arena(arena, result.body); } else { // NOTE: Get emscripten contexts - DN_NETEmcRequest *emc_request = DN_Cast(DN_NETEmcRequest *) request->context[1]; - DN_NETEmcWSEvent *emc_event = emc_request->first_event; - emc_request->first_event = emc_event->next; // Advance the list pointer + DN_NETEmcWSEvent *emc_event = emc_request->first_event; DN_Assert(emc_event); - DN_Assert((emc_event->state >= DN_NETResponseState_WSOpen && emc_event->state <= DN_NETResponseState_WSPong) || - emc_event->state == DN_NETResponseState_Error); + + DN_AssertF((emc_event->state >= DN_NETResponseState_WSOpen && emc_event->state <= DN_NETResponseState_WSPong) || emc_event->state == DN_NETResponseState_Error, + "emc_event=%p", emc_event); // NOTE: Build the result result.state = emc_event->state; result.request = handle; result.body = DN_Str8FromStr8Arena(arena, emc_event->payload); + // NOTE: Advance the event list + { + if (emc_request->first_event == emc_request->last_event) { + emc_request->last_event = emc_request->last_event->next; + DN_Assert(emc_request->first_event->next == emc_request->last_event); + } + emc_request->first_event = emc_event->next; - // NOTE: Free the payload which is stored in the Emscripten pool - if (emc_event->payload.size) { - DN_PoolDealloc(&emc->pool, emc_event->payload.data); - emc_event->payload = {}; + // NOTE: If there's still an event on the request then we do not dequeue the request from the + // response list. The user can still "wait" for a response to read more data from it. + if (emc_request->first_event) + dequeue_request = false; } if (result.state != DN_NETResponseState_WSClose) end_request = false; } - // NOTE: Deallocate the memory used in the request and reset the string builder - DN_ArenaPopTo(&request->arena, 0); + // NOTE: Remove request from the response list which is doubly-linked + if (dequeue_request) { + if (request->prev) { + DN_AssertF(request->prev->next == request, "next=%p vs request=%p", request->prev->next, request); + request->prev->next = request->next; + } + + if (request->next) { + DN_AssertF(request->next->prev == request, "prev=%p vs request=%p", request->next->prev, request); + request->next->prev = request->prev; + } + + if (request == emc->response_list) + emc->response_list = emc->response_list->next; + + request->prev = nullptr; + request->next = nullptr; + DN_Assert(emc_request->first_event == nullptr); + DN_Assert(emc_request->last_event == nullptr); + + // NOTE: Deallocate the memory used in the request and reset the string builder (as all + // payload(s) have been read from the request). + if (end_request) + DN_ArenaPopTo(&request->arena, 0); + else + DN_ArenaPopTo(&request->arena, request->start_response_arena_pos); + } + if (end_request) { DN_NET_EndFinishedRequest_(request); - DN_NETEmcRequest *emc_request = DN_Cast(DN_NETEmcRequest *) request->context[1]; emscripten_websocket_delete(emc_request->socket); + emc_request->socket = 0; DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context; - request->next = emc->free_list; + request->next = emc->free_list; + request->prev = nullptr; emc->free_list = request; } @@ -381,7 +424,7 @@ static DN_OSSemaphoreWaitResult DN_NET_EmcSemaphoreWait_(DN_OSSemaphore *sem, DN DN_NETResponse DN_NET_EmcWaitForResponse(DN_NETRequestHandle handle, DN_Arena *arena, DN_U32 timeout_ms) { - DN_NETResponse result = {}; + DN_NETResponse result = {}; DN_NETRequest *request_ptr = DN_Cast(DN_NETRequest *) handle.handle; if (request_ptr && request_ptr->gen == handle.gen) { DN_NETCore *net = DN_Cast(DN_NETCore *) request_ptr->context[0]; @@ -391,10 +434,7 @@ DN_NETResponse DN_NET_EmcWaitForResponse(DN_NETRequestHandle handle, DN_Arena *a if (wait != DN_OSSemaphoreWaitResult_Success) return result; - // NOTE: Remove request from the done list - request_ptr->next = nullptr; - emc->response_list = emc->response_list->next; - result = DN_NET_EmcHandleFinishedRequest_(net, emc, handle, request_ptr, arena); + result = DN_NET_EmcHandleFinishedRequest_(net, emc, handle, request_ptr, arena); // NOTE: Decrement the global 'request done' completion semaphore since the user consumed the // request individually. @@ -414,16 +454,12 @@ DN_NETResponse DN_NET_EmcWaitForAnyResponse(DN_NETCore *net, DN_Arena *arena, DN if (wait != DN_OSSemaphoreWaitResult_Success) return result; - // NOTE: Dequeue the request that is done from the done list DN_AssertF(emc->response_list, "This should be set otherwise we bumped the completion sem without queueing into the " "done list or we forgot to wait on the global semaphore after a request finished"); - DN_NETRequest *request_ptr = emc->response_list; - DN_Assert(request_ptr == emc->response_list); - request_ptr->next = nullptr; - emc->response_list = emc->response_list->next; // NOTE: Decrement the request's completion semaphore since the user consumed the global semaphore + DN_NETRequest *request_ptr = emc->response_list; DN_OSSemaphoreWaitResult net_wait_result = DN_OS_SemaphoreWait(&request_ptr->completion_sem, 0 /*timeout_ms*/); DN_AssertF(net_wait_result == DN_OSSemaphoreWaitResult_Success, "Wait result was: %zu", DN_Cast(DN_USize) net_wait_result); diff --git a/Source/Extra/dn_tests_main.cpp b/Source/Extra/dn_tests_main.cpp index 60256cd..4e08c58 100644 --- a/Source/Extra/dn_tests_main.cpp +++ b/Source/Extra/dn_tests_main.cpp @@ -42,7 +42,7 @@ DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider int main(int, char**) { DN_Core core = {}; - DN_Init(&core, DN_InitFlags_LogAllFeatures, nullptr); + DN_Init(&core, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS, nullptr); DN_Tests_RunSuite(DN_TestsPrint_Yes); return 0; } diff --git a/Source/OS/dn_os_posix.cpp b/Source/OS/dn_os_posix.cpp index 6ae9f59..2630950 100644 --- a/Source/OS/dn_os_posix.cpp +++ b/Source/OS/dn_os_posix.cpp @@ -28,6 +28,10 @@ static DN_U32 DN_OS_MemConvertPageToOSFlags_(DN_U32 protect) DN_API void *DN_OS_MemReserve(DN_USize size, DN_MemCommit commit, DN_U32 page_flags) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory, you should use DN_OS_MemAlloc"); + #endif + unsigned long os_page_flags = DN_OS_MemConvertPageToOSFlags_(page_flags); if (commit == DN_MemCommit_Yes) @@ -43,6 +47,9 @@ DN_API void *DN_OS_MemReserve(DN_USize size, DN_MemCommit commit, DN_U32 page_fl DN_API bool DN_OS_MemCommit(void *ptr, DN_USize size, DN_U32 page_flags) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory"); + #endif bool result = false; if (!ptr || size == 0) return false; @@ -56,17 +63,26 @@ DN_API bool DN_OS_MemCommit(void *ptr, DN_USize size, DN_U32 page_flags) DN_API void DN_OS_MemDecommit(void *ptr, DN_USize size) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory"); + #endif mprotect(ptr, size, PROT_NONE); madvise(ptr, size, MADV_FREE); } DN_API void DN_OS_MemRelease(void *ptr, DN_USize size) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory"); + #endif munmap(ptr, size); } DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags) { + #if defined(DN_PLATFORM_EMSCRIPTEN) + DN_InvalidCodePathF("Emscripten does not support virtual memory"); + #endif if (!ptr || size == 0) return 0; @@ -151,7 +167,8 @@ DN_API DN_U64 DN_OS_DateUnixTimeSFromLocalDate(DN_Date date) DN_API DN_U64 DN_OS_DateLocalUnixTimeSFromUnixTimeS(DN_U64 unix_ts_s) { struct tm tm_local; - void *ret = localtime_r(&unix_ts_s, &tm_local); + time_t unix_ts = unix_ts_s; + void *ret = localtime_r(&unix_ts, &tm_local); DN_Assert(ret); long local_offset_seconds = tm_local.tm_gmtoff; diff --git a/Source/OS/dn_os_tls.cpp b/Source/OS/dn_os_tls.cpp index b5cefb3..74fd333 100644 --- a/Source/OS/dn_os_tls.cpp +++ b/Source/OS/dn_os_tls.cpp @@ -32,9 +32,12 @@ DN_API void DN_OS_TLSInit(DN_OSTLS *tls, DN_OSTLSInitArgs args) return; DN_U64 reserve = args.reserve ? args.reserve : DN_Kilobytes(64); - DN_U64 commit = args.commit ? args.commit : DN_Kilobytes(4); DN_U64 err_sink_reserve = args.err_sink_reserve ? args.err_sink_reserve : DN_Kilobytes(64); + + #if !defined(DN_PLATFORM_EMSCRIPTEN) + DN_U64 commit = args.commit ? args.commit : DN_Kilobytes(4); DN_U64 err_sink_commit = args.err_sink_commit ? args.err_sink_commit : DN_Kilobytes(4); + #endif // TODO: We shouldn't have the no alloc track flag here but the initial TLS // init on OS init happens before CORE init. CORE init is the one responsible @@ -42,8 +45,22 @@ DN_API void DN_OS_TLSInit(DN_OSTLS *tls, DN_OSTLSInitArgs args) for (DN_ForItCArray(it, DN_Arena, tls->arenas)) { DN_Arena *arena = it.data; switch (DN_Cast(DN_OSTLSArena) it.index) { - default: *arena = DN_ArenaFromVMem(reserve, commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break; - case DN_OSTLSArena_ErrorSink: *arena = DN_ArenaFromVMem(err_sink_reserve, err_sink_commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break; + default: { + #if defined(DN_PLATFORM_EMSCRIPTEN) + *arena = DN_ArenaFromHeap(reserve, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); + #else + *arena = DN_ArenaFromVMem(reserve, commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); + #endif + } break; + + case DN_OSTLSArena_ErrorSink: { + #if defined(DN_PLATFORM_EMSCRIPTEN) + *arena = DN_ArenaFromHeap(err_sink_reserve, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); + #else + *arena = DN_ArenaFromVMem(err_sink_reserve, err_sink_commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); + #endif + } break; + case DN_OSTLSArena_Count: DN_InvalidCodePath; break; } } diff --git a/project.rdbg b/project.rdbg index 4654071..f4a2cd9 100644 --- a/project.rdbg +++ b/project.rdbg @@ -1,2 +1,19 @@ // raddbg 0.9.25 project file +recent_file: path: "Source/OS/dn_os_w32.cpp" +target: +{ + executable: "Build/dn_unit_tests_msvc.exe" + working_directory: "Build/" + enabled: 1 +} +debug_info: +{ + path: "C:/Home/Code/DN/Build/dn_unit_tests_msvc.pdb" + timestamp: 66199776062119 +} +debug_info: +{ + path: "C:/Home/Cloud/Dev/Win/msvc/msvc_host_x64_target_x64/14.41.17.11/VC/Tools/MSVC/14.41.34120/bin/Hostx64/x64/clang_rt.asan_dynamic-x86_64.pdb" + timestamp: 66163731918117 +}