Adding scratch arena for main thread (and any thread in the future)
Added some function based on raddbg code for string conversion and more.
This commit is contained in:
@@ -12,7 +12,7 @@ void InitEntityManager(Juliet::NonNullPtr<World> world)
|
|||||||
|
|
||||||
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
|
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
|
||||||
|
|
||||||
newManager->Arena = Juliet::ArenaAllocate({} JULIET_DEBUG_PARAM("Entity Arena"));
|
newManager->Arena = Juliet::ArenaAllocate({ .Name = "Entity Arena" });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownEntityManager()
|
void ShutdownEntityManager()
|
||||||
|
|||||||
+2
-2
@@ -43,7 +43,7 @@ extern "C" JULIET_API void __cdecl GameUpdate(Juliet::GameData* params, [[maybe_
|
|||||||
gGameState = params->GameState;
|
gGameState = params->GameState;
|
||||||
if (!gGameState)
|
if (!gGameState)
|
||||||
{
|
{
|
||||||
Arena* gameStateArena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_PARAM("Game Total Arena"));
|
Arena* gameStateArena = ArenaAllocate({ .ReserveSize = Megabytes(1), .Name = "Game Total Arena" });
|
||||||
auto* gameState = ArenaPushStruct<GameState>(gameStateArena);
|
auto* gameState = ArenaPushStruct<GameState>(gameStateArena);
|
||||||
gGameState = params->GameState = gameState;
|
gGameState = params->GameState = gameState;
|
||||||
gameState->TotalArena = gameStateArena;
|
gameState->TotalArena = gameStateArena;
|
||||||
@@ -57,7 +57,7 @@ extern "C" JULIET_API void __cdecl GameUpdate(Juliet::GameData* params, [[maybe_
|
|||||||
ReserveCamera(4);
|
ReserveCamera(4);
|
||||||
|
|
||||||
// Bootstrap world
|
// Bootstrap world
|
||||||
auto* worldArena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_PARAM("World Arena"));
|
auto* worldArena = ArenaAllocate({ .ReserveSize = Megabytes(1), .Name = "World Arena" });
|
||||||
World* world = ArenaPushStruct<World>(worldArena JULIET_DEBUG_PARAM("World"));
|
World* world = ArenaPushStruct<World>(worldArena JULIET_DEBUG_PARAM("World"));
|
||||||
gameState->World = world;
|
gameState->World = world;
|
||||||
gameState->World->WorldArena = worldArena;
|
gameState->World->WorldArena = worldArena;
|
||||||
|
|||||||
@@ -202,4 +202,30 @@ namespace Juliet
|
|||||||
return "UnknownType";
|
return "UnknownType";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint16 safe_cast_uint16(uint32 value)
|
||||||
|
{
|
||||||
|
Assert(value <= uint16Max);
|
||||||
|
uint16 result = (uint16)value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32 bitmask1 = 0b0000'0001;
|
||||||
|
const uint32 bitmask2 = 0b0000'0011;
|
||||||
|
const uint32 bitmask3 = 0b0000'0111;
|
||||||
|
const uint32 bitmask4 = 0b0000'1111;
|
||||||
|
const uint32 bitmask5 = 0b0001'1111;
|
||||||
|
const uint32 bitmask6 = 0b0011'1111;
|
||||||
|
const uint32 bitmask7 = 0b0111'1111;
|
||||||
|
const uint32 bitmask8 = 0b1111'1111;
|
||||||
|
const uint32 bitmask9 = 0x0000'01ff;
|
||||||
|
const uint32 bitmask10 = 0x0000'03ff;
|
||||||
|
const uint32 bitmask11 = 0x0000'07ff;
|
||||||
|
const uint32 bitmask12 = 0x0000'0fff;
|
||||||
|
const uint32 bitmask13 = 0x0000'1fff;
|
||||||
|
const uint32 bitmask14 = 0x0000'3fff;
|
||||||
|
const uint32 bitmask15 = 0x0000'7fff;
|
||||||
|
const uint32 bitmask16 = 0x0000'ffff;
|
||||||
|
// ...
|
||||||
|
const uint32 bitmask32 = 0xffff'ffff;
|
||||||
} // namespace Juliet
|
} // namespace Juliet
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Juliet
|
|||||||
struct Arena;
|
struct Arena;
|
||||||
|
|
||||||
#define ConstString(str) { const_cast<char*>((str)), sizeof(str) - 1 }
|
#define ConstString(str) { const_cast<char*>((str)), sizeof(str) - 1 }
|
||||||
#define CStr(str) ((str).Data)
|
#define CStr(str) ((str).Str)
|
||||||
#define InplaceString(name, size) \
|
#define InplaceString(name, size) \
|
||||||
char name##_[size]; \
|
char name##_[size]; \
|
||||||
MemSet(name##_, 0, sizeof(uint32)); \
|
MemSet(name##_, 0, sizeof(uint32)); \
|
||||||
@@ -40,9 +40,16 @@ namespace Juliet
|
|||||||
|
|
||||||
// Represents a UTF-8 String.
|
// Represents a UTF-8 String.
|
||||||
// Not null terminated.
|
// Not null terminated.
|
||||||
struct String
|
struct String8
|
||||||
{
|
{
|
||||||
char* Data;
|
char* Str;
|
||||||
|
size_t Size;
|
||||||
|
};
|
||||||
|
using String = String8;
|
||||||
|
|
||||||
|
struct String16
|
||||||
|
{
|
||||||
|
uint16* Str;
|
||||||
size_t Size;
|
size_t Size;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -51,6 +58,12 @@ namespace Juliet
|
|||||||
size_t Capacity;
|
size_t Capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UnicodeDecode
|
||||||
|
{
|
||||||
|
uint32 Increment;
|
||||||
|
uint32 Codepoint;
|
||||||
|
};
|
||||||
|
|
||||||
constexpr uint32 kInvalidUTF8 = 0xFFFD;
|
constexpr uint32 kInvalidUTF8 = 0xFFFD;
|
||||||
|
|
||||||
inline size_t StringLength(String str)
|
inline size_t StringLength(String str)
|
||||||
@@ -75,13 +88,13 @@ namespace Juliet
|
|||||||
|
|
||||||
inline bool IsValid(String str)
|
inline bool IsValid(String str)
|
||||||
{
|
{
|
||||||
return str.Size > 0 && str.Data != nullptr && *str.Data;
|
return str.Size > 0 && str.Str != nullptr && *str.Str;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline String WrapString(const char* str)
|
inline String WrapString(const char* str)
|
||||||
{
|
{
|
||||||
String result = {};
|
String result = {};
|
||||||
result.Data = const_cast<char*>(str);
|
result.Str = const_cast<char*>(str);
|
||||||
result.Size = str ? strlen(str) : 0;
|
result.Size = str ? strlen(str) : 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -91,9 +104,9 @@ namespace Juliet
|
|||||||
String result = str;
|
String result = str;
|
||||||
while (result.Size)
|
while (result.Size)
|
||||||
{
|
{
|
||||||
if (*result.Data != c)
|
if (*result.Str != c)
|
||||||
{
|
{
|
||||||
++result.Data;
|
++result.Str;
|
||||||
--result.Size;
|
--result.Size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -151,6 +164,7 @@ namespace Juliet
|
|||||||
extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst, bool nullTerminate);
|
extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst, bool nullTerminate);
|
||||||
|
|
||||||
JULIET_API String StringCopy(NonNullPtr<Arena> arena, String str);
|
JULIET_API String StringCopy(NonNullPtr<Arena> arena, String str);
|
||||||
|
JULIET_API String16 str16_from_8(NonNullPtr<Arena> arena, String8 str);
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
String Format(NonNullPtr<Arena> arena, const char* formatStr, Args&&... args)
|
String Format(NonNullPtr<Arena> arena, const char* formatStr, Args&&... args)
|
||||||
@@ -158,6 +172,8 @@ namespace Juliet
|
|||||||
std::string result = std::vformat(formatStr, std::make_format_args(args...));
|
std::string result = std::vformat(formatStr, std::make_format_args(args...));
|
||||||
return StringCopy(arena, WrapString(result.c_str()));
|
return StringCopy(arena, WrapString(result.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define juliet_snprintf snprintf
|
||||||
} // namespace Juliet
|
} // namespace Juliet
|
||||||
|
|
||||||
#ifdef UNIT_TEST
|
#ifdef UNIT_TEST
|
||||||
@@ -169,12 +185,12 @@ namespace Juliet::UnitTest
|
|||||||
String s2 = ConstString("abcdefabcdef");
|
String s2 = ConstString("abcdefabcdef");
|
||||||
String s3 = ConstString("11111111111111111111");
|
String s3 = ConstString("11111111111111111111");
|
||||||
|
|
||||||
Assert(FindChar(s1, 'x').Data == nullptr);
|
Assert(FindChar(s1, 'x').Str == nullptr);
|
||||||
Assert(FindChar(s2, 'y').Data == nullptr);
|
Assert(FindChar(s2, 'y').Str == nullptr);
|
||||||
Assert(FindChar(s2, 'a').Data - s2.Data == 0);
|
Assert(FindChar(s2, 'a').Str - s2.Str == 0);
|
||||||
Assert(FindChar(s2, 'd').Data - s2.Data == 3);
|
Assert(FindChar(s2, 'd').Str - s2.Str == 3);
|
||||||
Assert(FindChar(s2, 'f').Data - s2.Data == 5);
|
Assert(FindChar(s2, 'f').Str - s2.Str == 5);
|
||||||
Assert(FindChar(s3, '1').Data - s3.Data == 0);
|
Assert(FindChar(s3, '1').Str - s3.Str == 0);
|
||||||
}
|
}
|
||||||
} // namespace Juliet::UnitTest
|
} // namespace Juliet::UnitTest
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace Juliet
|
|||||||
JULIET_DEBUG_ONLY(Arena* GlobalNext;)
|
JULIET_DEBUG_ONLY(Arena* GlobalNext;)
|
||||||
JULIET_DEBUG_ONLY(Arena* GlobalPrev;)
|
JULIET_DEBUG_ONLY(Arena* GlobalPrev;)
|
||||||
JULIET_DEBUG_ONLY(ArenaDebugInfo* FirstDebugInfo;)
|
JULIET_DEBUG_ONLY(ArenaDebugInfo* FirstDebugInfo;)
|
||||||
JULIET_DEBUG_ONLY(const char* Name;)
|
const char* Name;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Arena) <= k_ArenaHeaderSize);
|
static_assert(sizeof(Arena) <= k_ArenaHeaderSize);
|
||||||
|
|
||||||
@@ -59,11 +59,13 @@ namespace Juliet
|
|||||||
uint64 ReserveSize = g_Arena_Default_Reserve_Size;
|
uint64 ReserveSize = g_Arena_Default_Reserve_Size;
|
||||||
uint64 CommitSize = g_Arena_Default_Commit_Size;
|
uint64 CommitSize = g_Arena_Default_Commit_Size;
|
||||||
|
|
||||||
|
const char* Name;
|
||||||
|
|
||||||
// When false, will assert if a new block is reserved.
|
// When false, will assert if a new block is reserved.
|
||||||
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
|
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] JULIET_API Arena* ArenaAllocate(const ArenaParams& params JULIET_DEBUG_PARAM(const char* name),
|
[[nodiscard]] JULIET_API Arena* ArenaAllocate(const ArenaParams& params,
|
||||||
const std::source_location& loc = std::source_location::current());
|
const std::source_location& loc = std::source_location::current());
|
||||||
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena);
|
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena);
|
||||||
|
|
||||||
@@ -88,7 +90,7 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
return Format(GetDebugInfoArena(), std::forward<FirstDebugArg>(firstDebugArg),
|
return Format(GetDebugInfoArena(), std::forward<FirstDebugArg>(firstDebugArg),
|
||||||
std::forward<DebugArgs>(debugArgs)...)
|
std::forward<DebugArgs>(debugArgs)...)
|
||||||
.Data;
|
.Str;
|
||||||
}()));
|
}()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,23 +104,23 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
if constexpr (sizeof...(DebugArgs) > 0)
|
if constexpr (sizeof...(DebugArgs) > 0)
|
||||||
{
|
{
|
||||||
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Data;
|
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
|
||||||
}
|
}
|
||||||
return GetTypeName<Type>();
|
return GetTypeName<Type>();
|
||||||
}())));
|
}())));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type JULIET_DEBUG_ONLY(, typename... DebugArgs)>
|
template <typename Type, bool shouldZero = true JULIET_DEBUG_ONLY(, typename... DebugArgs)>
|
||||||
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
|
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
|
||||||
{
|
{
|
||||||
return static_cast<Type*>(
|
return static_cast<Type*>(
|
||||||
ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)),
|
ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)),
|
||||||
true JULIET_DEBUG_PARAM(
|
shouldZero JULIET_DEBUG_PARAM(
|
||||||
[&]() -> const char*
|
[&]() -> const char*
|
||||||
{
|
{
|
||||||
if constexpr (sizeof...(DebugArgs) > 0)
|
if constexpr (sizeof...(DebugArgs) > 0)
|
||||||
{
|
{
|
||||||
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Data;
|
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
|
||||||
}
|
}
|
||||||
return GetTypeName<Type>();
|
return GetTypeName<Type>();
|
||||||
}())));
|
}())));
|
||||||
|
|||||||
@@ -28,3 +28,5 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <Core/Common/CoreTypes.h>
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Core/Common/String.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace Juliet
|
||||||
{
|
{
|
||||||
using Thread = std::thread;
|
uint32 thread_id();
|
||||||
|
|
||||||
|
void set_thread_name(String name);
|
||||||
|
|
||||||
// TODO : Proper wait
|
// TODO : Proper wait
|
||||||
inline void wait_ms(int milliseconds)
|
inline void wait_ms(int milliseconds)
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Core/Common/CoreTypes.h>
|
||||||
|
#include <Core/Memory/MemoryArena.h>
|
||||||
|
|
||||||
|
namespace Juliet
|
||||||
|
{
|
||||||
|
struct thread_context
|
||||||
|
{
|
||||||
|
Arena* ScratchArenas[2];
|
||||||
|
|
||||||
|
char ThreadName[64];
|
||||||
|
uint8 ThreadNameSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
thread_context* thread_context_alloc();
|
||||||
|
void thread_context_release(NonNullPtr<thread_context> ctx);
|
||||||
|
void thread_context_select(NonNullPtr<thread_context> ctx);
|
||||||
|
thread_context* thread_context_current();
|
||||||
|
|
||||||
|
Arena* thread_context_get_scratch(Arena** conflicts, size_t count);
|
||||||
|
TempArena scratch_begin(Arena** conflicts, size_t count);
|
||||||
|
void scratch_end(TempArena scratch);
|
||||||
|
} // namespace Juliet
|
||||||
@@ -60,6 +60,7 @@ namespace Juliet
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
// TODO: remove this as we convert to simple unicode decode / encode at the bottom
|
||||||
uint32 StepUTF8(String& inStr)
|
uint32 StepUTF8(String& inStr)
|
||||||
{
|
{
|
||||||
// From rfc3629, the UTF-8 spec:
|
// From rfc3629, the UTF-8 spec:
|
||||||
@@ -92,7 +93,7 @@ namespace Juliet
|
|||||||
}
|
}
|
||||||
if ((octet & 0x80) == 0x0) // One byte code point: 0xxxxxxx
|
if ((octet & 0x80) == 0x0) // One byte code point: 0xxxxxxx
|
||||||
{
|
{
|
||||||
inStr.Data += 1;
|
inStr.Str += 1;
|
||||||
inStr.Size -= 1;
|
inStr.Size -= 1;
|
||||||
return octet;
|
return octet;
|
||||||
}
|
}
|
||||||
@@ -104,7 +105,7 @@ namespace Juliet
|
|||||||
const uint32 result = ((octet & 0x1F) << 6) | (secondByte & 0x3F);
|
const uint32 result = ((octet & 0x1F) << 6) | (secondByte & 0x3F);
|
||||||
if (result >= 0x80) // If the result is smaller than 0x80 its an overlong!
|
if (result >= 0x80) // If the result is smaller than 0x80 its an overlong!
|
||||||
{
|
{
|
||||||
inStr.Data += 2;
|
inStr.Str += 2;
|
||||||
inStr.Size -= 1;
|
inStr.Size -= 1;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -131,7 +132,7 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
if ((result < 0xD800) || (result > 0xDFFF)) // If out of range its an UTF-16 surrogate
|
if ((result < 0xD800) || (result > 0xDFFF)) // If out of range its an UTF-16 surrogate
|
||||||
{
|
{
|
||||||
inStr.Data += 3;
|
inStr.Str += 3;
|
||||||
inStr.Size -= 1;
|
inStr.Size -= 1;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -164,7 +165,7 @@ namespace Juliet
|
|||||||
const uint32 result = ((octet & 0x07) << 18) | secondOctet | thirdOctet | fourthOctet;
|
const uint32 result = ((octet & 0x07) << 18) | secondOctet | thirdOctet | fourthOctet;
|
||||||
if (result >= 0x10000) // If smaller its an overlong
|
if (result >= 0x10000) // If smaller its an overlong
|
||||||
{
|
{
|
||||||
inStr.Data += 4;
|
inStr.Str += 4;
|
||||||
inStr.Size -= 1;
|
inStr.Size -= 1;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -180,7 +181,7 @@ namespace Juliet
|
|||||||
}
|
}
|
||||||
LogError(LogCategory::Core, "StepUTF8: Non supported codepoint. IsOverlong: %s. IsInvalid %s. IsUTF16Surrogate %s",
|
LogError(LogCategory::Core, "StepUTF8: Non supported codepoint. IsOverlong: %s. IsInvalid %s. IsUTF16Surrogate %s",
|
||||||
isOverlong ? "true" : "false", isInvalid ? "true" : "false", isUTF16Surrogate ? "true" : "false");
|
isOverlong ? "true" : "false", isInvalid ? "true" : "false", isUTF16Surrogate ? "true" : "false");
|
||||||
inStr.Data += 1;
|
inStr.Str += 1;
|
||||||
return kInvalidUTF8;
|
return kInvalidUTF8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,8 +255,8 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
Assert(IsValid(src));
|
Assert(IsValid(src));
|
||||||
|
|
||||||
const char* srcStr = src.Data;
|
const char* srcStr = src.Str;
|
||||||
char* dstStr = dst.Data;
|
char* dstStr = dst.Str;
|
||||||
size_t remainingCapacity = dst.Capacity;
|
size_t remainingCapacity = dst.Capacity;
|
||||||
|
|
||||||
uint32 character = 0;
|
uint32 character = 0;
|
||||||
@@ -489,13 +490,138 @@ namespace Juliet
|
|||||||
return ConvertString(sourceFormat, destFormat, src, dst, nullTerminate);
|
return ConvertString(sourceFormat, destFormat, src, dst, nullTerminate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
uint8 utf8_class[32] = {
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
UnicodeDecode utf8_decode(uint8* str, size_t max)
|
||||||
|
{
|
||||||
|
// From rfc3629, the UTF-8 spec:
|
||||||
|
// https://www.ietf.org/rfc/rfc3629.txt
|
||||||
|
//
|
||||||
|
// Char. number range | UTF-8 octet sequence
|
||||||
|
// (hexadecimal) | (binary)
|
||||||
|
// --------------------+---------------------------------------------
|
||||||
|
// 0000 0000-0000 007F | 0xxxxxxx
|
||||||
|
// 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
|
||||||
|
// 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
|
// 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
UnicodeDecode result = { 1, uint32Max };
|
||||||
|
uint8 byte = str[0];
|
||||||
|
uint8 byte_class = utf8_class[byte >> 3];
|
||||||
|
switch (byte_class)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
result.Codepoint = byte;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
if (1 < max)
|
||||||
|
{
|
||||||
|
uint8 next_byte = str[1];
|
||||||
|
if (utf8_class[next_byte >> 3] == 0)
|
||||||
|
{
|
||||||
|
result.Codepoint = (byte & bitmask5) << 6;
|
||||||
|
result.Codepoint |= (next_byte & bitmask6);
|
||||||
|
result.Increment = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
if (2 < max)
|
||||||
|
{
|
||||||
|
uint8 next_byte[2] = { str[1], str[2] };
|
||||||
|
if (utf8_class[next_byte[0] >> 3] == 0 && utf8_class[next_byte[1] >> 3] == 0)
|
||||||
|
{
|
||||||
|
result.Codepoint = (byte & bitmask4) << 12;
|
||||||
|
result.Codepoint |= ((next_byte[0] & bitmask6) << 6);
|
||||||
|
result.Codepoint |= (next_byte[1] & bitmask6);
|
||||||
|
result.Increment = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
if (3 < max)
|
||||||
|
{
|
||||||
|
uint8 next_byte[3] = { str[1], str[2], str[3] };
|
||||||
|
if (utf8_class[next_byte[0] >> 3] == 0 && utf8_class[next_byte[1] >> 3] == 0 &&
|
||||||
|
utf8_class[next_byte[2] >> 3] == 0)
|
||||||
|
{
|
||||||
|
result.Codepoint = (byte & bitmask3) << 18;
|
||||||
|
result.Codepoint |= ((next_byte[0] & bitmask6) << 12);
|
||||||
|
result.Codepoint |= ((next_byte[1] & bitmask6) << 6);
|
||||||
|
result.Codepoint |= (next_byte[2] & bitmask6);
|
||||||
|
result.Increment = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 utf16_encode(uint16* str, uint32 codepoint)
|
||||||
|
{
|
||||||
|
Assert(str);
|
||||||
|
uint32 increment = 1;
|
||||||
|
if (codepoint == uint32Max)
|
||||||
|
{
|
||||||
|
str[0] = '?';
|
||||||
|
}
|
||||||
|
else if (codepoint < 0x10000)
|
||||||
|
{
|
||||||
|
str[0] = (uint16)codepoint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 var = codepoint - 0x10000;
|
||||||
|
str[0] = safe_cast_uint16(0xD800 + (var >> 10));
|
||||||
|
str[1] = safe_cast_uint16(0xDC00 + (var & bitmask10));
|
||||||
|
increment = 2;
|
||||||
|
}
|
||||||
|
return increment;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
String StringCopy(NonNullPtr<Arena> arena, String str)
|
String StringCopy(NonNullPtr<Arena> arena, String str)
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
result.Size = str.Size;
|
result.Size = str.Size;
|
||||||
result.Data = static_cast<char*>(ArenaPush(arena, str.Size + 1, alignof(char), true JULIET_DEBUG_PARAM("String")));
|
result.Str = static_cast<char*>(ArenaPush(arena, str.Size + 1, alignof(char), true JULIET_DEBUG_PARAM("String")));
|
||||||
MemCopy(result.Data, str.Data, str.Size);
|
MemCopy(result.Str, str.Str, str.Size);
|
||||||
result.Data[result.Size] = 0;
|
result.Str[result.Size] = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String16 str16_from_8(NonNullPtr<Arena> arena, String8 in)
|
||||||
|
{
|
||||||
|
String16 result = {};
|
||||||
|
if (in.Size > 0)
|
||||||
|
{
|
||||||
|
size_t neededCapacity = in.Size * 2;
|
||||||
|
uint16* str = ArenaPushArray<uint16, false>(arena, neededCapacity + 1);
|
||||||
|
uint8* inStr = (uint8*)in.Str;
|
||||||
|
uint8* inStrEnd = inStr + in.Size;
|
||||||
|
|
||||||
|
UnicodeDecode consumed;
|
||||||
|
uint64 size = 0;
|
||||||
|
for (; inStr < inStrEnd; inStr += consumed.Increment)
|
||||||
|
{
|
||||||
|
consumed = utf8_decode(inStr, inStrEnd - inStr);
|
||||||
|
size += utf16_encode(str + size, consumed.Codepoint);
|
||||||
|
}
|
||||||
|
str[size] = 0;
|
||||||
|
ArenaPop(arena, (neededCapacity - size) * 2);
|
||||||
|
result = { str, size };
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
Assert(!g_CurrentDisplayDevice);
|
Assert(!g_CurrentDisplayDevice);
|
||||||
|
|
||||||
Arena* arena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Display System"));
|
Arena* arena = ArenaAllocate({ .Name = "Display System" });
|
||||||
|
|
||||||
DisplayDevice* candidateDevice = nullptr;
|
DisplayDevice* candidateDevice = nullptr;
|
||||||
DisplayDeviceFactory* candidateFactory = nullptr;
|
DisplayDeviceFactory* candidateFactory = nullptr;
|
||||||
@@ -80,7 +80,7 @@ namespace Juliet
|
|||||||
Assert(g_CurrentDisplayDevice->CreatePlatformWindow);
|
Assert(g_CurrentDisplayDevice->CreatePlatformWindow);
|
||||||
|
|
||||||
Window window = {};
|
Window window = {};
|
||||||
window.Arena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Window"));
|
window.Arena = ArenaAllocate({ .Name = "Window" });
|
||||||
window.Width = width;
|
window.Width = width;
|
||||||
window.Height = height;
|
window.Height = height;
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace Juliet::Win32
|
|||||||
|
|
||||||
int x = CW_USEDEFAULT, y = CW_USEDEFAULT;
|
int x = CW_USEDEFAULT, y = CW_USEDEFAULT;
|
||||||
const int w = window->Width, h = window->Height;
|
const int w = window->Width, h = window->Height;
|
||||||
HWND handle = CreateWindowExA(styleEx, WindowClassPtr, window->Title.Data, style, x, y, w, h, nullptr, nullptr,
|
HWND handle = CreateWindowExA(styleEx, WindowClassPtr, window->Title.Str, style, x, y, w, h, nullptr, nullptr,
|
||||||
instance, nullptr);
|
instance, nullptr);
|
||||||
|
|
||||||
PumpEvents(self);
|
PumpEvents(self);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Juliet
|
|||||||
DWORD attributes = GetFileAttributesA(path);
|
DWORD attributes = GetFileAttributesA(path);
|
||||||
return (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY);
|
return (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
}
|
}
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
String GetBasePath()
|
String GetBasePath()
|
||||||
{
|
{
|
||||||
@@ -71,10 +71,7 @@ namespace Juliet
|
|||||||
// Probe candidate paths for compiled shader directory
|
// Probe candidate paths for compiled shader directory
|
||||||
// 1. Shipping layout: Assets/Shaders/ next to the exe
|
// 1. Shipping layout: Assets/Shaders/ next to the exe
|
||||||
// 2. Dev layout: ../../Assets/compiled/ (exe is in bin/x64Clang-<Config>/)
|
// 2. Dev layout: ../../Assets/compiled/ (exe is in bin/x64Clang-<Config>/)
|
||||||
constexpr const char* kCandidates[] = {
|
constexpr const char* kCandidates[] = { "Assets/Shaders/", "../../Assets/compiled/" };
|
||||||
"Assets/Shaders/",
|
|
||||||
"../../Assets/compiled/"
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const char* candidate : kCandidates)
|
for (const char* candidate : kCandidates)
|
||||||
{
|
{
|
||||||
@@ -103,12 +100,12 @@ namespace Juliet
|
|||||||
if (IsValid(CachedBasePath))
|
if (IsValid(CachedBasePath))
|
||||||
{
|
{
|
||||||
CachedBasePath.Size = 0;
|
CachedBasePath.Size = 0;
|
||||||
SafeFree(CachedBasePath.Data);
|
SafeFree(CachedBasePath.Str);
|
||||||
}
|
}
|
||||||
if (IsValid(CachedAssetBasePath))
|
if (IsValid(CachedAssetBasePath))
|
||||||
{
|
{
|
||||||
CachedAssetBasePath.Size = 0;
|
CachedAssetBasePath.Size = 0;
|
||||||
SafeFree(CachedAssetBasePath.Data);
|
SafeFree(CachedAssetBasePath.Str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace Juliet
|
} // namespace Juliet
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace Juliet::Platform
|
|||||||
|
|
||||||
bool IsAbsolutePath(String path)
|
bool IsAbsolutePath(String path)
|
||||||
{
|
{
|
||||||
if (!path.Data || path.Size == 0)
|
if (!path.Str || path.Size == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ namespace Juliet::Platform
|
|||||||
// A disk designator with a backslash, for example "C:\" or "d:\".
|
// A disk designator with a backslash, for example "C:\" or "d:\".
|
||||||
// A single backslash, for example, "\directory" or "\file.txt". This is also referred to as an absolute path.
|
// A single backslash, for example, "\directory" or "\file.txt". This is also referred to as an absolute path.
|
||||||
// We will only handle the first two. Single backslash is weird.
|
// We will only handle the first two. Single backslash is weird.
|
||||||
const char* pathStr = path.Data;
|
const char* pathStr = path.Str;
|
||||||
size_t pathLen = path.Size;
|
size_t pathLen = path.Size;
|
||||||
|
|
||||||
if (pathLen > 1)
|
if (pathLen > 1)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Juliet::Internal
|
|||||||
|
|
||||||
int64 FileSize(NonNullPtr<IOStreamDataPayload> payload)
|
int64 FileSize(NonNullPtr<IOStreamDataPayload> payload)
|
||||||
{
|
{
|
||||||
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
|
Win32IOStreamDataPayload* win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
|
||||||
LARGE_INTEGER size;
|
LARGE_INTEGER size;
|
||||||
|
|
||||||
if (!GetFileSizeEx(win32Payload->Handle, &size))
|
if (!GetFileSizeEx(win32Payload->Handle, &size))
|
||||||
@@ -38,7 +38,7 @@ namespace Juliet::Internal
|
|||||||
|
|
||||||
int64 FileSeek(NonNullPtr<IOStreamDataPayload> payload, int64 offset, IOStreamSeekPivot pivot)
|
int64 FileSeek(NonNullPtr<IOStreamDataPayload> payload, int64 offset, IOStreamSeekPivot pivot)
|
||||||
{
|
{
|
||||||
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
|
Win32IOStreamDataPayload* win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
|
||||||
if ((pivot == IOStreamSeekPivot::Current) && (win32Payload->SizeLeft > 0))
|
if ((pivot == IOStreamSeekPivot::Current) && (win32Payload->SizeLeft > 0))
|
||||||
{
|
{
|
||||||
offset -= static_cast<int64>(win32Payload->SizeLeft);
|
offset -= static_cast<int64>(win32Payload->SizeLeft);
|
||||||
@@ -69,7 +69,7 @@ namespace Juliet::Internal
|
|||||||
|
|
||||||
size_t FileRead(NonNullPtr<IOStreamDataPayload> payload, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status)
|
size_t FileRead(NonNullPtr<IOStreamDataPayload> payload, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status)
|
||||||
{
|
{
|
||||||
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
|
Win32IOStreamDataPayload* win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
|
||||||
size_t totalNeed = size;
|
size_t totalNeed = size;
|
||||||
size_t totalRead = 0;
|
size_t totalRead = 0;
|
||||||
size_t sizeToReadAhead = 0;
|
size_t sizeToReadAhead = 0;
|
||||||
@@ -133,7 +133,7 @@ namespace Juliet::Internal
|
|||||||
|
|
||||||
size_t FileWrite(NonNullPtr<IOStreamDataPayload> payload, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status)
|
size_t FileWrite(NonNullPtr<IOStreamDataPayload> payload, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status)
|
||||||
{
|
{
|
||||||
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
|
Win32IOStreamDataPayload* win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
|
||||||
DWORD bytes;
|
DWORD bytes;
|
||||||
|
|
||||||
if (win32Payload->SizeLeft)
|
if (win32Payload->SizeLeft)
|
||||||
@@ -204,12 +204,12 @@ namespace Juliet::Internal
|
|||||||
"Mode should have at most 2 characters, one being either r,w or a and the other can only be +");
|
"Mode should have at most 2 characters, one being either r,w or a and the other can only be +");
|
||||||
if (modeLength == 1)
|
if (modeLength == 1)
|
||||||
{
|
{
|
||||||
Assert((mode.Data[0] == 'r' || mode.Data[0] == 'w' || mode.Data[0] == 'a') &&
|
Assert((mode.Str[0] == 'r' || mode.Str[0] == 'w' || mode.Str[0] == 'a') &&
|
||||||
"Invalid Mode. First char is not r,w or a");
|
"Invalid Mode. First char is not r,w or a");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assert((mode.Data[1] == '+' || mode.Data[1] == 'b') && "Invalid Mode. Second char is not +");
|
Assert((mode.Str[1] == '+' || mode.Str[1] == 'b') && "Invalid Mode. Second char is not +");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ namespace Juliet::Internal
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool autoClose = true;
|
constexpr bool autoClose = true;
|
||||||
auto payload = static_cast<Win32IOStreamDataPayload*>(Calloc(1, sizeof(Win32IOStreamDataPayload)));
|
Win32IOStreamDataPayload* payload = static_cast<Win32IOStreamDataPayload*>(Calloc(1, sizeof(Win32IOStreamDataPayload)));
|
||||||
if (!payload)
|
if (!payload)
|
||||||
{
|
{
|
||||||
if (autoClose)
|
if (autoClose)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <Core/HAL/OS/OS.h>
|
#include <Core/HAL/OS/OS.h>
|
||||||
#include <Core/HAL/OS/OS_Private.h>
|
#include <Core/HAL/OS/OS_Private.h>
|
||||||
|
#include <Core/Thread/Thread.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace Juliet
|
||||||
{
|
{
|
||||||
@@ -61,7 +62,18 @@ namespace Juliet
|
|||||||
|
|
||||||
int Bootstrap(EntryPointFunc entryPointFunc, int argc, wchar_t** argv)
|
int Bootstrap(EntryPointFunc entryPointFunc, int argc, wchar_t** argv)
|
||||||
{
|
{
|
||||||
return Internal::OS_Main(entryPointFunc, argc, argv);
|
|
||||||
|
int result = Internal::OS_Main(argc, argv);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
set_thread_name(WrapString("main_thread"));
|
||||||
|
|
||||||
|
result = entryPointFunc(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
Internal::OS_Main_Exit();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Juliet
|
} // namespace Juliet
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ namespace Juliet
|
|||||||
|
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
int OS_Main(EntryPointFunc entryPointFunc, int argc, wchar_t** argv);
|
int OS_Main(int argc, wchar_t** argv);
|
||||||
}
|
void OS_Main_Exit();
|
||||||
|
} // namespace Internal
|
||||||
} // namespace Juliet
|
} // namespace Juliet
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/CoreUtils.h>
|
#include <Core/Common/CoreUtils.h>
|
||||||
|
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||||
#include <Core/HAL/OS/OS.h>
|
#include <Core/HAL/OS/OS.h>
|
||||||
#include <Core/HAL/OS/OS_Private.h>
|
#include <Core/HAL/OS/OS_Private.h>
|
||||||
#include <Core/HAL/Win32.h>
|
#include <Core/HAL/Win32.h>
|
||||||
#include <Core/Logging/LogManager.h>
|
#include <Core/Logging/LogManager.h>
|
||||||
#include <Core/Logging/LogTypes.h>
|
#include <Core/Logging/LogTypes.h>
|
||||||
|
#include <Core/Thread/ThreadContext.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace Juliet
|
||||||
{
|
{
|
||||||
|
Win32_SetThreadDescription_FuncType* Win32_SetThreadDescription_Func = nullptr;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
global RIO_EXTENSION_FUNCTION_TABLE w32_rio_functions = {};
|
RIO_EXTENSION_FUNCTION_TABLE w32_rio_functions = {};
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
namespace Memory::Internal
|
namespace Memory::Internal
|
||||||
{
|
{
|
||||||
@@ -97,7 +101,9 @@ namespace Juliet
|
|||||||
|
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
int OS_Main(EntryPointFunc entryPointFunc, int argc, wchar_t** argv)
|
thread_local thread_context* mainThread = nullptr;
|
||||||
|
|
||||||
|
int OS_Main(int argc, wchar_t** argv)
|
||||||
{
|
{
|
||||||
SetUnhandledExceptionFilter(&ExceptionFilter);
|
SetUnhandledExceptionFilter(&ExceptionFilter);
|
||||||
|
|
||||||
@@ -109,6 +115,11 @@ namespace Juliet
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get some kernel32 functions
|
||||||
|
auto dynLib = LoadDynamicLibrary("kernel32.dll");
|
||||||
|
Win32_SetThreadDescription_Func =
|
||||||
|
(Win32_SetThreadDescription_FuncType*)LoadFunction(dynLib, "SetThreadDescription");
|
||||||
|
|
||||||
// Create a dummy socket to access RIO functions. Those will be used to do fine memory management
|
// Create a dummy socket to access RIO functions. Those will be used to do fine memory management
|
||||||
{
|
{
|
||||||
WSADATA WinSockData;
|
WSADATA WinSockData;
|
||||||
@@ -121,8 +132,17 @@ namespace Juliet
|
|||||||
closesocket(Sock);
|
closesocket(Sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = entryPointFunc(argc, argv);
|
mainThread = thread_context_alloc();
|
||||||
return result;
|
thread_context_select(mainThread);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_Main_Exit()
|
||||||
|
{
|
||||||
|
Assert(mainThread);
|
||||||
|
thread_context_release(mainThread);
|
||||||
|
mainThread = nullptr;
|
||||||
}
|
}
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Juliet
|
} // namespace Juliet
|
||||||
|
|||||||
@@ -75,3 +75,5 @@
|
|||||||
|
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
|
||||||
|
using Win32_SetThreadDescription_FuncType = HRESULT(HANDLE hThread, PCWSTR lpThreadDescription);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename)
|
void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename)
|
||||||
{
|
{
|
||||||
code.Arena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_ONLY(, "Hot Reload"));
|
code.Arena = ArenaAllocate({ .ReserveSize = Megabytes(1), .Name = "Hot Reload" });
|
||||||
|
|
||||||
// Get the app base path and build the dll path from there.
|
// Get the app base path and build the dll path from there.
|
||||||
String basePath = GetBasePath();
|
String basePath = GetBasePath();
|
||||||
@@ -25,7 +25,7 @@ namespace Juliet
|
|||||||
const size_t dllFullPathLength =
|
const size_t dllFullPathLength =
|
||||||
basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
|
basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
|
||||||
|
|
||||||
code.DLLFullPath.Data =
|
code.DLLFullPath.Str =
|
||||||
static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_PARAM("DLL Path")));
|
static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_PARAM("DLL Path")));
|
||||||
int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
|
int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
|
||||||
if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
|
if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
|
||||||
@@ -39,7 +39,7 @@ namespace Juliet
|
|||||||
// Lock filename path
|
// Lock filename path
|
||||||
const size_t lockPathLength =
|
const size_t lockPathLength =
|
||||||
basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
|
basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
|
||||||
code.LockFullPath.Data =
|
code.LockFullPath.Str =
|
||||||
static_cast<char*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_PARAM("Lock File Path")));
|
static_cast<char*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_PARAM("Lock File Path")));
|
||||||
writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
|
writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
|
||||||
if (writtenSize < static_cast<int>(lockPathLength) - 1)
|
if (writtenSize < static_cast<int>(lockPathLength) - 1)
|
||||||
|
|||||||
@@ -34,11 +34,11 @@ namespace Juliet
|
|||||||
// TODO : Create and use a TransientAllocator
|
// TODO : Create and use a TransientAllocator
|
||||||
// Create temp dll name
|
// Create temp dll name
|
||||||
|
|
||||||
char* lockFilename = code.LockFullPath.Data;
|
char* lockFilename = code.LockFullPath.Str;
|
||||||
WIN32_FILE_ATTRIBUTE_DATA Ignored;
|
WIN32_FILE_ATTRIBUTE_DATA Ignored;
|
||||||
if (!GetFileAttributesExA(lockFilename, GetFileExInfoStandard, &Ignored))
|
if (!GetFileAttributesExA(lockFilename, GetFileExInfoStandard, &Ignored))
|
||||||
{
|
{
|
||||||
const char* dllName = code.DLLFullPath.Data;
|
const char* dllName = code.DLLFullPath.Str;
|
||||||
|
|
||||||
FILETIME lastWriteTime = GetLastWriteTime(dllName);
|
FILETIME lastWriteTime = GetLastWriteTime(dllName);
|
||||||
ULARGE_INTEGER result{ .LowPart = lastWriteTime.dwLowDateTime, .HighPart = lastWriteTime.dwHighDateTime };
|
ULARGE_INTEGER result{ .LowPart = lastWriteTime.dwLowDateTime, .HighPart = lastWriteTime.dwHighDateTime };
|
||||||
@@ -145,7 +145,7 @@ namespace Juliet
|
|||||||
codeLastWriteTime.dwHighDateTime = largeInt.HighPart;
|
codeLastWriteTime.dwHighDateTime = largeInt.HighPart;
|
||||||
codeLastWriteTime.dwLowDateTime = largeInt.LowPart;
|
codeLastWriteTime.dwLowDateTime = largeInt.LowPart;
|
||||||
|
|
||||||
FILETIME lastWriteTime = GetLastWriteTime(code.DLLFullPath.Data);
|
FILETIME lastWriteTime = GetLastWriteTime(code.DLLFullPath.Str);
|
||||||
int compare = CompareFileTime(&lastWriteTime, &codeLastWriteTime);
|
int compare = CompareFileTime(&lastWriteTime, &codeLastWriteTime);
|
||||||
return compare != 0;
|
return compare != 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ namespace Juliet::ImGuiService
|
|||||||
Assert(!g_Initialized);
|
Assert(!g_Initialized);
|
||||||
|
|
||||||
// Initialize ImGui Arena using Engine Pool
|
// Initialize ImGui Arena using Engine Pool
|
||||||
g_ImGuiArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "ImGui"));
|
g_ImGuiArena = ArenaAllocate({ .Name = "Juliet" });
|
||||||
|
|
||||||
// Setup Allocator
|
// Setup Allocator
|
||||||
ImGui::SetAllocatorFunctions(ImGuiAllocWrapper, ImGuiFreeWrapper, nullptr);
|
ImGui::SetAllocatorFunctions(ImGuiAllocWrapper, ImGuiFreeWrapper, nullptr);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace Juliet
|
|||||||
|
|
||||||
Logs* LogAllocate()
|
Logs* LogAllocate()
|
||||||
{
|
{
|
||||||
Arena* arena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Log Manager"));
|
Arena* arena = ArenaAllocate({ .Name = "Log Manager" });
|
||||||
Logs* logs = ArenaPushStruct<Logs>(arena);
|
Logs* logs = ArenaPushStruct<Logs>(arena);
|
||||||
logs->Arena = arena;
|
logs->Arena = arena;
|
||||||
return logs;
|
return logs;
|
||||||
|
|||||||
@@ -18,17 +18,15 @@ namespace Juliet
|
|||||||
|
|
||||||
// https://github.com/EpicGamesExt/raddebugger/blob/master/src/base/base_arena.c
|
// https://github.com/EpicGamesExt/raddebugger/blob/master/src/base/base_arena.c
|
||||||
|
|
||||||
Arena* ArenaAllocate(const ArenaParams& params JULIET_DEBUG_ONLY(, const char* name), const std::source_location& loc)
|
Arena* ArenaAllocate(const ArenaParams& params, const std::source_location& loc)
|
||||||
{
|
{
|
||||||
Log(LogLevel::Message, LogCategory::Core, "Allocating from %s : %ul", loc.file_name(), loc.line());
|
Log(LogLevel::Message, LogCategory::Core, "Allocating from %s : %ul", loc.file_name(), loc.line());
|
||||||
|
|
||||||
Byte* baseMem = nullptr;
|
|
||||||
|
|
||||||
uint64 reserve_size = AlignPow2(params.ReserveSize, k_PageSize);
|
uint64 reserve_size = AlignPow2(params.ReserveSize, k_PageSize);
|
||||||
uint64 commit_size = AlignPow2(params.CommitSize, k_PageSize);
|
uint64 commit_size = AlignPow2(params.CommitSize, k_PageSize);
|
||||||
|
|
||||||
// TODO: handle large pages
|
// TODO: handle large pages
|
||||||
baseMem = Memory::OS_Reserve(reserve_size);
|
Byte* baseMem = Memory::OS_Reserve(reserve_size);
|
||||||
Memory::OS_Commit(baseMem, commit_size);
|
Memory::OS_Commit(baseMem, commit_size);
|
||||||
|
|
||||||
Arena* arena = reinterpret_cast<Arena*>(baseMem);
|
Arena* arena = reinterpret_cast<Arena*>(baseMem);
|
||||||
@@ -47,7 +45,16 @@ namespace Juliet
|
|||||||
arena->CanReserveMore = params.CanReserveMore;
|
arena->CanReserveMore = params.CanReserveMore;
|
||||||
arena->FirstDebugInfo = nullptr;
|
arena->FirstDebugInfo = nullptr;
|
||||||
|
|
||||||
DebugArenaSetDebugName(arena, name);
|
if (params.Name == nullptr)
|
||||||
|
{
|
||||||
|
arena->Name = "NoName";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arena->Name = params.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugArenaSetDebugName(arena, arena->Name);
|
||||||
DebugRegisterArena(arena);
|
DebugRegisterArena(arena);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -112,8 +119,7 @@ namespace Juliet
|
|||||||
commitSize = AlignPow2(size + k_ArenaHeaderSize, align);
|
commitSize = AlignPow2(size + k_ArenaHeaderSize, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
newBlock =
|
newBlock = ArenaAllocate({ .ReserveSize = reserveSize, .CommitSize = commitSize, .Name = arena->Name });
|
||||||
ArenaAllocate({ .ReserveSize = reserveSize, .CommitSize = commitSize } JULIET_DEBUG_ONLY(, arena->Name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newBlock->BasePosition = current->BasePosition + current->Reserved;
|
newBlock->BasePosition = current->BasePosition + current->Reserved;
|
||||||
@@ -152,7 +158,8 @@ namespace Juliet
|
|||||||
result = reinterpret_cast<Byte*>(current) + positionPrePush;
|
result = reinterpret_cast<Byte*>(current) + positionPrePush;
|
||||||
current->Position = positionPostPush;
|
current->Position = positionPostPush;
|
||||||
|
|
||||||
JULIET_DEBUG_ONLY(if (!IsDebugInfoArena(arena)) { DebugArenaAddDebugInfo(current, size, positionPrePush, tag); })
|
JULIET_DEBUG_ONLY(
|
||||||
|
if (!IsDebugInfoArena(arena)) { DebugArenaAddDebugInfo(current, size, positionPrePush, tag); })
|
||||||
|
|
||||||
if (sizeToZero != 0)
|
if (sizeToZero != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ namespace Juliet
|
|||||||
if (!g_DebugInfoArena)
|
if (!g_DebugInfoArena)
|
||||||
{
|
{
|
||||||
// Create a dedicated arena for debug info
|
// Create a dedicated arena for debug info
|
||||||
g_DebugInfoArena = ArenaAllocate(
|
g_DebugInfoArena =
|
||||||
{ .ReserveSize = Megabytes(16), .CommitSize = Kilobytes(64) } JULIET_DEBUG_ONLY(, "Debug Info Arena"));
|
ArenaAllocate({ .ReserveSize = Megabytes(16), .CommitSize = Kilobytes(64), .Name = "Debug Info Arena" });
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArenaPushStruct<ArenaDebugInfo>(g_DebugInfoArena JULIET_DEBUG_PARAM("ArenaDebugInfo"));
|
return ArenaPushStruct<ArenaDebugInfo>(g_DebugInfoArena JULIET_DEBUG_PARAM("ArenaDebugInfo"));
|
||||||
@@ -35,8 +35,8 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
if (!g_DebugInfoArena)
|
if (!g_DebugInfoArena)
|
||||||
{
|
{
|
||||||
g_DebugInfoArena = ArenaAllocate(
|
g_DebugInfoArena =
|
||||||
{ .ReserveSize = Megabytes(16), .CommitSize = Kilobytes(64) } JULIET_DEBUG_ONLY(, "Debug Info Arena"));
|
ArenaAllocate({ .ReserveSize = Megabytes(16), .CommitSize = Kilobytes(64), .Name = "Debug Info Arena" });
|
||||||
}
|
}
|
||||||
return g_DebugInfoArena;
|
return g_DebugInfoArena;
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ namespace Juliet
|
|||||||
if (tag)
|
if (tag)
|
||||||
{
|
{
|
||||||
String copiedTag = StringCopy(g_DebugInfoArena, WrapString(tag));
|
String copiedTag = StringCopy(g_DebugInfoArena, WrapString(tag));
|
||||||
info->Tag = copiedTag.Data;
|
info->Tag = copiedTag.Str;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ namespace Juliet::UnitTest
|
|||||||
printf("Running Paged Memory Arena Tests...\n");
|
printf("Running Paged Memory Arena Tests...\n");
|
||||||
|
|
||||||
// New Arena!
|
// New Arena!
|
||||||
ArenaParams param{ .ReserveSize = Megabytes(64llu), .CommitSize = Kilobytes(64llu) };
|
ArenaParams param{ .ReserveSize = Megabytes(64llu), .CommitSize = Kilobytes(64llu), .Name = "Test Arena" };
|
||||||
Arena* testArena = ArenaAllocate(param JULIET_DEBUG_ONLY(, "Test Arena"));
|
Arena* testArena = ArenaAllocate(param);
|
||||||
|
|
||||||
size_t pos = ArenaPos(testArena);
|
size_t pos = ArenaPos(testArena);
|
||||||
Assert(pos == k_ArenaHeaderSize);
|
Assert(pos == k_ArenaHeaderSize);
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#include <Core/Thread/ThreadContext.h>
|
||||||
|
|
||||||
|
#include <Core/Thread/Thread.h>
|
||||||
|
|
||||||
|
namespace Juliet
|
||||||
|
{
|
||||||
|
thread_local thread_context* local_thread_context;
|
||||||
|
|
||||||
|
thread_context* thread_context_alloc()
|
||||||
|
{
|
||||||
|
thread_local char name[2][1024];
|
||||||
|
juliet_snprintf(name[0], sizeof(name[0]), "Scratch/0[TID:%u]", thread_id());
|
||||||
|
juliet_snprintf(name[1], sizeof(name[1]), "Scratch/1[TID:%u]", thread_id());
|
||||||
|
Arena* arena_0 = ArenaAllocate({ .Name = name[0] });
|
||||||
|
Arena* arena_1 = ArenaAllocate({ .Name = name[1] });
|
||||||
|
|
||||||
|
thread_context* ctx = ArenaPushStruct<thread_context>(arena_0);
|
||||||
|
ctx->ScratchArenas[0] = arena_0;
|
||||||
|
ctx->ScratchArenas[1] = arena_1;
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_context_release(NonNullPtr<thread_context> ctx)
|
||||||
|
{
|
||||||
|
ArenaRelease(ctx->ScratchArenas[1]);
|
||||||
|
ArenaRelease(ctx->ScratchArenas[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_context_select(NonNullPtr<thread_context> ctx)
|
||||||
|
{
|
||||||
|
local_thread_context = ctx.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_context* thread_context_current()
|
||||||
|
{
|
||||||
|
Assert(local_thread_context);
|
||||||
|
return local_thread_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arena* thread_context_get_scratch(Arena** conflicts, size_t count)
|
||||||
|
{
|
||||||
|
thread_context* ctx = thread_context_current();
|
||||||
|
Arena* result = nullptr;
|
||||||
|
Arena** arena_ptr = ctx->ScratchArenas;
|
||||||
|
for (size_t i = 0; i < ArraySize(ctx->ScratchArenas); i += 1, arena_ptr += 1)
|
||||||
|
{
|
||||||
|
Arena** conflict_ptr = conflicts;
|
||||||
|
bool has_conflict = false;
|
||||||
|
for (size_t j = 0; j < count; j += 1, conflict_ptr += 1)
|
||||||
|
{
|
||||||
|
if (*arena_ptr == *conflict_ptr)
|
||||||
|
{
|
||||||
|
has_conflict = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!has_conflict)
|
||||||
|
{
|
||||||
|
result = *arena_ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TempArena scratch_begin(Arena** conflicts, size_t count)
|
||||||
|
{
|
||||||
|
return ArenaTempBegin(thread_context_get_scratch(conflicts, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
void scratch_end(TempArena scratch)
|
||||||
|
{
|
||||||
|
ArenaTempEnd(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Juliet
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include <Core/Thread/Thread.h>
|
||||||
|
|
||||||
|
#include <Core/HAL/Win32.h>
|
||||||
|
#include <Core/Thread/ThreadContext.h>
|
||||||
|
|
||||||
|
#include <processthreadsapi.h>
|
||||||
|
|
||||||
|
namespace Juliet
|
||||||
|
{
|
||||||
|
uint32 thread_id()
|
||||||
|
{
|
||||||
|
uint32 id = GetCurrentThreadId();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern Win32_SetThreadDescription_FuncType* Win32_SetThreadDescription_Func;
|
||||||
|
|
||||||
|
void set_thread_name(String name)
|
||||||
|
{
|
||||||
|
TempArena scratch = scratch_begin(0, 0);
|
||||||
|
|
||||||
|
// New way:
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
|
||||||
|
// Old way:
|
||||||
|
// https://learn.microsoft.com/fr-fr/previous-versions/visualstudio/visual-studio-2015/debugger/how-to-set-a-thread-name-in-native-code?view=vs-2015&redirectedfrom=MSDN
|
||||||
|
|
||||||
|
if (Win32_SetThreadDescription_Func != nullptr)
|
||||||
|
{
|
||||||
|
String16 name16 = str16_from_8(scratch.Arena, name);
|
||||||
|
Win32_SetThreadDescription_Func(GetCurrentThread(), (WCHAR*)name16.Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 name_copy = StringCopy(scratch.Arena, name);
|
||||||
|
|
||||||
|
#pragma pack(push, 8)
|
||||||
|
struct THREADNAME_INFO
|
||||||
|
{
|
||||||
|
DWORD dwType; // Must be 0x1000.
|
||||||
|
LPCSTR szName; // Pointer to name (in user addr space).
|
||||||
|
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||||
|
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
THREADNAME_INFO info;
|
||||||
|
info.dwType = 0x1000;
|
||||||
|
info.szName = CStr(name_copy);
|
||||||
|
info.dwThreadID = thread_id();
|
||||||
|
info.dwFlags = 0;
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 6320 6322)
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Juliet
|
||||||
@@ -46,7 +46,7 @@ namespace Juliet::Debug
|
|||||||
{
|
{
|
||||||
if (s_PagedArenaStates.Arena == nullptr)
|
if (s_PagedArenaStates.Arena == nullptr)
|
||||||
{
|
{
|
||||||
Arena* pagedArenaStates = ArenaAllocate({} JULIET_DEBUG_ONLY(, "DebugState States"));
|
Arena* pagedArenaStates = ArenaAllocate({ .Name = "DebugState States" });
|
||||||
s_PagedArenaStates.Create(pagedArenaStates);
|
s_PagedArenaStates.Create(pagedArenaStates);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ namespace Juliet::Debug
|
|||||||
static VectorArena<const Arena*> blocks;
|
static VectorArena<const Arena*> blocks;
|
||||||
if (blocks.Arena == nullptr)
|
if (blocks.Arena == nullptr)
|
||||||
{
|
{
|
||||||
Arena* pagedArenaStates = ArenaAllocate({} JULIET_DEBUG_ONLY(, "DebugState Blocks"));
|
Arena* pagedArenaStates = ArenaAllocate({ .Name = "DebugState Blocks" });
|
||||||
blocks.Create(pagedArenaStates);
|
blocks.Create(pagedArenaStates);
|
||||||
}
|
}
|
||||||
blocks.Clear();
|
blocks.Clear();
|
||||||
|
|||||||
@@ -151,10 +151,8 @@ namespace Juliet
|
|||||||
|
|
||||||
void InitializeEngine(JulietInit_Flags flags)
|
void InitializeEngine(JulietInit_Flags flags)
|
||||||
{
|
{
|
||||||
EngineInstance.PlatformArena =
|
EngineInstance.PlatformArena = ArenaAllocate({ .ReserveSize = Megabytes(128), .Name = "Platform Arena" });
|
||||||
ArenaAllocate({ .ReserveSize = Megabytes(128) } JULIET_DEBUG_PARAM("Platform Arena"));
|
EngineInstance.AssetArena = ArenaAllocate({ .ReserveSize = Megabytes(256), .Name = "Asset Arena" });
|
||||||
EngineInstance.AssetArena =
|
|
||||||
ArenaAllocate({ .ReserveSize = Megabytes(256) } JULIET_DEBUG_PARAM("Asset Arena"));
|
|
||||||
|
|
||||||
InitializeLogManager();
|
InitializeLogManager();
|
||||||
|
|
||||||
|
|||||||
@@ -4230,7 +4230,6 @@ namespace Juliet
|
|||||||
|
|
||||||
driver->D3D12SerializeVersionedRootSignatureFct = nullptr;
|
driver->D3D12SerializeVersionedRootSignatureFct = nullptr;
|
||||||
|
|
||||||
Assert(ArenaPos(driver->DriverArena) == sizeof(D3D12Driver)); // Verify we didnt forget to release something
|
|
||||||
ArenaRelease(driver->DriverArena);
|
ArenaRelease(driver->DriverArena);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4314,7 +4313,7 @@ namespace Juliet
|
|||||||
|
|
||||||
GraphicsDevice* D3D12_CreateGraphicsDevice(bool enableDebug)
|
GraphicsDevice* D3D12_CreateGraphicsDevice(bool enableDebug)
|
||||||
{
|
{
|
||||||
Arena* driverArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "D3D12 Driver Arena"));
|
Arena* driverArena = ArenaAllocate({ .Name = "D3D12 Driver Arena" });
|
||||||
D3D12Driver* driver = ArenaPushStruct<D3D12Driver>(driverArena JULIET_DEBUG_PARAM("D3D12Driver struct"));
|
D3D12Driver* driver = ArenaPushStruct<D3D12Driver>(driverArena JULIET_DEBUG_PARAM("D3D12Driver struct"));
|
||||||
|
|
||||||
driver->DriverArena = driverArena;
|
driver->DriverArena = driverArena;
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ namespace Juliet
|
|||||||
// TODO: Add path builder in the lib
|
// TODO: Add path builder in the lib
|
||||||
String base = GetBasePath();
|
String base = GetBasePath();
|
||||||
char inplaceBuffer[256];
|
char inplaceBuffer[256];
|
||||||
snprintf(inplaceBuffer, sizeof(inplaceBuffer), "%s%s", base.Data, filename.Data);
|
snprintf(inplaceBuffer, sizeof(inplaceBuffer), "%s%s", base.Str, filename.Str);
|
||||||
String absolutePath = WrapString(inplaceBuffer);
|
String absolutePath = WrapString(inplaceBuffer);
|
||||||
shaderByteCode = LoadFile(absolutePath);
|
shaderByteCode = LoadFile(absolutePath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ namespace Juliet::UnitTest
|
|||||||
|
|
||||||
void VectorUnitTest()
|
void VectorUnitTest()
|
||||||
{
|
{
|
||||||
ArenaParams params{};
|
ArenaParams params{ .Name = "VectorUnitTestArena" };
|
||||||
Arena* testArena = ArenaAllocate(params JULIET_DEBUG_ONLY(, "VectorUnitTestArena"));
|
Arena* testArena = ArenaAllocate(params);
|
||||||
|
|
||||||
// Test 1: Integer VectorArena (Basic Operations)
|
// Test 1: Integer VectorArena (Basic Operations)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user