Port changes from SolidPP
This commit is contained in:
@@ -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;
|
||||
|
||||
+24
-20
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user