Various conversion to memory arena and misc clean up
This commit is contained in:
@@ -47,10 +47,11 @@ namespace Juliet
|
||||
bool (*Close)(NonNullPtr<IOStreamDataPayload> data);
|
||||
};
|
||||
|
||||
extern JULIET_API IOStream* IOFromFile(String filename, String mode);
|
||||
extern JULIET_API IOStream* IOFromFile(NonNullPtr<Arena> arena, String filename, String mode);
|
||||
|
||||
// Let you use an interface to open any io. Is used internally by IOFromFile
|
||||
extern JULIET_API IOStream* IOFromInterface(NonNullPtr<const IOStreamInterface> streamInterface, NonNullPtr<IOStreamDataPayload> payload);
|
||||
extern JULIET_API IOStream* IOFromInterface(NonNullPtr<Arena> arena, NonNullPtr<const IOStreamInterface> streamInterface,
|
||||
NonNullPtr<IOStreamDataPayload> payload);
|
||||
|
||||
// Write formatted string into the stream.
|
||||
extern JULIET_API size_t IOPrintf(NonNullPtr<IOStream> stream, _Printf_format_string_ const char* format, ...);
|
||||
@@ -61,9 +62,8 @@ namespace Juliet
|
||||
|
||||
extern JULIET_API int64 IOSize(NonNullPtr<IOStream> stream);
|
||||
|
||||
// TODO : Use memory arena because that Allocates
|
||||
extern JULIET_API ByteBuffer LoadFile(String filename);
|
||||
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<IOStream> stream, bool closeStreamWhenDone);
|
||||
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, String filename);
|
||||
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, NonNullPtr<IOStream> stream, bool closeStreamWhenDone);
|
||||
|
||||
extern JULIET_API bool IOClose(NonNullPtr<IOStream> stream);
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -9,8 +9,6 @@ namespace Juliet
|
||||
|
||||
struct HotReloadCode
|
||||
{
|
||||
Arena* Arena;
|
||||
|
||||
String DLLFullPath;
|
||||
String LockFullPath;
|
||||
String TransientDLLName;
|
||||
@@ -28,7 +26,8 @@ namespace Juliet
|
||||
bool IsValid : 1;
|
||||
};
|
||||
|
||||
extern JULIET_API void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename);
|
||||
extern JULIET_API void InitHotReloadCode(NonNullPtr<Arena> arena, HotReloadCode& code, String dllName,
|
||||
String transientDllName, String lockFilename);
|
||||
extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code);
|
||||
|
||||
extern JULIET_API void LoadCode(HotReloadCode& code);
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
#include <Core/HAL/IO/IOStream.h>
|
||||
|
||||
#include <Core/Common/String.h>
|
||||
#include <Core/HAL/IO/IOStream_Private.h>
|
||||
#include <Core/HAL/IO/IOStream_cpp.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Thread/Thread.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
IOStream* IOFromFile(String filename, String mode)
|
||||
IOStream* IOFromFile(NonNullPtr<Arena> arena, String filename, String mode)
|
||||
{
|
||||
if (!IsValid(filename))
|
||||
{
|
||||
@@ -22,14 +21,14 @@ namespace Juliet
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Internal::IOFromFile(filename, mode);
|
||||
return Internal::IOFromFile(arena, filename, mode);
|
||||
}
|
||||
|
||||
IOStream* IOFromInterface(NonNullPtr<const IOStreamInterface> streamInterface, NonNullPtr<IOStreamDataPayload> payload)
|
||||
IOStream* IOFromInterface(NonNullPtr<Arena> arena, NonNullPtr<const IOStreamInterface> streamInterface,
|
||||
NonNullPtr<IOStreamDataPayload> payload)
|
||||
{
|
||||
Assert(streamInterface->Version >= sizeof(*streamInterface.Get()));
|
||||
|
||||
auto stream = static_cast<IOStream*>(Calloc(1, sizeof(IOStream)));
|
||||
auto stream = ArenaPushStruct<IOStream>(arena);
|
||||
if (stream)
|
||||
{
|
||||
IOStreamInterface* dstInterface = &stream->Interface;
|
||||
@@ -132,23 +131,19 @@ namespace Juliet
|
||||
return stream->Interface.Size(stream->Data);
|
||||
}
|
||||
|
||||
ByteBuffer LoadFile(String filename)
|
||||
ByteBuffer LoadFile(NonNullPtr<Arena> arena, String filename)
|
||||
{
|
||||
IOStream* stream = IOFromFile(filename, WrapString("rb"));
|
||||
IOStream* stream = IOFromFile(arena, filename, WrapString("rb"));
|
||||
if (!stream)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
return LoadFile(stream, true);
|
||||
return LoadFile(arena, stream, true);
|
||||
}
|
||||
|
||||
ByteBuffer LoadFile(NonNullPtr<IOStream> stream, bool closeStreamWhenDone)
|
||||
ByteBuffer LoadFile(NonNullPtr<Arena> arena, NonNullPtr<IOStream> stream, bool closeStreamWhenDone)
|
||||
{
|
||||
constexpr size_t kFileChunkSize = 1024;
|
||||
uint8* data = nullptr;
|
||||
uint8* newData = nullptr;
|
||||
size_t totalSize = 0;
|
||||
ByteBuffer resultBuffer = {};
|
||||
|
||||
auto deferred = Defer(
|
||||
[&]()
|
||||
@@ -168,12 +163,13 @@ namespace Juliet
|
||||
loadChunks = true;
|
||||
}
|
||||
size_t size = static_cast<size_t>(ssize);
|
||||
data = static_cast<uint8*>(Malloc(static_cast<size_t>(size + 1)));
|
||||
uint8* data = ArenaPushArray<uint8, false>(arena, size + 1);
|
||||
if (!data)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
size_t totalSize = 0;
|
||||
while (true)
|
||||
{
|
||||
if (loadChunks)
|
||||
@@ -181,13 +177,13 @@ namespace Juliet
|
||||
if ((totalSize + kFileChunkSize) > size)
|
||||
{
|
||||
size = totalSize + kFileChunkSize;
|
||||
newData = static_cast<uint8*>(Realloc(data, static_cast<size_t>(size + 1)));
|
||||
if (!newData)
|
||||
|
||||
// Not enough space, add some
|
||||
uint8* newSpace = ArenaPushArray<uint8, false>(arena, kFileChunkSize);
|
||||
if (!newSpace)
|
||||
{
|
||||
Free(data);
|
||||
return {};
|
||||
}
|
||||
data = newData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,9 +207,9 @@ namespace Juliet
|
||||
// Adding null terminator
|
||||
data[totalSize] = '\0';
|
||||
|
||||
ByteBuffer resultBuffer = {};
|
||||
resultBuffer.Data = reinterpret_cast<Byte*>(data);
|
||||
resultBuffer.Size = totalSize;
|
||||
|
||||
return resultBuffer;
|
||||
}
|
||||
|
||||
@@ -224,7 +220,6 @@ namespace Juliet
|
||||
{
|
||||
result = stream->Interface.Close(stream->Data);
|
||||
}
|
||||
Free(stream.Get());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,5 +15,5 @@ namespace Juliet
|
||||
|
||||
namespace Juliet::Internal
|
||||
{
|
||||
IOStream* IOFromFile(String filename, String mode);
|
||||
IOStream* IOFromFile(NonNullPtr<Arena> arena, String filename, String mode);
|
||||
} // namespace Juliet::Internal
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <Core/HAL/Win32.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
|
||||
namespace Juliet::Internal
|
||||
{
|
||||
@@ -181,14 +180,12 @@ namespace Juliet::Internal
|
||||
}
|
||||
win32Payload->Handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
SafeFree(win32Payload->Data);
|
||||
SafeFree(win32Payload);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
IOStream* IOFromFile(String filename, String mode)
|
||||
IOStream* IOFromFile(NonNullPtr<Arena> arena, String filename, String mode)
|
||||
{
|
||||
// "r" = reading, file must exist
|
||||
// "w" = writing, truncate existing, file may not exist
|
||||
@@ -238,7 +235,7 @@ namespace Juliet::Internal
|
||||
}
|
||||
|
||||
constexpr bool autoClose = true;
|
||||
Win32IOStreamDataPayload* payload = static_cast<Win32IOStreamDataPayload*>(Calloc(1, sizeof(Win32IOStreamDataPayload)));
|
||||
Win32IOStreamDataPayload* payload = ArenaPushStruct<Win32IOStreamDataPayload>(arena);
|
||||
if (!payload)
|
||||
{
|
||||
if (autoClose)
|
||||
@@ -263,14 +260,14 @@ namespace Juliet::Internal
|
||||
payload->IsAppending = isAppending;
|
||||
payload->ShouldAutoClose = autoClose;
|
||||
|
||||
payload->Data = static_cast<char*>(Malloc(kFileReadBufferSize));
|
||||
payload->Data = ArenaPushArray<char, false>(arena, kFileReadBufferSize);
|
||||
if (!payload->Data)
|
||||
{
|
||||
iface.Close(payload);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IOStream* stream = IOFromInterface(&iface, payload);
|
||||
IOStream* stream = IOFromInterface(arena, &iface, payload);
|
||||
if (!stream)
|
||||
{
|
||||
iface.Close(payload);
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Juliet
|
||||
{
|
||||
thread_local thread_context* mainThread = nullptr;
|
||||
|
||||
int OS_Main(int argc, wchar_t** argv)
|
||||
int OS_Main([[maybe_unused]] int argc, [[maybe_unused]] wchar_t** argv)
|
||||
{
|
||||
SetUnhandledExceptionFilter(&ExceptionFilter);
|
||||
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename)
|
||||
void InitHotReloadCode(NonNullPtr<Arena> arena, HotReloadCode& code, String dllName, String transientDllName, String lockFilename)
|
||||
{
|
||||
code.Arena = ArenaAllocate({ .ReserveSize = Megabytes(1), .Name = "Hot Reload" });
|
||||
|
||||
// Get the app base path and build the dll path from there.
|
||||
String basePath = GetBasePath();
|
||||
size_t basePathLength = StringLength(basePath);
|
||||
@@ -25,12 +23,11 @@ namespace Juliet
|
||||
const size_t dllFullPathLength =
|
||||
basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
|
||||
|
||||
code.DLLFullPath.Str =
|
||||
static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_PARAM("DLL Path")));
|
||||
code.DLLFullPath.Str = static_cast<char*>(
|
||||
ArenaPush(arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_PARAM("Hot Reload DLL Path")));
|
||||
int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
|
||||
if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
|
||||
{
|
||||
// Arena memory persists, no free needed
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create DLL Full Path");
|
||||
return;
|
||||
}
|
||||
@@ -39,13 +36,12 @@ namespace Juliet
|
||||
// Lock filename path
|
||||
const size_t lockPathLength =
|
||||
basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
|
||||
code.LockFullPath.Str =
|
||||
static_cast<char*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_PARAM("Lock File Path")));
|
||||
code.LockFullPath.Str = static_cast<char*>(
|
||||
ArenaPush(arena, lockPathLength, alignof(char), true JULIET_DEBUG_PARAM("Hot Reload Lock File Path")));
|
||||
writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
|
||||
if (writtenSize < static_cast<int>(lockPathLength) - 1)
|
||||
{
|
||||
code.LockFullPath.Size = 0;
|
||||
// Arena memory persists, no free needed
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create lock file full path");
|
||||
return;
|
||||
}
|
||||
@@ -59,11 +55,7 @@ namespace Juliet
|
||||
UnloadCode(code);
|
||||
|
||||
code.DLLFullPath.Size = 0;
|
||||
// Arena memory persists until engine shutdown
|
||||
code.LockFullPath.Size = 0;
|
||||
// Arena memory persists until engine shutdown
|
||||
|
||||
ArenaRelease(code.Arena);
|
||||
}
|
||||
|
||||
void ReloadCode(HotReloadCode& code)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Core/Thread/ThreadContext.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -31,9 +32,6 @@ namespace Juliet
|
||||
|
||||
void LoadCode(HotReloadCode& code)
|
||||
{
|
||||
// TODO : Create and use a TransientAllocator
|
||||
// Create temp dll name
|
||||
|
||||
char* lockFilename = code.LockFullPath.Str;
|
||||
WIN32_FILE_ATTRIBUTE_DATA Ignored;
|
||||
if (!GetFileAttributesExA(lockFilename, GetFileExInfoStandard, &Ignored))
|
||||
@@ -56,7 +54,7 @@ namespace Juliet
|
||||
basePathLength + StringLength(code.TransientDLLName) + /* _ */ 1 + kTempDLLBufferSizeForID + 1 /* \0 */;
|
||||
|
||||
// Allocate from Scratch Arena (transient)
|
||||
TempArena temp = ArenaTempBegin(code.Arena);
|
||||
TempArena temp = scratch_begin(0, 0);
|
||||
auto tempDllPath = ArenaPushArray<char>(temp.Arena, tempDllMaxBufferSize);
|
||||
|
||||
for (uint32 attempt = 0; attempt < kMaxAttempts; ++attempt)
|
||||
@@ -97,7 +95,7 @@ namespace Juliet
|
||||
break;
|
||||
}
|
||||
}
|
||||
ArenaTempEnd(temp);
|
||||
scratch_end(temp);
|
||||
|
||||
code.Dll = LoadDynamicLibrary(tempDllPath);
|
||||
if (code.Dll)
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Juliet::ImGuiService
|
||||
Assert(!g_Initialized);
|
||||
|
||||
// Initialize ImGui Arena using Engine Pool
|
||||
g_ImGuiArena = ArenaAllocate({ .Name = "Juliet" });
|
||||
g_ImGuiArena = ArenaAllocate({ .Name = "Imgui Allocator Arena" });
|
||||
|
||||
// Setup Allocator
|
||||
ImGui::SetAllocatorFunctions(ImGuiAllocWrapper, ImGuiFreeWrapper, nullptr);
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Graphics/Graphics.h>
|
||||
|
||||
#include <Core/Thread/ThreadContext.h>
|
||||
#include <Graphics/GraphicsDevice.h>
|
||||
|
||||
namespace Juliet
|
||||
@@ -316,21 +318,22 @@ namespace Juliet
|
||||
// Shaders
|
||||
Shader* CreateShader(NonNullPtr<GraphicsDevice> device, String filename, ShaderCreateInfo& shaderCreateInfo)
|
||||
{
|
||||
TempArena fileArena = scratch_begin(0, 0);
|
||||
ByteBuffer shaderByteCode = {};
|
||||
|
||||
// Create path from filename
|
||||
if (IsAbsolutePath(filename))
|
||||
{
|
||||
shaderByteCode = LoadFile(filename);
|
||||
shaderByteCode = LoadFile(fileArena.Arena, filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Add path builder in the lib
|
||||
String base = GetBasePath();
|
||||
char inplaceBuffer[256];
|
||||
snprintf(inplaceBuffer, sizeof(inplaceBuffer), "%s%s", base.Str, filename.Str);
|
||||
juliet_snprintf(inplaceBuffer, sizeof(inplaceBuffer), "%s%s", base.Str, filename.Str);
|
||||
String absolutePath = WrapString(inplaceBuffer);
|
||||
shaderByteCode = LoadFile(absolutePath);
|
||||
shaderByteCode = LoadFile(fileArena.Arena, absolutePath);
|
||||
}
|
||||
|
||||
if (!IsValid(shaderByteCode))
|
||||
@@ -340,7 +343,7 @@ namespace Juliet
|
||||
|
||||
Shader* shader = device->CreateShader(device->Driver, shaderByteCode, shaderCreateInfo JULIET_DEBUG_PARAM(filename));
|
||||
|
||||
Free(shaderByteCode);
|
||||
scratch_end(fileArena);
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
+2
-2
@@ -106,7 +106,7 @@ namespace
|
||||
|
||||
} // namespace
|
||||
|
||||
void JulietApplication::Init(NonNullPtr<Arena>)
|
||||
void JulietApplication::Init(NonNullPtr<Arena> platformArena)
|
||||
{
|
||||
Log(LogLevel::Message, LogCategory::Tool, "Initializing Juliet Application...");
|
||||
Log(LogLevel::Message, LogCategory::Tool, "%s", CStr(GetBasePath()));
|
||||
@@ -182,7 +182,7 @@ void JulietApplication::Init(NonNullPtr<Arena>)
|
||||
GameCode.Functions = reinterpret_cast<void**>(&Game);
|
||||
GameCode.FunctionCount = ArraySize(GameFunctionTable);
|
||||
GameCode.FunctionNames = GameFunctionTable;
|
||||
InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
|
||||
InitHotReloadCode(platformArena, GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
|
||||
Running = GameCode.IsValid;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user