diff --git a/Source/Base/dn_base.cpp b/Source/Base/dn_base.cpp index 0597dc0..2866353 100644 --- a/Source/Base/dn_base.cpp +++ b/Source/Base/dn_base.cpp @@ -1154,7 +1154,8 @@ DN_API DN_Str8x64 DN_ArenaInfoStr8x64(DN_ArenaInfo info) DN_Str8x32 used = DN_ByteCountStr8x32(info.used); DN_Str8x32 commit = DN_ByteCountStr8x32(info.commit); DN_Str8x32 reserve = DN_ByteCountStr8x32(info.reserve); - result = DN_Str8x64FromFmt("Blks/Used/Comm/Resv (%u/%.*s/%.*s/%.*s)", DN_Cast(DN_U32)info.blocks, DN_Str8PrintFmt(used), DN_Str8PrintFmt(commit), DN_Str8PrintFmt(reserve)); + // NOTE: Blocks, Used, Commit, Reserve + result = DN_Str8x64FromFmt("B=%u U=%.*s C=%.*s R=%.*s", DN_Cast(DN_U32)info.blocks, DN_Str8PrintFmt(used), DN_Str8PrintFmt(commit), DN_Str8PrintFmt(reserve)); return result; } @@ -1533,7 +1534,10 @@ DN_API void DN_ErrSinkEndExitIfErrorF_(DN_ErrSink *err, DN_CallSite call_site, D DN_API void DN_ErrSinkAppendFV_(DN_ErrSink *err, DN_U32 error_code, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args) { - DN_Assert(err && err->stack_size); + if (!err) + return; + + DN_Assert(err->stack_size); DN_ErrSinkNode *node = err->stack + (err->stack_size - 1); DN_AssertF(node, "Error sink must be begun by calling 'Begin' before using this function."); @@ -1613,7 +1617,7 @@ DN_API DN_Arena *DN_TCMainArena() return result; } -DN_API DN_Arena *DN_TCTempArena(DN_Arena **conflicts, DN_U64 count) +DN_API DN_Arena *DN_TCTempArena(DN_Arena **conflicts, DN_USize count) { DN_TCCore *tc = DN_TCGet(); DN_Arena *candidates[] = {tc->temp_a_arena, tc->temp_b_arena}; @@ -1647,7 +1651,7 @@ DN_TCScratchCpp::~DN_TCScratchCpp() } #endif -DN_API DN_TCScratch DN_TCScratchBegin(DN_Arena **conflicts, DN_U64 count) +DN_API DN_TCScratch DN_TCScratchBegin(DN_Arena **conflicts, DN_USize count) { DN_TCScratch result = {}; result.arena = DN_TCTempArena(conflicts, count); @@ -3228,7 +3232,7 @@ DN_API DN_Str8Slice DN_Str8BuilderBuildSlice(DN_Str8Builder const *builder, DN_A } // NOTE: DN_UTF -DN_API int DN_UTF8EncodeCodepoint(DN_U8 utf8[4], DN_U32 codepoint) +DN_API int DN_UTF8Encode(DN_U8 utf8[4], DN_U32 codepoint) { // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ // ----------------------------------------+----------------------------+--------------------+ @@ -3269,7 +3273,96 @@ DN_API int DN_UTF8EncodeCodepoint(DN_U8 utf8[4], DN_U32 codepoint) return 0; } -DN_API int DN_UTF16EncodeCodepoint(DN_U16 utf16[2], DN_U32 codepoint) +DN_API DN_UTF8DecodeResult DN_UTF8Decode(DN_Str8 stream) +{ + DN_UTF8DecodeResult result = {}; + result.remaining = stream; + if (stream.size <= 0) + return result; + + DN_U8 b0 = DN_Cast(DN_U8)stream.data[0]; + DN_U8 b1 = DN_Cast(DN_U8)(stream.size >= 2 ? stream.data[1] : 0); + DN_U8 b2 = DN_Cast(DN_U8)(stream.size >= 3 ? stream.data[2] : 0); + DN_U8 b3 = DN_Cast(DN_U8)(stream.size >= 4 ? stream.data[3] : 0); + + if ((b0 & 0b1000'0000) == 0) { + result.codepoint = b0; + result.success = true; + result.remaining = DN_Str8FromPtr(stream.data + 1, stream.size - 1); + return result; + } + + if ((b0 & 0b1110'0000) == 0b1100'0000) { + if (stream.size < 2) + return result; + if ((b1 & 0b1100'0000) != 0b1000'0000) + return result; + DN_U32 cp = ((b0 & 0b0001'1111) << 6) | ((b1 & 0b0011'1111) << 0); + if (cp < 0x80) + return result; + result.codepoint = cp; + result.success = true; + result.remaining = DN_Str8FromPtr(stream.data + 2, stream.size - 2); + return result; + } + + if ((b0 & 0b1111'0000) == 0b1110'0000) { + if (stream.size < 3) + return result; + if ((b1 & 0b1100'0000) != 0b1000'0000) + return result; + if ((b2 & 0b1100'0000) != 0b1000'0000) + return result; + DN_U32 cp = ((b0 & 0b0000'1111) << 12) | ((b1 & 0b0011'1111) << 6) | ((b2 & 0b0011'1111) << 0); + if (cp < 0x800) + return result; + result.codepoint = cp; + result.success = true; + result.remaining = DN_Str8FromPtr(stream.data + 3, stream.size - 3); + return result; + } + + if ((b0 & 0b1111'1000) == 0b1111'0000) { + if (stream.size < 4) + return result; + if ((b1 & 0b1100'0000) != 0b1000'0000) + return result; + if ((b2 & 0b1100'0000) != 0b1000'0000) + return result; + if ((b3 & 0b1100'0000) != 0b1000'0000) + return result; + DN_U32 cp = ((b0 & 0b0000'0111) << 18) | + ((b1 & 0b0011'1111) << 12) | + ((b2 & 0b0011'1111) << 6) | + ((b3 & 0b0011'1111) << 0); + if (cp < 0x10000 || cp > 0x10FFFF) + return result; + result.codepoint = cp; + result.success = true; + result.remaining = DN_Str8FromPtr(stream.data + 4, stream.size - 4); + return result; + } + + return result; +} + +DN_API bool DN_UTF8DecodeIterate(DN_UTF8DecodeIterator *it, DN_Str8 utf8) +{ + if (it->init) { + it->codepoint_index++; + } else { + it->remaining = utf8; + it->init = true; + } + DN_UTF8DecodeResult decode = DN_UTF8Decode(it->remaining); + it->success = decode.success; + it->remaining = decode.remaining; + it->codepoint = decode.codepoint; + bool result = it->success; + return result; +} + +DN_API int DN_UTF16Encode(DN_U16 utf16[2], DN_U32 codepoint) { // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ // ----------------------------------------+------------------------------------+------------------+ @@ -4286,6 +4379,36 @@ DN_API DN_LogTypeParam DN_LogTypeParamFromType(DN_LogType type) return result; } +DN_API DN_F32 DN_F32Lerp(DN_F32 a, DN_F32 t, DN_F32 b) +{ + DN_F32 result = a + ((b - a) * t); + return result; +} + +DN_API DN_F32 DN_F32Floor(DN_F32 val) +{ + DN_I32 val_i32 = DN_Cast(DN_I32) val; + if (val < 0 && val != DN_Cast(DN_F32) val_i32) + val_i32 -= 1; + DN_F32 result = DN_Cast(DN_F32)val_i32; + return result; +} + +DN_API DN_F32 DN_F32Ceil(DN_F32 val) +{ + DN_I32 val_i32 = DN_Cast(DN_I32)(val); + if (val > 0 && val != DN_Cast(DN_F32) val_i32) + val_i32 += 1; + DN_F32 result = DN_Cast(DN_F32) val_i32; + return result; +} + +DN_API DN_F32 DN_F32RoundHalfUp(DN_F32 val) +{ + DN_F32 result = val >= 0 ? DN_F32Floor(val + 0.5f) : DN_F32Ceil(val - 0.5f); + return result; +} + DN_API bool operator==(DN_V2I32 lhs, DN_V2I32 rhs) { bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y); @@ -4574,6 +4697,14 @@ DN_API DN_V2U16 &operator+=(DN_V2U16 &lhs, DN_V2U16 rhs) return lhs; } +DN_API DN_V2F32 DN_V2F32Lerp(DN_V2F32 a, DN_F32 t, DN_V2F32 b) +{ + DN_V2F32 result = {}; + result.x = a.x + ((b.x - a.x) * t); + result.y = a.y + ((b.y - a.y) * t); + return result; +} + DN_API bool operator!=(DN_V2F32 lhs, DN_V2F32 rhs) { bool result = !(lhs == rhs); @@ -5094,6 +5225,15 @@ DN_API DN_V3F32 &operator+=(DN_V3F32 &lhs, DN_V3F32 rhs) return lhs; } +DN_API DN_V3F32 DN_V3F32Lerp(DN_V3F32 lhs, DN_F32 t01, DN_V3F32 rhs) +{ + DN_V3F32 result = {}; + result.x = lhs.x + ((rhs.x - lhs.x) * t01); + result.y = lhs.y + ((rhs.y - lhs.y) * t01); + result.z = lhs.z + ((rhs.z - lhs.z) * t01); + return result; +} + DN_API DN_F32 DN_V3_LengthSq(DN_V3F32 a) { DN_F32 result = DN_Squared(a.x) + DN_Squared(a.y) + DN_Squared(a.z); @@ -5114,22 +5254,78 @@ DN_API DN_V3F32 DN_V3_Normalise(DN_V3F32 a) return result; } -DN_API DN_V4F32 DN_V4F32FromRGBU32(DN_U32 u32) +DN_API DN_V4F32 DN_V4F32Lerp(DN_V4F32 lhs, DN_F32 t01, DN_V4F32 rhs) +{ + DN_V4F32 result = {}; + result.x = lhs.x + (rhs.x - lhs.x) * t01; + result.y = lhs.y + (rhs.y - lhs.y) * t01; + result.z = lhs.z + (rhs.z - lhs.z) * t01; + result.w = lhs.w + (rhs.w - lhs.w) * t01; + return result; +} + +DN_API bool DN_V4F32RGBA01IsValid(DN_V4F32 rgba01) +{ + bool result = rgba01.r >= 0 && rgba01.r <= 1.f && + rgba01.g >= 0 && rgba01.g <= 1.f && + rgba01.b >= 0 && rgba01.b <= 1.f && + rgba01.a >= 0 && rgba01.a <= 1.f; + return result; +} + +DN_API DN_V4F32 DN_V4F32RGBA01FromRGBU32(DN_U32 u32) { 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_V4F32FromRGBU8(r, g, b); + DN_V4F32 result = DN_V4F32RGBA01FromRGBU8(r, g, b); return result; } -DN_API DN_V4F32 DN_V4F32FromRGBAU32(DN_U32 u32) +DN_API DN_V4F32 DN_V4F32RGBA01FromRGBAU32(DN_U32 u32) { 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_V4F32FromRGBAU8(r, g, b, a); + DN_V4F32 result = DN_V4F32RGBA01FromRGBAU8(r, g, b, a); + return result; +} + +#define DN_SRGB_COEFFICIENT_F32 2.2f +DN_API DN_V4F32 DN_V4F32Linear01FromSRGB01(DN_V4F32 srgb01) +{ + DN_Assert(srgb01.x >= 0.f && srgb01.x <= 1.f); + DN_Assert(srgb01.y >= 0.f && srgb01.y <= 1.f); + DN_Assert(srgb01.z >= 0.f && srgb01.z <= 1.f); + DN_Assert(srgb01.a >= 0.f && srgb01.a <= 1.f); + DN_V4F32 result = {}; + result.r = DN_PowF32(srgb01.r, DN_SRGB_COEFFICIENT_F32); + result.g = DN_PowF32(srgb01.g, DN_SRGB_COEFFICIENT_F32); + result.b = DN_PowF32(srgb01.b, DN_SRGB_COEFFICIENT_F32); + result.a = srgb01.a; + return result; +} + +DN_API DN_V4F32 DN_V4F32Linear01Desaturate(DN_V4F32 linear01, DN_F32 t01) +{ + DN_F32 luminance = (linear01.r * DN_V3F32_RGB_LUMINANCE.r) + (linear01.g * DN_V3F32_RGB_LUMINANCE.g) + (linear01.b * DN_V3F32_RGB_LUMINANCE.b); + DN_V4F32 result = linear01; + result.rgb = DN_V3F32Lerp(result.rgb, t01, DN_V3F32From1N(luminance)); + return result; +} + +DN_API DN_V4F32 DN_V4F32SRGB01FromLinear01(DN_V4F32 linear01) +{ + DN_Assert(linear01.x >= 0.f && linear01.x <= 1.f); + DN_Assert(linear01.y >= 0.f && linear01.y <= 1.f); + DN_Assert(linear01.z >= 0.f && linear01.z <= 1.f); + DN_Assert(linear01.a >= 0.f && linear01.a <= 1.f); + DN_V4F32 result = {}; + result.r = DN_PowF32(linear01.r, 1.f / DN_SRGB_COEFFICIENT_F32); + result.g = DN_PowF32(linear01.g, 1.f / DN_SRGB_COEFFICIENT_F32); + result.b = DN_PowF32(linear01.b, 1.f / DN_SRGB_COEFFICIENT_F32); + result.a = linear01.a; return result; } @@ -5554,16 +5750,80 @@ DN_API DN_M2x3 DN_M2x3Scale(DN_V2F32 scale) DN_API DN_M2x3 DN_M2x3Rotate(DN_F32 radians) { - DN_M2x3 result = { - { - DN_CosF32(radians), - DN_SinF32(radians), - 0, - -DN_SinF32(radians), - DN_CosF32(radians), - 0, - } - }; + DN_M2x3 result = {{ + DN_CosF32(radians), DN_SinF32(radians), 0, + -DN_SinF32(radians), DN_CosF32(radians), 0, + }}; + return result; +} + +DN_API DN_M2x3 DN_M2x3ProjFromV2F32(DN_V2F32 size, DN_M2x3ProjOrigin origin) +{ + DN_M2x3 result = {}; + + // NOTE: Maps coordinates within a rectangle of `size` into NDC where (-1, +1) is top left, (+1, -1) is bot right + if (origin == DN_M2x3ProjOrigin_TopLeft) { + result = {{ + 2.f/size.w, 0, -1.f, + 0, -2.f/size.h, +1.f, + }}; + } else { + DN_Assert(origin == DN_M2x3ProjOrigin_Center); + result = {{ + 2.f/size.w, 0, 0.f, + 0, -2.f/size.h, 0.f, + }}; + } + return result; +} + +DN_API DN_M2x3XForm DN_M2x3XFormFromM2x3(DN_M2x3 forward, DN_M2x3 inverse) +{ + DN_M2x3XForm result = {}; + result.forward = forward; + result.inverse = inverse; + return result; +} + +DN_API DN_M2x3XForm DN_M2x3XFormFromTRS(DN_V2F32 pos, DN_V2F32 scale, DN_F32 rotate_rads, DN_V2F32 pivot_pos) +{ + DN_M2x3XForm result = {}; + result.forward = DN_M2x3Identity(); + result.inverse = DN_M2x3Identity(); + + if (scale.x == 0) + scale.x = 1; + if (scale.y == 0) + scale.y = 1; + + result.forward = DN_M2x3Mul(result.forward, DN_M2x3Translate(pivot_pos)); + result.forward = DN_M2x3Mul(result.forward, DN_M2x3Rotate(rotate_rads)); + result.forward = DN_M2x3Mul(result.forward, DN_M2x3Scale(scale)); + result.forward = DN_M2x3Mul(result.forward, DN_M2x3Translate(-pivot_pos)); + result.forward = DN_M2x3Mul(result.forward, DN_M2x3Translate(pos)); + + DN_V2F32 inverse_scale = DN_V2F32From1N(1) / scale; + result.inverse = DN_M2x3Mul(result.inverse, DN_M2x3Translate(-pos)); + result.inverse = DN_M2x3Mul(result.inverse, DN_M2x3Translate(pivot_pos)); + result.inverse = DN_M2x3Mul(result.inverse, DN_M2x3Scale(inverse_scale)); + result.inverse = DN_M2x3Mul(result.inverse, DN_M2x3Rotate(-rotate_rads)); + result.inverse = DN_M2x3Mul(result.inverse, DN_M2x3Translate(-pivot_pos)); + return result; +} + +DN_API DN_M2x3XForm DN_M2x3XFormIdentity() +{ + DN_M2x3XForm result = {}; + result.forward = DN_M2x3Identity(); + result.inverse = DN_M2x3Identity(); + return result; +} + +DN_API DN_M2x3XForm DN_M2x3XFormMul(DN_M2x3XForm m1, DN_M2x3XForm m2) +{ + DN_M2x3XForm result = {}; + result.forward = DN_M2x3Mul(m1.forward, m2.forward); + result.inverse = DN_M2x3Mul(m2.inverse, m1.inverse); return result; } @@ -5616,6 +5876,16 @@ DN_API DN_V2F32 DN_M2x3MulV2F32(DN_M2x3 m1, DN_V2F32 v2) return result; } +DN_API DN_Rect DN_M2x3MulRect(DN_M2x3 m1, DN_Rect rect) +{ + DN_2V2F32 rect_range = DN_RectRange(rect); + DN_2V2F32 result_range = {}; + result_range.min = DN_M2x3MulV2F32(m1, rect_range.min); + result_range.max = DN_M2x3MulV2F32(m1, rect_range.max); + DN_Rect result = DN_RectFrom2V2(result_range.min, result_range.max - result_range.min); + return result; +} + DN_API bool operator==(const DN_Rect &lhs, const DN_Rect &rhs) { bool result = (lhs.pos == rhs.pos) && (lhs.size == rhs.size); @@ -5712,11 +5982,17 @@ DN_API DN_Rect DN_RectUnion(DN_Rect a, DN_Rect b) return result; } -DN_API DN_RectMinMax DN_RectGetMinMax(DN_Rect a) +DN_API DN_2V2F32 DN_RectRange(DN_Rect a) { - DN_RectMinMax result = {}; - result.min = a.pos; - result.max = a.pos + a.size; + DN_2V2F32 result = {}; + result.min = a.pos; + result.max = a.pos + a.size; + return result; +} + +DN_API bool DN_RectEq(DN_Rect lhs, DN_Rect rhs) +{ + bool result = lhs.pos == rhs.pos && lhs.size == rhs.size; return result; } @@ -5851,17 +6127,3 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, } return result; } - -DN_API DN_V2F32 DN_LerpV2F32(DN_V2F32 a, DN_F32 t, DN_V2F32 b) -{ - DN_V2F32 result = {}; - result.x = a.x + ((b.x - a.x) * t); - result.y = a.y + ((b.y - a.y) * t); - return result; -} - -DN_API DN_F32 DN_LerpF32(DN_F32 a, DN_F32 t, DN_F32 b) -{ - DN_F32 result = a + ((b - a) * t); - return result; -} diff --git a/Source/Base/dn_base.h b/Source/Base/dn_base.h index 641d6b7..aede219 100644 --- a/Source/Base/dn_base.h +++ b/Source/Base/dn_base.h @@ -228,6 +228,9 @@ #if !defined(DN_TanF32) #define DN_TanF32(val) tanf(val) #endif + #if !defined(DN_PowF32) + #define DN_PowF32(val, exp) powf(val, exp) + #endif #endif // NOTE: Math @@ -836,6 +839,22 @@ struct DN_Pool DN_U8 align; }; +struct DN_UTF8DecodeResult +{ + bool success; + DN_Str8 remaining; + DN_U32 codepoint; +}; + +struct DN_UTF8DecodeIterator +{ + bool init; + bool success; + DN_Str8 remaining; + DN_USize codepoint_index; + DN_U32 codepoint; +}; + struct DN_NibbleFromU8Result { char nibble0; @@ -1213,7 +1232,19 @@ union DN_V2F32 struct { DN_F32 w, h; }; DN_F32 data[2]; }; -DN_DArrayStructDecl(DN_V2F32); + +struct DN_2V2F32 +{ + DN_V2F32 min; + DN_V2F32 max; +}; + +struct DN_V2F32Array +{ + DN_V2F32 *data; + DN_USize count; + DN_USize max; +}; union DN_V3F32 { @@ -1231,7 +1262,13 @@ union DN_V4F32 DN_V3F32 xyz; DN_F32 data[4]; }; -DN_DArrayStructDecl(DN_V4F32); + +struct DN_V4F32Array +{ + DN_V4F32* data; + DN_USize count; + DN_USize max; +}; DN_MSVC_WARNING_POP struct DN_M4 @@ -1245,16 +1282,23 @@ union DN_M2x3 DN_F32 row[2][3]; }; +struct DN_M2x3XForm +{ + DN_M2x3 forward; + DN_M2x3 inverse; +}; + +enum DN_M2x3ProjOrigin +{ + DN_M2x3ProjOrigin_TopLeft, + DN_M2x3ProjOrigin_Center, +}; + struct DN_Rect { DN_V2F32 pos, size; }; -struct DN_RectMinMax -{ - DN_V2F32 min, max; -}; - enum DN_RectCutClip { DN_RectCutClip_No, @@ -1638,8 +1682,10 @@ DN_API DN_Str8 DN_Str8BuilderBuild DN_API DN_Str8 DN_Str8BuilderBuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena); DN_API DN_Str8Slice DN_Str8BuilderBuildSlice (DN_Str8Builder const *builder, DN_Arena *arena); -DN_API int DN_EncodeUTF8Codepoint (DN_U8 utf8[4], DN_U32 codepoint); -DN_API int DN_EncodeUTF16Codepoint (DN_U16 utf16[2], DN_U32 codepoint); +DN_API int DN_UTF8Encode (DN_U8 utf8[4], DN_U32 codepoint); +DN_API int DN_UTF16Encode (DN_U16 utf16[2], DN_U32 codepoint); +DN_API DN_UTF8DecodeResult DN_UTF8Decode (DN_Str8 stream); +DN_API bool DN_UTF8DecodeIterate (DN_UTF8DecodeIterator *it, DN_Str8 utf8); DN_API DN_U8 DN_U8FromHexNibble (char hex); DN_API DN_NibbleFromU8Result DN_NibbleFromU8 (DN_U8 u8); @@ -1756,6 +1802,11 @@ DN_API void DN_StackTracePrint DN_API void DN_StackTraceReloadSymbols (); #endif +DN_API DN_F32 DN_F32Lerp (DN_F32 a, DN_F32 t, DN_F32 b); +DN_API DN_F32 DN_F32Floor (DN_F32 val); +DN_API DN_F32 DN_F32Ceil (DN_F32 val); +DN_API DN_F32 DN_F32RoundHalfUp (DN_F32 val); + #define DN_V2I32Zero DN_Literal(DN_V2I32){{(DN_I32)(0), (DN_I32)(0)}} #define DN_V2I32One DN_Literal(DN_V2I32){{(DN_I32)(1), (DN_I32)(1)}} #define DN_V2I32From1N(x) DN_Literal(DN_V2I32){{(DN_I32)(x), (DN_I32)(x)}} @@ -1827,8 +1878,9 @@ DN_API DN_V2U16& operator+= #define DN_V2F32One DN_Literal(DN_V2F32){{(DN_F32)(1), (DN_F32)(1)}} #define DN_V2F32From1N(x) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(x)}} #define DN_V2F32From2N(x, y) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(y)}} -#define DN_V2F32FromV2I32(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} -#define DN_V2F32FromV2U32(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} +#define DN_V2F32FromV2(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} + +DN_API DN_V2F32 DN_V2F32Lerp (DN_V2F32 a, DN_F32 t, DN_V2F32 b); DN_API bool operator!= (DN_V2F32 lhs, DN_V2F32 rhs); DN_API bool operator== (DN_V2F32 lhs, DN_V2F32 rhs); @@ -1896,6 +1948,10 @@ DN_API DN_F32 DN_V2F32Area #define DN_V3F32From3N(x, y, z) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z)}} #define DN_V3F32FromV2F32And1N(xy, z) DN_Literal(DN_V3F32){{(DN_F32)(xy.x), (DN_F32)(xy.y), (DN_F32)(z)}} +// NOTE: Grayscale co-efficients from: +// https://github.com/EpicGames/UnrealEngine/blob/260bb2e1c5610b31c63a36206eedd289409c5f11/Engine/Source/Runtime/Core/Private/Math/Color.cpp#L304 +DN_V3F32 static const DN_V3F32_RGB_LUMINANCE = DN_V3F32From3N(0.3f, 0.59f, 0.11f); + DN_API bool operator== (DN_V3F32 lhs, DN_V3F32 rhs); DN_API bool operator!= (DN_V3F32 lhs, DN_V3F32 rhs); DN_API bool operator>= (DN_V3F32 lhs, DN_V3F32 rhs); @@ -1919,6 +1975,7 @@ DN_API DN_V3F32& operator/= DN_API DN_V3F32& operator/= (DN_V3F32 &lhs, DN_I32 rhs); DN_API DN_V3F32& operator-= (DN_V3F32 &lhs, DN_V3F32 rhs); DN_API DN_V3F32& operator+= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32 DN_V3F32Lerp (DN_V3F32 lhs, DN_F32 t01, DN_V3F32 rhs); DN_API DN_F32 DN_V3F32LengthSq (DN_V3F32 a); DN_API DN_F32 DN_V3F32Length (DN_V3F32 a); DN_API DN_V3F32 DN_V3F32Normalise (DN_V3F32 a); @@ -1926,11 +1983,19 @@ DN_API DN_V3F32 DN_V3F32Normalise #define DN_V4F32From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V4F32From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} #define DN_V4F32FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} -#define DN_V4F32FromRGBAU8(r, g, b, a) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, a / 255.f}} -#define DN_V4F32FromRGBU8(r, g, b) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, 1.f}} -DN_API DN_V4F32 DN_V4F32FromRGBU32 (DN_U32 u32); -DN_API DN_V4F32 DN_V4F32FromRGBAU32 (DN_U32 u32); +#define DN_V4F32RGBA01FromRGBAU8(r, g, b, a) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, a / 255.f}} +#define DN_V4F32RGBA01FromRGBU8(r, g, b) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, 1.f}} + +DN_API DN_V4F32 DN_V4F32Lerp (DN_V4F32 lhs, DN_F32 t01, DN_V4F32 rhs); +DN_API bool DN_V4F32RGBA01IsValid (DN_V4F32 rgba01); +DN_API DN_V4F32 DN_V4F32RGBA01FromRGBU32 (DN_U32 u32); +DN_API DN_V4F32 DN_V4F32RGBA01FromRGBAU32 (DN_U32 u32); +DN_API DN_V4F32 DN_V4F32Linear01FromSRGB01 (DN_V4F32 rgb01); +DN_API DN_V4F32 DN_V4F32Linear01Desaturate (DN_V4F32 linear01, DN_F32 t01); +DN_API DN_V4F32 DN_V4F32SRGB01FromLinear01 (DN_V4F32 linear01); + #define DN_V4F32FromV4Alpha(v4, alpha) DN_V4F32FromV3And1N(v4.xyz, alpha) + DN_API bool operator== (DN_V4F32 lhs, DN_V4F32 rhs); DN_API bool operator!= (DN_V4F32 lhs, DN_V4F32 rhs); DN_API bool operator<= (DN_V4F32 lhs, DN_V4F32 rhs); @@ -1976,9 +2041,15 @@ DN_API DN_M2x3 DN_M2x3Translate DN_API DN_V2F32 DN_M2x3ScaleGet (DN_M2x3 m2x3); DN_API DN_M2x3 DN_M2x3Scale (DN_V2F32 scale); DN_API DN_M2x3 DN_M2x3Rotate (DN_F32 radians); +DN_API DN_M2x3 DN_M2x3ProjFromV2F32 (DN_V2F32 size, DN_M2x3ProjOrigin origin); +DN_API DN_M2x3XForm DN_M2x3XFormFrom2M2x3 (DN_M2x3 forward, DN_M2x3 inverse); +DN_API DN_M2x3XForm DN_M2x3XFormFromTRS (DN_V2F32 pos, DN_V2F32 scale, DN_F32 rotate_rads, DN_V2F32 pivot_pos); +DN_API DN_M2x3XForm DN_M2x3XFormIdentity (); +DN_API DN_M2x3XForm DN_M2x3XFormMul (DN_M2x3XForm m1, DN_M2x3XForm m2); DN_API DN_M2x3 DN_M2x3Mul (DN_M2x3 m1, DN_M2x3 m2); DN_API DN_V2F32 DN_M2x3Mul2F32 (DN_M2x3 m1, DN_F32 x, DN_F32 y); DN_API DN_V2F32 DN_M2x3MulV2F32 (DN_M2x3 m1, DN_V2F32 v2); +DN_API DN_Rect DN_M2x3MulRect (DN_M2x3 m1, DN_Rect rect); #define DN_RectFrom2V2(pos, size) DN_Literal(DN_Rect){(pos), (size)} #define DN_RectFrom4N(x, y, w, h) DN_Literal(DN_Rect){DN_Literal(DN_V2F32){{x, y}}, DN_Literal(DN_V2F32){{w, h}}} @@ -1993,7 +2064,8 @@ DN_API DN_Rect DN_RectExpandV2 DN_API bool DN_RectIntersects (DN_Rect a, DN_Rect b); DN_API DN_Rect DN_RectIntersection (DN_Rect a, DN_Rect b); DN_API DN_Rect DN_RectUnion (DN_Rect a, DN_Rect b); -DN_API DN_RectMinMax DN_RectGetMinMax (DN_Rect a); +DN_API DN_2V2F32 DN_RectRange (DN_Rect a); +DN_API bool DN_RectEq (DN_Rect lhs, DN_Rect rhs); DN_API DN_F32 DN_RectArea (DN_Rect a); DN_API DN_V2F32 DN_RectInterpV2F32 (DN_Rect rect, DN_V2F32 t01); DN_API DN_V2F32 DN_RectTopLeft (DN_Rect rect); @@ -2020,6 +2092,4 @@ DN_API DN_Rect DN_RectCutCut #define DN_RectCutInit(rect, side) DN_Literal(DN_RectCut){rect, side} DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 (DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b); -DN_API DN_V2F32 DN_LerpV2F32 (DN_V2F32 a, DN_F32 t, DN_V2F32 b); -DN_API DN_F32 DN_LerpF32 (DN_F32 a, DN_F32 t, DN_F32 b); #endif // !defined(DN_BASE_H) diff --git a/Source/Base/dn_base_containers.h b/Source/Base/dn_base_containers.h index d01ae09..c6cf1c2 100644 --- a/Source/Base/dn_base_containers.h +++ b/Source/Base/dn_base_containers.h @@ -286,12 +286,12 @@ template struct DN_DSMapResult #define DN_CppDeclType #endif -#define DN_PArrayResizeFromPool(ptr, size, max, pool, new_max) DN_CArrayResizeFromPool((void **)&(ptr), size, max, sizeof((ptr)[0]), pool, new_max) -#define DN_PArrayResizeFromArena(ptr, size, max, arena, new_max) DN_CArrayResizeFromArena((void **)&(ptr), size, max, sizeof((ptr)[0]), arena, new_max) -#define DN_PArrayGrowFromPool(ptr, size, max, pool, new_max) DN_CArrayGrowFromPool((void **)&(ptr), size, max, sizeof((ptr)[0]), pool, new_max) -#define DN_PArrayGrowFromArena(ptr, size, max, arena, new_max) DN_CArrayGrowFromArena((void **)&(ptr), size, max, sizeof((ptr)[0]), arena, new_max) -#define DN_PArrayGrowIfNeededFromPool(ptr, size, max, pool, add_count) DN_CArrayGrowIfNeededFromPool((void **)(ptr), size, max, sizeof((ptr)[0]), pool, add_count) -#define DN_PArrayGrowIfNeededFromArena(ptr, size, max, arena, add_count) DN_CArrayGrowIfNeededFromArena((void **)(ptr), size, max, sizeof((ptr)[0]), arena, add_count) +#define DN_PArrayResizeFromPool(ptr, size, max, pool, new_max) DN_CArrayResizeFromPool((void **)&(ptr), size, max, sizeof((*ptr)[0]), pool, new_max) +#define DN_PArrayResizeFromArena(ptr, size, max, arena, new_max) DN_CArrayResizeFromArena((void **)&(ptr), size, max, sizeof((*ptr)[0]), arena, new_max) +#define DN_PArrayGrowFromPool(ptr, size, max, pool, new_max) DN_CArrayGrowFromPool((void **)&(ptr), size, max, sizeof((*ptr)[0]), pool, new_max) +#define DN_PArrayGrowFromArena(ptr, size, max, arena, new_max) DN_CArrayGrowFromArena((void **)&(ptr), size, max, sizeof((*ptr)[0]), arena, new_max) +#define DN_PArrayGrowIfNeededFromPool(ptr, size, max, pool, add_count) DN_CArrayGrowIfNeededFromPool((void **)(ptr), size, max, sizeof((*ptr)[0]), pool, add_count) +#define DN_PArrayGrowIfNeededFromArena(ptr, size, max, arena, add_count) DN_CArrayGrowIfNeededFromArena((void **)(ptr), size, max, sizeof((*ptr)[0]), arena, add_count) #define DN_PArrayMakeArray(ptr, size, max, count, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_CArrayMakeArray(ptr, size, max, sizeof((ptr)[0]), count, z_mem) #define DN_PArrayMakeArrayZ(ptr, size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_CArrayMakeArray(ptr, size, max, sizeof((ptr)[0]), count, DN_ZMem_Yes) #define DN_PArrayMake(ptr, size, max, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_CArrayMakeArray(ptr, size, max, sizeof((ptr)[0]), 1, z_mem) @@ -318,7 +318,7 @@ template struct DN_DSMapResult #define DN_LArrayMakeArray(c_array, size, count, z_mem) DN_PArrayMakeArray(c_array, size, DN_ArrayCountU(c_array), count, z_mem) #define DN_LArrayMakeArrayZ(c_array, size, count) DN_PArrayMakeArrayZ(c_array, size, DN_ArrayCountU(c_array), count) #define DN_LArrayMake(c_array, size, z_mem) DN_PArrayMake(c_array, size, DN_ArrayCountU(c_array), z_mem) -#define DN_LArrayMakeZ(c_array, size, max) DN_PArrayMakeZ(c_array, size, DN_ArrayCountU(c_array), max) +#define DN_LArrayMakeZ(c_array, size) DN_PArrayMakeZ(c_array, size, DN_ArrayCountU(c_array)) #define DN_LArrayAddArray(c_array, size, items, count, add) DN_PArrayAddArray(c_array, size, DN_ArrayCountU(c_array), items, count, add) #define DN_LArrayAdd(c_array, size, item, add) DN_PArrayAdd(c_array, size, DN_ArrayCountU(c_array), item, add) #define DN_LArrayAppendArray(c_array, size, items, count) DN_PArrayAppendArray(c_array, size, DN_ArrayCountU(c_array), items, count) @@ -369,8 +369,8 @@ DN_API bool DN_CArrayResizeFromPool DN_API bool DN_CArrayResizeFromArena (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Arena *arena, DN_USize new_max); DN_API bool DN_CArrayGrowFromPool (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max); DN_API bool DN_CArrayGrowFromArena (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max); -DN_API bool DN_CArrayGrowIfNeededFromPool (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool); -DN_API bool DN_CArrayGrowIfNeededFromArena (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Arena *pool); +DN_API bool DN_CArrayGrowIfNeededFromPool (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize add_count); +DN_API bool DN_CArrayGrowIfNeededFromArena (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Arena *pool, DN_USize add_count); DN_API void* DN_SinglyLLDetach (void **link, void **next); diff --git a/Source/OS/dn_os.cpp b/Source/OS/dn_os.cpp index 1a60326..d721d18 100644 --- a/Source/OS/dn_os.cpp +++ b/Source/OS/dn_os.cpp @@ -27,7 +27,7 @@ DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGet(DN_ArenaMemFuncType type) result.type = DN_ArenaMemFuncType_Basic; result.basic_alloc = DN_ArenaBasicAllocFromOSHeap; result.basic_dealloc = DN_OS_MemDealloc; - }; + } break; case DN_ArenaMemFuncType_VMem: { DN_Core *dn = DN_Get(); diff --git a/Source/OS/dn_os_posix.cpp b/Source/OS/dn_os_posix.cpp index 88569bb..61a93eb 100644 --- a/Source/OS/dn_os_posix.cpp +++ b/Source/OS/dn_os_posix.cpp @@ -339,17 +339,17 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink { bool result = false; #if defined(DN_PLATFORM_EMSCRIPTEN) - DN_OS_ErrSinkAppendF(error, 1, "Unsupported on Emscripten because of their VFS model"); + DN_ErrSinkAppendF(error, 1, "Unsupported on Emscripten because of their VFS model"); #else int src_fd = open(src.data, O_RDONLY); if (src_fd == -1) { int error_code = errno; - DN_OS_ErrSinkAppendF(error, - error_code, - "Failed to open file '%.*s' for copying: (%d) %s", - DN_Str8PrintFmt(src), - error_code, - strerror(error_code)); + DN_ErrSinkAppendF(error, + error_code, + "Failed to open file '%.*s' for copying: (%d) %s", + DN_Str8PrintFmt(src), + error_code, + strerror(error_code)); return result; } DN_DEFER @@ -361,12 +361,12 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink int dest_fd = open(dest.data, O_WRONLY | O_CREAT | (overwrite ? O_TRUNC : 0), 0644); if (dest_fd == -1) { int error_code = errno; - DN_OS_ErrSinkAppendF(error, - error_code, - "Failed to open file destination '%.*s' for copying to: (%d) %s", - DN_Str8PrintFmt(src), - error_code, - strerror(error_code)); + DN_ErrSinkAppendF(error, + error_code, + "Failed to open file destination '%.*s' for copying to: (%d) %s", + DN_Str8PrintFmt(src), + error_code, + strerror(error_code)); return result; } DN_DEFER @@ -378,12 +378,12 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink int fstat_result = fstat(src_fd, &stat_existing); if (fstat_result == -1) { int error_code = errno; - DN_OS_ErrSinkAppendF(error, - error_code, - "Failed to query file size of '%.*s' for copying: (%d) %s", - DN_Str8PrintFmt(src), - error_code, - strerror(error_code)); + DN_ErrSinkAppendF(error, + error_code, + "Failed to query file size of '%.*s' for copying: (%d) %s", + DN_Str8PrintFmt(src), + error_code, + strerror(error_code)); return result; } @@ -394,16 +394,16 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); DN_Str8 file_size_str8 = DN_Str8FromByteCount(scratch.arena, stat_existing.st_size, DN_ByteCountType_Auto); DN_Str8 bytes_written_str8 = DN_Str8FromByteCount(scratch.arena, bytes_written, DN_ByteCountType_Auto); - DN_OS_ErrSinkAppendF(error, - error_code, - "Failed to copy file '%.*s' to '%.*s', we copied %.*s but the file " - "size is %.*s: (%d) %s", - DN_Str8PrintFmt(src), - DN_Str8PrintFmt(dest), - DN_Str8PrintFmt(bytes_written_str8), - DN_Str8PrintFmt(file_size_str8), - error_code, - strerror(error_code)); + DN_rrSinkAppendF(error, + error_code, + "Failed to copy file '%.*s' to '%.*s', we copied %.*s but the file " + "size is %.*s: (%d) %s", + DN_Str8PrintFmt(src), + DN_Str8PrintFmt(dest), + DN_Str8PrintFmt(bytes_written_str8), + DN_Str8PrintFmt(file_size_str8), + error_code, + strerror(error_code)); DN_TCScratchEnd(&scratch); } @@ -427,7 +427,7 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink int unlink_result = unlink(src.data); if (unlink_result == -1) { int error_code = errno; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, error_code, "File '%.*s' was moved but failed to be unlinked from old location: (%d) %s", @@ -455,7 +455,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, if (access & DN_OSFileAccess_Execute) { result.error = true; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, 1, "Failed to open file '%.*s': File access flag 'execute' is not supported", @@ -479,12 +479,12 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, if (!handle) { // TODO(doyle): FileOpen flag to string result.error = true; - DN_OS_ErrSinkAppendF(error, - 1, - "Failed to open file '%.*s': File could not be opened in requested " - "mode 'DN_OSFileOpen' flag %d", - DN_Str8PrintFmt(path), - open_mode); + DN_ErrSinkAppendF(error, + 1, + "Failed to open file '%.*s': File could not be opened in requested " + "mode 'DN_OSFileOpen' flag %d", + DN_Str8PrintFmt(path), + open_mode); return result; } fclose(handle); @@ -501,12 +501,12 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, FILE *handle = fopen(path.data, fopen_mode); if (!handle) { result.error = true; - DN_OS_ErrSinkAppendF(error, - 1, - "Failed to open file '%S': File could not be opened with requested " - "access mode 'DN_OSFileAccess' %d", - path, - fopen_mode); + DN_ErrSinkAppendF(error, + 1, + "Failed to open file '%S': File could not be opened with requested " + "access mode 'DN_OSFileAccess' %d", + path, + fopen_mode); return result; } result.handle = handle; @@ -523,7 +523,7 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size if (feof(DN_Cast(FILE*)file->handle)) { DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size); - DN_OS_ErrSinkAppendF(err, 1, "Failed to read %S from file", buffer_size_str8); + DN_ErrSinkAppendF(err, 1, "Failed to read %S from file", buffer_size_str8); DN_TCScratchEnd(&scratch); return result; } @@ -542,7 +542,7 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz if (!result) { DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size); - DN_OS_ErrSinkAppendF(err, 1, "Failed to write buffer (%s) to file handle", DN_Str8PrintFmt(buffer_size_str8)); + DN_ErrSinkAppendF(err, 1, "Failed to write buffer (%s) to file handle", DN_Str8PrintFmt(buffer_size_str8)); DN_TCScratchEnd(&scratch); } return result; @@ -553,13 +553,13 @@ DN_API bool DN_OS_FileFlush(DN_OSFile *file, DN_ErrSink *err) // TODO: errno is not thread safe int fd = fileno(DN_Cast(FILE *) file->handle); if (fd == -1) { - DN_OS_ErrSinkAppendF(err, errno, "Failed to flush file buffer to disk, file handle could not be converted to descriptor (%d): %s", fd, strerror(errno)); + DN_ErrSinkAppendF(err, errno, "Failed to flush file buffer to disk, file handle could not be converted to descriptor (%d): %s", fd, strerror(errno)); return false; } int fsync_result = fsync(fd); if (fsync_result == -1) { - DN_OS_ErrSinkAppendF(err, errno, "Failed to flush file buffer to disk (%d): %s", fsync_result, strerror(errno)); + DN_ErrSinkAppendF(err, errno, "Failed to flush file buffer to disk (%d): %s", fsync_result, strerror(errno)); return false; } return true; @@ -833,22 +833,22 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, return result; } -DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, - DN_OSExecArgs *args, - DN_ErrSink *error) +DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, + DN_OSExecArgs *args, + DN_ErrSink *error) { #if defined(DN_PLATFORM_EMSCRIPTEN) DN_InvalidCodePathF("Unsupported operation"); #endif - DN_AssertFOnce(args->environment.size == 0, "Unimplemented in POSIX"); + DN_AssertFOnce(args->environment.count == 0, "Unimplemented in POSIX"); DN_OSExecAsyncHandle result = {}; - if (cmd_line.size == 0) + if (cmd_line.count == 0) return result; - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); DN_DEFER { DN_TCScratchEnd(&scratch); }; - DN_Str8 cmd_rendered = DN_Slice_Str8Render(scratch.arena, cmd_line, DN_Str8Lit(" ")); + DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), scratch.arena); int stdout_pipe[DN_OSPipeType__Count] = {}; int stderr_pipe[DN_OSPipeType__Count] = {}; @@ -856,7 +856,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, if (DN_BitIsSet(args->flags, DN_OSExecFlags_SaveStdout)) { if (pipe(stdout_pipe) == -1) { result.os_error_code = errno; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, result.os_error_code, "Failed to create stdout pipe to redirect the output of the command '%.*s': %s", @@ -883,7 +883,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, stderr_pipe[DN_OSPipeType__Write] = stdout_pipe[DN_OSPipeType__Write]; } else if (pipe(stderr_pipe) == -1) { result.os_error_code = errno; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, result.os_error_code, "Failed to create stderr pipe to redirect the output of the command '%.*s': %s", @@ -906,7 +906,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, pid_t child_pid = fork(); if (child_pid < 0) { result.os_error_code = errno; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, result.os_error_code, "Failed to fork process to execute the command '%.*s': %s", @@ -919,7 +919,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, if (DN_BitIsSet(args->flags, DN_OSExecFlags_SaveStdout) && (dup2(stdout_pipe[DN_OSPipeType__Write], STDOUT_FILENO) == -1)) { result.os_error_code = errno; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, result.os_error_code, "Failed to redirect stdout 'write' pipe for output of command '%.*s': %s", @@ -931,7 +931,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, if (DN_BitIsSet(args->flags, DN_OSExecFlags_SaveStderr) && (dup2(stderr_pipe[DN_OSPipeType__Write], STDERR_FILENO) == -1)) { result.os_error_code = errno; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, result.os_error_code, "Failed to redirect stderr 'read' pipe for output of command '%.*s': %s", @@ -942,10 +942,10 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, // NOTE: Convert the command into something suitable for execvp char **argv = - DN_ArenaNewArray(scratch.arena, char *, cmd_line.size + 1 /*null*/, DN_ZMem_Yes); + DN_ArenaNewArray(scratch.arena, char *, cmd_line.count + 1 /*null*/, DN_ZMem_Yes); if (!argv) { result.exit_code = -1; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, result.os_error_code, "Failed to create argument values from command line '%.*s': Out of memory", @@ -953,7 +953,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, return result; } - for (DN_ForIndexU(arg_index, cmd_line.size)) { + for (DN_ForIndexU(arg_index, cmd_line.count)) { DN_Str8 arg = cmd_line.data[arg_index]; argv[arg_index] = DN_Str8FromStr8Arena(scratch.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated } @@ -976,7 +976,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_Str8 working_dir = DN_Str8FromStr8Arena(scratch.arena, args->working_dir); if (chdir(working_dir.data) == -1) { result.os_error_code = errno; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, result.os_error_code, "Failed to create argument values from command line '%.*s': %s", @@ -990,7 +990,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, // binary to execute is guaranteed to be null-terminated. if (execvp(argv[0], argv) < 0) { result.os_error_code = errno; - DN_OS_ErrSinkAppendF( + DN_ErrSinkAppendF( error, result.os_error_code, "Failed to execute command'%.*s': %s", @@ -1290,7 +1290,7 @@ static void *DN_OS_ThreadFunc_(void *user_context) return nullptr; } -DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_TCLane *lane, void *user_context) +DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context) { bool result = false; if (!thread) @@ -1299,7 +1299,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_TCLa thread->func = func; thread->user_context = user_context; thread->init_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/); - thread->lane = lane; + thread->lane = *lane; // TODO(doyle): Check if semaphore is valid // NOTE: pthread_t is essentially the thread ID. In Windows, the handle and @@ -1412,28 +1412,28 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus() DN_Str8 const VM_PEAK = DN_Str8Lit("VmPeak:"); DN_Str8 const VM_SIZE = DN_Str8Lit("VmSize:"); DN_Str8 status_buf = DN_Str8BuilderBuild(&builder, tmem.arena); - DN_Str8SplitResult lines = DN_Str8Split(tmem.arena, status_buf, DN_Str8Lit("\n"), DN_Str8SplitIncludeEmptyStrings_No); + DN_Str8SplitResult lines = DN_Str8SplitArena(tmem.arena, status_buf, DN_Str8Lit("\n"), DN_Str8SplitIncludeEmptyStrings_No); for (DN_ForItSize(line_it, DN_Str8, lines.data, lines.count)) { - DN_Str8 line = DN_Str8TrimWhitespaceAround(*line_it.data); + DN_Str8 line = DN_Str8TrimWhitespaceAround(*line_it.data); if (DN_Str8StartsWith(line, NAME, DN_Str8EqCase_Insensitive)) { - DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, NAME.size, line.size)); + DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Subset(line, NAME.size, line.size)); result.name_size = DN_Min(str8.size, sizeof(result.name)); DN_Memcpy(result.name, str8.data, result.name_size); } else if (DN_Str8StartsWith(line, PID, DN_Str8EqCase_Insensitive)) { - DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, PID.size, line.size)); + DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Subset(line, PID.size, line.size)); DN_U64FromResult to_u64 = DN_U64FromStr8(str8, 0); result.pid = to_u64.value; DN_Assert(to_u64.success); } else if (DN_Str8StartsWith(line, VM_SIZE, DN_Str8EqCase_Insensitive)) { - DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, VM_SIZE.size, line.size)); + DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Subset(line, VM_SIZE.size, line.size)); DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB"))); DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs; DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size, 0); result.vm_size = DN_Kilobytes(to_u64.value); DN_Assert(to_u64.success); } else if (DN_Str8StartsWith(line, VM_PEAK, DN_Str8EqCase_Insensitive)) { - DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, VM_PEAK.size, line.size)); + DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Subset(line, VM_PEAK.size, line.size)); DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB"))); DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs; DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size, 0); @@ -1498,7 +1498,7 @@ static void DN_OS_HttpRequestEMFetchOnSuccessCallback(emscripten_fetch_t *fetch) return; response->http_status = DN_Cast(DN_U32) fetch->status; - response->body = DN_Str8FromArena(response->arena, fetch->numBytes, DN_ZMem_No); + response->body = DN_Str8AllocArena(response->arena, fetch->numBytes, DN_ZMem_No); if (response->body.data) DN_Memcpy(response->body.data, fetch->data, fetch->numBytes); @@ -1513,7 +1513,7 @@ static void DN_OS_HttpRequestEMFetchOnErrorCallback(emscripten_fetch_t *fetch) return; response->http_status = DN_Cast(DN_U32) fetch->status; - response->body = DN_Str8FromArena(response->arena, fetch->numBytes, DN_ZMem_No); + response->body = DN_Str8AllocArena(response->arena, fetch->numBytes, DN_ZMem_No); if (response->body.size) DN_Memcpy(response->body.data, fetch->data, fetch->numBytes); diff --git a/Source/dn.cpp b/Source/dn.cpp index 74ac218..35e4463 100644 --- a/Source/dn.cpp +++ b/Source/dn.cpp @@ -7,6 +7,8 @@ #include "Base/dn_base_containers.cpp" #include "Base/dn_base_leak.cpp" +DN_Core *g_dn_; + #if DN_H_WITH_OS #include "OS/dn_os.cpp" #if defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN) @@ -18,8 +20,6 @@ #endif #endif -DN_Core *g_dn_; - DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args) { DN_Set(dn); @@ -52,16 +52,12 @@ DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args) { - #if defined(DN_PLATFORM_EMSCRIPTEN) - os->arena = DN_ArenaFromHeap(DN_Megabytes(1), DN_ArenaFlags_NoAllocTrack); - #else - os->arena = DN_ArenaFromVMem(DN_Megabytes(1), DN_Kilobytes(4), DN_ArenaFlags_NoAllocTrack); - #endif + os->arena = DN_ArenaFromMemFuncs(DN_Megabytes(1), DN_Kilobytes(4), DN_ArenaFlags_NoAllocTrack, DN_ArenaMemFuncsGetDefaults()); #if defined(DN_PLATFORM_WIN32) os->platform_context = DN_ArenaNew(&os->arena, DN_OSW32Core, DN_ZMem_Yes); #elif defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN) - os->platform_context = DN_ArenaNew(&os->arena, DN_OSPOSIXCore, DN_ZMem_Yes); + os->platform_context = DN_ArenaNew(&os->arena, DN_OSPosixCore, DN_ZMem_Yes); #endif #if defined(DN_PLATFORM_WIN32) @@ -101,7 +97,7 @@ DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args) #if DN_H_WITH_OS // NOTE: Setup the allocation table with allocation tracking turned off on // the arena we're using to initialise the table. - dn->leak.alloc_table_arena = DN_ArenaFromVMem(DN_Megabytes(1), DN_Kilobytes(512), DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak); + dn->leak.alloc_table_arena = DN_ArenaFromMemFuncs(DN_Megabytes(1), DN_Kilobytes(512), DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak, DN_ArenaMemFuncsGetDefaults()); dn->leak.alloc_table = DN_DSMapInit(&dn->leak.alloc_table_arena, 4096, DN_DSMapFlags_Nil); #endif } diff --git a/Source/dn.h b/Source/dn.h index b65bddd..b63986e 100644 --- a/Source/dn.h +++ b/Source/dn.h @@ -97,7 +97,6 @@ #else #error Please define a platform e.g. 'DN_PLATFORM_WIN32' to enable the correct implementation for platform APIs #endif - #include "OS/dn_os.h" #endif