Added a basic MemoryArena.
Added one scratch, one engine and one game arena. Converted the game alloc to arena + the display stuff. WIP Made using Antigravity+gemini
This commit is contained in:
10
.agent/rules/coding-guidelines.md
Normal file
10
.agent/rules/coding-guidelines.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
trigger: always_on
|
||||
---
|
||||
|
||||
No exceptions
|
||||
Use [[nodiscard]]
|
||||
auto is allowed but when its a pointer add the * and when reference adds the &
|
||||
Member variable are CamelCase
|
||||
Types are CamelCase
|
||||
Functions are CamelCase.
|
||||
@@ -1,17 +1,15 @@
|
||||
---
|
||||
description: Build the Juliet project using FastBuild
|
||||
---
|
||||
// turbo-all
|
||||
|
||||
This workflow sets up the Juliet build environment and runs `fbuild`.
|
||||
|
||||
1. To build a specific configuration (e.g., msvc-Debug):
|
||||
// turbo
|
||||
`cmd /c "misc\shell.bat & fbuild msvc-Debug"`
|
||||
|
||||
2. To build the default (msvc):
|
||||
// turbo
|
||||
`cmd /c "misc\shell.bat & fbuild msvc"`
|
||||
|
||||
3. To see all available targets:
|
||||
// turbo
|
||||
`cmd /c "misc\shell.bat & fbuild -targets"`
|
||||
`cmd /c "misc\shell.bat & fbuild -showtargets"`
|
||||
|
||||
6
.agent/workflows/launch.md
Normal file
6
.agent/workflows/launch.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
description: Launch the Juliet application
|
||||
---
|
||||
|
||||
1. Run the launch script
|
||||
misc\launch.bat autoclose
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
description: Recompile shaders for the Juliet project
|
||||
---
|
||||
// turbo-all
|
||||
|
||||
This workflow recompiles all shaders using the `recompile_shaders.bat` script.
|
||||
|
||||
1. Recompile all shaders:
|
||||
// turbo
|
||||
`cmd /c "misc\shell.bat & misc\recompile_shaders.bat"`
|
||||
|
||||
49
AgentData/MemoryArena.md
Normal file
49
AgentData/MemoryArena.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Memory System Status & Migration Plan
|
||||
|
||||
## Completed Work
|
||||
|
||||
### Core Systems
|
||||
- **MemoryArena**: Implemented linear allocator with alignment, markers, and reset support.
|
||||
- **Global Arenas**:
|
||||
- `ScratchArena` (64MB): Transient per-frame memory.
|
||||
- `EngineArena` (256MB): Persistent engine memory (internal).
|
||||
- `GameArena` (512MB): Persistent game memory (exported to Game DLL).
|
||||
- **Helpers**: Added `ArenaPushType<T>` and `ArenaPushArray<T>` with automatic zero-initialization.
|
||||
|
||||
### Migrated Subsystems
|
||||
- **Display**: `Win32Window` and `Win32DisplayDevice` now use `EngineArena`.
|
||||
- **Game Entities**: `Entity.h` uses `GameArena` for entity allocation; manual `free` calls removed from `game.cpp`.
|
||||
|
||||
## Remaining Work
|
||||
|
||||
The following subsystems still use legacy `malloc`/`calloc`/`realloc`/`free` and need to be migrated.
|
||||
|
||||
### Hot Reload System
|
||||
- **Files**: `Core/HotReload/HotReload.cpp`, `Core/HotReload/Win32/Win32HotReload.cpp`
|
||||
- **Allocations**: `DLLFullPath`, `LockFullPath`, `tempDllPath`.
|
||||
- **Strategy**:
|
||||
- Use `EngineArena` for persistent paths (`DLLFullPath`, `LockFullPath`).
|
||||
- Use `ScratchArena` for temporary paths (`tempDllPath`).
|
||||
|
||||
### IO System
|
||||
- **Files**: `Core/HAL/IO/IOStream.cpp`, `Core/HAL/IO/Win32/Win32IOStream.cpp`
|
||||
- **Allocations**: `IOStream` instance, data buffers, `Win32IOStreamDataPayload`.
|
||||
- **Challenge**: `Realloc` is used for growing buffers.
|
||||
- **Strategy**:
|
||||
- `IOStream` struct -> `ScratchArena` (if transient) or `EngineArena`.
|
||||
- Buffers: Evaluate if `ArenaPush` with large enough capacity is sufficient, or implement a growable buffer on top of arena (or use `std::vector` with custom allocator if absolutely needed, but prefer simple fixed max size if possible).
|
||||
|
||||
### Graphics / Debug
|
||||
- **Files**: `Graphics/DebugDisplayRenderer.cpp`
|
||||
- **Allocations**: `DepthTestedVertices`, `OverlayVertices`.
|
||||
- **Strategy**: Use `EngineArena` or a dedicated `RenderArena` if these are persistent. If per-frame, move to `ScratchArena`.
|
||||
|
||||
### Shader Compiler
|
||||
- **Files**: `JulietShaderCompiler/ShaderCompiler.cpp`
|
||||
- **Allocations**: Argument arrays, file buffers.
|
||||
- **Strategy**: Use `ScratchArena` for all compilation tasks as they are transient.
|
||||
|
||||
### Filesystem
|
||||
- **Files**: `Core/HAL/Filesystem/Filesystem.cpp`
|
||||
- **Allocations**: `CachedBasePath`.
|
||||
- **Strategy**: Migrate to `EngineArena` (persistent).
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <concepts>
|
||||
#include <Core/Common/CoreUtils.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Engine/Class.h>
|
||||
#include <Entity/EntityManager.h>
|
||||
#include <type_traits>
|
||||
@@ -17,6 +18,8 @@
|
||||
constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
|
||||
const Juliet::Class* entity::Kind = &entityKind##entity;
|
||||
|
||||
|
||||
|
||||
namespace Game
|
||||
{
|
||||
using DerivedType = void*;
|
||||
@@ -46,8 +49,9 @@ namespace Game
|
||||
requires EntityConcept<EntityType>
|
||||
EntityType* MakeEntity(EntityManager& manager, float x, float y)
|
||||
{
|
||||
EntityType* result = static_cast<EntityType*>(Juliet::Calloc(1, sizeof(EntityType)));
|
||||
Entity* base = result->Base = static_cast<Entity*>(Juliet::Calloc(1, sizeof(Entity)));
|
||||
auto* arena = Juliet::GetGameArena();
|
||||
EntityType* result = Juliet::ArenaPushType<EntityType>(arena);
|
||||
Entity* base = result->Base = Juliet::ArenaPushType<Entity>(arena);
|
||||
base->X = x;
|
||||
base->Y = y;
|
||||
base->Derived = result;
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
// Extra Compiler Options
|
||||
.CompilerOptions + ' "-IJuliet/include"'
|
||||
+ ' "-IGame"'
|
||||
// + ' -DGAME_EXPORT' // I'm just always exporting anyway but just in case
|
||||
.CompilerOptions + ' -DJULIET_EXPORT'
|
||||
|
||||
#if __WINDOWS__
|
||||
.CompilerOptions + ' -DJULIET_WIN32'
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
#undef max
|
||||
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/JulietInit.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Entity/Entity.h>
|
||||
#include <Entity/EntityManager.h>
|
||||
#include <Graphics/Graphics.h>
|
||||
|
||||
// Test code
|
||||
namespace Game
|
||||
@@ -31,8 +31,21 @@ namespace Game
|
||||
|
||||
using namespace Juliet;
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl GameInit()
|
||||
extern "C" JULIET_API void GameInit(GameInitParams* /*params*/)
|
||||
{
|
||||
// Example allocation in GameArena
|
||||
struct GameState
|
||||
{
|
||||
float TotalTime;
|
||||
int Score;
|
||||
};
|
||||
|
||||
auto* gameState = ArenaPushType<GameState>(GetGameArena());
|
||||
gameState->TotalTime = 0.0f;
|
||||
gameState->Score = 0;
|
||||
|
||||
printf("Game Arena Allocated: %p\n", gameState);
|
||||
|
||||
using namespace Game;
|
||||
|
||||
// Entity Use case
|
||||
@@ -51,20 +64,14 @@ extern "C" __declspec(dllexport) void __cdecl GameInit()
|
||||
|
||||
printf("Door is %s\n", door->IsOpened ? "Opened" : "Closed");
|
||||
printf("Rock has %d health points\n", rock->Health);
|
||||
|
||||
// Have to manually free for now because im not using arenas or anything
|
||||
free(door->Base);
|
||||
free(door);
|
||||
free(rock->Base);
|
||||
free(rock);
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl GameShutdown()
|
||||
extern "C" JULIET_API void __cdecl GameShutdown()
|
||||
{
|
||||
printf("Shutting down game...\n");
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl GameUpdate([[maybe_unused]] float deltaTime)
|
||||
extern "C" JULIET_API void __cdecl GameUpdate([[maybe_unused]] float deltaTime)
|
||||
{
|
||||
// printf("Updating game...\n");
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
<CustomBuild Include="include\Core\Math\Shape.h" />
|
||||
<CustomBuild Include="include\Core\Math\Vector.h" />
|
||||
<CustomBuild Include="include\Core\Memory\Allocator.h" />
|
||||
<CustomBuild Include="include\Core\Memory\MemoryArena.h" />
|
||||
<CustomBuild Include="include\Core\Memory\Utils.h" />
|
||||
<CustomBuild Include="include\Core\Networking\IPAddress.h" />
|
||||
<CustomBuild Include="include\Core\Networking\NetworkPacket.h" />
|
||||
@@ -118,6 +119,9 @@
|
||||
<CustomBuild Include="src\Core\Math\Math_Private.h" />
|
||||
<CustomBuild Include="src\Core\Math\MathRound.cpp" />
|
||||
<CustomBuild Include="src\Core\Memory\Allocator.cpp" />
|
||||
<CustomBuild Include="src\Core\Memory\EngineArena.h" />
|
||||
<CustomBuild Include="src\Core\Memory\MemoryArena.cpp" />
|
||||
<CustomBuild Include="src\Core\Memory\MemoryArenaTests.cpp" />
|
||||
<CustomBuild Include="src\Core\Networking\NetworkPacket.cpp" />
|
||||
<CustomBuild Include="src\Core\Networking\Socket.cpp" />
|
||||
<CustomBuild Include="src\Core\Networking\SocketPlatformImpl.h" />
|
||||
|
||||
@@ -91,6 +91,9 @@
|
||||
<CustomBuild Include="include\Core\Memory\Allocator.h">
|
||||
<Filter>include\Core\Memory</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="include\Core\Memory\MemoryArena.h">
|
||||
<Filter>include\Core\Memory</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="include\Core\Memory\Utils.h">
|
||||
<Filter>include\Core\Memory</Filter>
|
||||
</CustomBuild>
|
||||
@@ -273,6 +276,15 @@
|
||||
<CustomBuild Include="src\Core\Memory\Allocator.cpp">
|
||||
<Filter>src\Core\Memory</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="src\Core\Memory\EngineArena.h">
|
||||
<Filter>src\Core\Memory</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="src\Core\Memory\MemoryArena.cpp">
|
||||
<Filter>src\Core\Memory</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="src\Core\Memory\MemoryArenaTests.cpp">
|
||||
<Filter>src\Core\Memory</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="src\Core\Networking\NetworkPacket.cpp">
|
||||
<Filter>src\Core\Networking</Filter>
|
||||
</CustomBuild>
|
||||
|
||||
@@ -13,6 +13,14 @@ namespace Juliet
|
||||
All = 0xFb
|
||||
};
|
||||
|
||||
struct MemoryArena;
|
||||
|
||||
struct GameInitParams
|
||||
{
|
||||
MemoryArena* GameArena;
|
||||
MemoryArena* ScratchArena;
|
||||
};
|
||||
|
||||
void JulietInit(JulietInit_Flags flags);
|
||||
void JulietShutdown();
|
||||
} // namespace Juliet
|
||||
|
||||
61
Juliet/include/Core/Memory/MemoryArena.h
Normal file
61
Juliet/include/Core/Memory/MemoryArena.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <Juliet.h>
|
||||
#include <Core/Common/CoreTypes.h>
|
||||
#include <Core/Common/CoreUtils.h>
|
||||
#include <Core/Memory/Utils.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
struct MemoryArena
|
||||
{
|
||||
uint8* Data;
|
||||
size_t Size;
|
||||
size_t Offset;
|
||||
};
|
||||
|
||||
JULIET_API void MemoryArenaCreate(MemoryArena* arena, void* backingMemory, size_t size);
|
||||
JULIET_API void* ArenaPush(MemoryArena* arena, size_t size, size_t alignment = 16);
|
||||
JULIET_API void ArenaReset(MemoryArena* arena);
|
||||
JULIET_API size_t ArenaGetMarker(MemoryArena* arena);
|
||||
JULIET_API void ArenaResetToMarker(MemoryArena* arena, size_t marker);
|
||||
|
||||
// --- Global Arenas & Management ---
|
||||
|
||||
// Returns a global arena that resets every frame.
|
||||
JULIET_API MemoryArena* GetScratchArena();
|
||||
|
||||
// Persistent game arena.
|
||||
JULIET_API MemoryArena* GetGameArena();
|
||||
|
||||
// Internal engine function to reset the scratch arena.
|
||||
JULIET_API void ScratchArenaReset();
|
||||
|
||||
// Internal engine function to initialize memory arenas.
|
||||
void MemoryArenasInit();
|
||||
|
||||
// Internal engine function to shutdown memory arenas.
|
||||
void MemoryArenasShutdown();
|
||||
|
||||
template <typename T>
|
||||
inline T* ArenaPushType(MemoryArena* arena)
|
||||
{
|
||||
T* result = static_cast<T*>(ArenaPush(arena, sizeof(T), alignof(T)));
|
||||
if (result)
|
||||
{
|
||||
MemSet(result, 0, sizeof(T));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T* ArenaPushArray(MemoryArena* arena, size_t count)
|
||||
{
|
||||
T* result = static_cast<T*>(ArenaPush(arena, sizeof(T) * count, alignof(T)));
|
||||
if (result)
|
||||
{
|
||||
MemSet(result, 0, sizeof(T) * count);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace Juliet
|
||||
0
Juliet/include/Core/Memory/ScratchArena.h
Normal file
0
Juliet/include/Core/Memory/ScratchArena.h
Normal file
@@ -2,6 +2,8 @@
|
||||
#include <Core/HAL/Display/Display_Private.h>
|
||||
#include <Core/HAL/Display/DisplayDevice.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Core/Memory/EngineArena.h>
|
||||
#include <format>
|
||||
|
||||
namespace Juliet
|
||||
@@ -72,7 +74,8 @@ namespace Juliet
|
||||
{
|
||||
Assert(g_CurrentDisplayDevice->CreatePlatformWindow);
|
||||
|
||||
auto window = static_cast<Window*>(Calloc(1, sizeof(Window)));
|
||||
MemoryArena* arena = GetEngineArena();
|
||||
auto window = ArenaPushType<Window>(arena);
|
||||
if (!window)
|
||||
{
|
||||
return nullptr;
|
||||
@@ -80,9 +83,8 @@ namespace Juliet
|
||||
window->Width = width;
|
||||
window->Height = height;
|
||||
|
||||
// TODO String creator that copy
|
||||
auto titleLen = StringLength(title);
|
||||
auto buffer = static_cast<char*>(Calloc(titleLen, sizeof(char)));
|
||||
auto buffer = ArenaPushArray<char>(arena, titleLen);
|
||||
MemCopy(buffer, title, titleLen);
|
||||
|
||||
window->Title.Data = buffer;
|
||||
@@ -91,7 +93,8 @@ namespace Juliet
|
||||
g_CurrentDisplayDevice->MainWindow = window;
|
||||
if (!g_CurrentDisplayDevice->CreatePlatformWindow(g_CurrentDisplayDevice, window))
|
||||
{
|
||||
// TODO : Destroy
|
||||
// Note: We don't "free" from arena easily, but since this is catastrophic
|
||||
// and persistent, we just leak the small amount of arena space or handle it if we had a marker.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -107,13 +110,12 @@ namespace Juliet
|
||||
|
||||
HideWindow(window);
|
||||
|
||||
// TODO : Free string function
|
||||
SafeFree(window->Title.Data);
|
||||
// We don't free from arena, these are persistent until shutdown.
|
||||
window->Title.Data = nullptr;
|
||||
window->Title.Size = 0;
|
||||
|
||||
g_CurrentDisplayDevice->DestroyPlatformWindow(g_CurrentDisplayDevice, window);
|
||||
|
||||
Free(window.Get());
|
||||
g_CurrentDisplayDevice->MainWindow = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Memory/EngineArena.h>
|
||||
#include <Core/Memory/Utils.h>
|
||||
|
||||
namespace Juliet::Win32
|
||||
{
|
||||
@@ -12,14 +14,12 @@ namespace Juliet::Win32
|
||||
return true;
|
||||
}
|
||||
void Shutdown(NonNullPtr<DisplayDevice> /*self*/) {}
|
||||
void Free(NonNullPtr<DisplayDevice> self)
|
||||
{
|
||||
Juliet::Free(self.Get());
|
||||
}
|
||||
void Free(NonNullPtr<DisplayDevice> /*self*/) {}
|
||||
|
||||
DisplayDevice* CreateDevice()
|
||||
{
|
||||
auto device = static_cast<DisplayDevice*>(Calloc(1, sizeof(DisplayDevice)));
|
||||
auto device = ArenaPushType<DisplayDevice>(GetEngineArena());
|
||||
|
||||
if (!device)
|
||||
{
|
||||
return nullptr;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||
#include <Core/HAL/Display/Window.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Memory/EngineArena.h>
|
||||
#include <Core/Memory/Utils.h>
|
||||
|
||||
namespace Juliet::Win32
|
||||
{
|
||||
@@ -12,7 +14,8 @@ namespace Juliet::Win32
|
||||
|
||||
bool SetupWindowState(NonNullPtr<DisplayDevice> /*self*/, NonNullPtr<Window> window, HWND handle)
|
||||
{
|
||||
auto state = static_cast<Window32State*>(Calloc(1, sizeof(Window32State)));
|
||||
auto state = ArenaPushType<Window32State>(GetEngineArena());
|
||||
|
||||
window->State = state;
|
||||
state->Handle = handle;
|
||||
state->Window = window;
|
||||
@@ -31,8 +34,6 @@ namespace Juliet::Win32
|
||||
{
|
||||
ReleaseDC(state->Handle, state->HDC);
|
||||
DestroyWindow(state->Handle);
|
||||
|
||||
SafeFree(state);
|
||||
}
|
||||
window->State = nullptr;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Memory/EngineArena.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Core/Thread/Thread.h>
|
||||
|
||||
#define MAX_TRIES 100
|
||||
@@ -21,11 +23,11 @@ namespace Juliet
|
||||
// First allocate all the full path.
|
||||
// TODO: Add path composition into filesystem + string format + string builder
|
||||
const size_t dllFullPathLength = basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
|
||||
code.DLLFullPath.Data = static_cast<char*>(Calloc(dllFullPathLength, sizeof(char)));
|
||||
code.DLLFullPath.Data = ArenaPushArray<char>(GetEngineArena(), dllFullPathLength);
|
||||
int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
|
||||
if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
|
||||
{
|
||||
SafeFree(code.DLLFullPath.Data);
|
||||
// Arena memory persists, no free needed
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create DLL Full Path");
|
||||
return;
|
||||
}
|
||||
@@ -33,12 +35,12 @@ namespace Juliet
|
||||
|
||||
// Lock filename path
|
||||
const size_t lockPathLength = basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
|
||||
code.LockFullPath.Data = static_cast<char*>(Calloc(lockPathLength, sizeof(char)));
|
||||
code.LockFullPath.Data = ArenaPushArray<char>(GetEngineArena(), lockPathLength);
|
||||
writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
|
||||
if (writtenSize < static_cast<int>(lockPathLength) - 1)
|
||||
{
|
||||
code.LockFullPath.Size = 0;
|
||||
SafeFree(code.LockFullPath.Data);
|
||||
// Arena memory persists, no free needed
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create lock file full path");
|
||||
return;
|
||||
}
|
||||
@@ -52,9 +54,9 @@ namespace Juliet
|
||||
UnloadCode(code);
|
||||
|
||||
code.DLLFullPath.Size = 0;
|
||||
SafeFree(code.DLLFullPath.Data);
|
||||
// Arena memory persists until engine shutdown
|
||||
code.LockFullPath.Size = 0;
|
||||
SafeFree(code.LockFullPath.Data);
|
||||
// Arena memory persists until engine shutdown
|
||||
}
|
||||
|
||||
void ReloadCode(HotReloadCode& code)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -53,7 +54,10 @@ namespace Juliet
|
||||
|
||||
const size_t tempDllMaxBufferSize =
|
||||
basePathLength + StringLength(code.TransientDLLName) + /* _ */ 1 + kTempDLLBufferSizeForID + 1 /* \0 */;
|
||||
auto tempDllPath = static_cast<char*>(Calloc(tempDllMaxBufferSize, sizeof(char)));
|
||||
|
||||
// Allocate from Scratch Arena (transient)
|
||||
auto tempDllPath = ArenaPushArray<char>(GetScratchArena(), tempDllMaxBufferSize);
|
||||
|
||||
for (uint32 attempt = 0; attempt < kMaxAttempts; ++attempt)
|
||||
{
|
||||
// int to char
|
||||
@@ -61,7 +65,7 @@ namespace Juliet
|
||||
int idLength = snprintf(idToStr, sizeof(idToStr), "%u", code.UniqueID);
|
||||
if (idLength < 0)
|
||||
{
|
||||
SafeFree(tempDllPath);
|
||||
// Scratch memory, no free needed
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create temp full path");
|
||||
return;
|
||||
}
|
||||
@@ -70,14 +74,14 @@ namespace Juliet
|
||||
CStr(code.TransientDLLName));
|
||||
if (writtenSize < 0)
|
||||
{
|
||||
SafeFree(tempDllPath);
|
||||
// Scratch memory, no free needed
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create temp full path");
|
||||
return;
|
||||
}
|
||||
|
||||
if (static_cast<size_t>(writtenSize) + 1 < basePathLength + static_cast<size_t>(idLength) + code.TransientDLLName.Size)
|
||||
{
|
||||
SafeFree(tempDllPath);
|
||||
// Scratch memory, no free needed
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create temp full path");
|
||||
return;
|
||||
}
|
||||
@@ -109,7 +113,7 @@ namespace Juliet
|
||||
}
|
||||
}
|
||||
|
||||
SafeFree(tempDllPath);
|
||||
// Scratch memory, no free needed
|
||||
}
|
||||
|
||||
if (!code.IsValid)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <Core/HAL/Display/Display_Private.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem_Private.h>
|
||||
#include <Core/JulietInit.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -38,9 +39,22 @@ namespace Juliet
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#if JULIET_DEBUG
|
||||
namespace UnitTest
|
||||
{
|
||||
extern void TestMemoryArena();
|
||||
}
|
||||
#endif
|
||||
|
||||
void JulietInit(JulietInit_Flags flags)
|
||||
{
|
||||
// Mandatory systems
|
||||
MemoryArenasInit();
|
||||
|
||||
#if JULIET_DEBUG
|
||||
UnitTest::TestMemoryArena();
|
||||
#endif
|
||||
|
||||
InitFilesystem();
|
||||
|
||||
// Optional systems
|
||||
@@ -61,6 +75,7 @@ namespace Juliet
|
||||
}
|
||||
|
||||
ShutdownFilesystem();
|
||||
MemoryArenasShutdown();
|
||||
}
|
||||
|
||||
} // namespace Juliet
|
||||
|
||||
10
Juliet/src/Core/Memory/EngineArena.h
Normal file
10
Juliet/src/Core/Memory/EngineArena.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
// Persistent engine-only arena.
|
||||
// Not exported to the Game DLL.
|
||||
MemoryArena* GetEngineArena();
|
||||
} // namespace Juliet
|
||||
116
Juliet/src/Core/Memory/MemoryArena.cpp
Normal file
116
Juliet/src/Core/Memory/MemoryArena.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Core/Memory/Utils.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
void MemoryArenaCreate(MemoryArena* arena, void* backingMemory, size_t size)
|
||||
{
|
||||
Assert(arena);
|
||||
Assert(backingMemory);
|
||||
arena->Data = static_cast<uint8*>(backingMemory);
|
||||
arena->Size = size;
|
||||
arena->Offset = 0;
|
||||
}
|
||||
|
||||
void* ArenaPush(MemoryArena* arena, size_t size, size_t alignment)
|
||||
{
|
||||
Assert(arena);
|
||||
|
||||
// Alignment must be power of 2
|
||||
Assert((alignment & (alignment - 1)) == 0);
|
||||
|
||||
size_t currentPtr = reinterpret_cast<size_t>(arena->Data + arena->Offset);
|
||||
size_t offset = (currentPtr + (alignment - 1)) & ~(alignment - 1);
|
||||
size_t newOffset = offset - reinterpret_cast<size_t>(arena->Data) + size;
|
||||
|
||||
if (newOffset > arena->Size)
|
||||
{
|
||||
Assert(false, "Memory Arena overflow");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* result = arena->Data + (offset - reinterpret_cast<size_t>(arena->Data));
|
||||
arena->Offset = newOffset;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ArenaReset(MemoryArena* arena)
|
||||
{
|
||||
Assert(arena);
|
||||
arena->Offset = 0;
|
||||
}
|
||||
|
||||
size_t ArenaGetMarker(MemoryArena* arena)
|
||||
{
|
||||
Assert(arena);
|
||||
return arena->Offset;
|
||||
}
|
||||
|
||||
void ArenaResetToMarker(MemoryArena* arena, size_t marker)
|
||||
{
|
||||
Assert(arena);
|
||||
Assert(marker <= arena->Offset);
|
||||
arena->Offset = marker;
|
||||
}
|
||||
|
||||
// --- Global Arenas & Management ---
|
||||
|
||||
namespace
|
||||
{
|
||||
MemoryArena g_ScratchArena;
|
||||
MemoryArena g_EngineArena;
|
||||
MemoryArena g_GameArena;
|
||||
|
||||
void* g_ScratchBacking = nullptr;
|
||||
void* g_EngineBacking = nullptr;
|
||||
void* g_GameBacking = nullptr;
|
||||
|
||||
constexpr size_t kScratchSize = 64 * 1024 * 1024; // 64MB
|
||||
constexpr size_t kEngineSize = 256 * 1024 * 1024; // 256MB
|
||||
constexpr size_t kGameSize = 512 * 1024 * 1024; // 512MB
|
||||
} // namespace
|
||||
|
||||
MemoryArena* GetScratchArena()
|
||||
{
|
||||
return &g_ScratchArena;
|
||||
}
|
||||
|
||||
MemoryArena* GetEngineArena()
|
||||
{
|
||||
return &g_EngineArena;
|
||||
}
|
||||
|
||||
MemoryArena* GetGameArena()
|
||||
{
|
||||
return &g_GameArena;
|
||||
}
|
||||
|
||||
void ScratchArenaReset()
|
||||
{
|
||||
ArenaReset(&g_ScratchArena);
|
||||
}
|
||||
|
||||
void MemoryArenasInit()
|
||||
{
|
||||
// TODO: Use the VirtualAlloc API for this on windows
|
||||
g_ScratchBacking = Malloc(kScratchSize);
|
||||
MemSet(g_ScratchBacking, 0, kScratchSize);
|
||||
g_EngineBacking = Malloc(kEngineSize);
|
||||
MemSet(g_EngineBacking, 0, kEngineSize);
|
||||
g_GameBacking = Malloc(kGameSize);
|
||||
MemSet(g_GameBacking, 0, kGameSize);
|
||||
|
||||
MemoryArenaCreate(&g_ScratchArena, g_ScratchBacking, kScratchSize);
|
||||
MemoryArenaCreate(&g_EngineArena, g_EngineBacking, kEngineSize);
|
||||
MemoryArenaCreate(&g_GameArena, g_GameBacking, kGameSize);
|
||||
}
|
||||
|
||||
void MemoryArenasShutdown()
|
||||
{
|
||||
SafeFree(g_ScratchBacking);
|
||||
SafeFree(g_EngineBacking);
|
||||
SafeFree(g_GameBacking);
|
||||
}
|
||||
} // namespace Juliet
|
||||
67
Juliet/src/Core/Memory/MemoryArenaTests.cpp
Normal file
67
Juliet/src/Core/Memory/MemoryArenaTests.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <cstdio>
|
||||
#include <Core/Common/CoreUtils.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
|
||||
#if JULIET_DEBUG
|
||||
|
||||
namespace Juliet::UnitTest
|
||||
{
|
||||
void TestMemoryArena()
|
||||
{
|
||||
// 1. Core Arena Functionality
|
||||
uint8 buffer[1024];
|
||||
MemoryArena arena;
|
||||
MemoryArenaCreate(&arena, buffer, 1024);
|
||||
|
||||
Assert(arena.Offset == 0);
|
||||
Assert(arena.Size == 1024);
|
||||
|
||||
void* p1 = ArenaPush(&arena, 100);
|
||||
Assert(p1 != nullptr);
|
||||
Assert(arena.Offset >= 100);
|
||||
|
||||
size_t marker = ArenaGetMarker(&arena);
|
||||
void* p2 = ArenaPush(&arena, 200);
|
||||
Assert(p2 != nullptr);
|
||||
Assert(arena.Offset >= marker + 200);
|
||||
|
||||
ArenaResetToMarker(&arena, marker);
|
||||
Assert(arena.Offset == marker);
|
||||
|
||||
ArenaReset(&arena);
|
||||
Assert(arena.Offset == 0);
|
||||
|
||||
// 2. Alignment Test
|
||||
void* p3 = ArenaPush(&arena, 1, 1);
|
||||
[[maybe_unused]] size_t addr = reinterpret_cast<size_t>(p3);
|
||||
void* p4 = ArenaPush(&arena, 1, 16);
|
||||
size_t addr2 = reinterpret_cast<size_t>(p4);
|
||||
Assert((addr2 % 16) == 0);
|
||||
|
||||
// 3. Template Helpers
|
||||
struct TestData
|
||||
{
|
||||
int a;
|
||||
float b;
|
||||
};
|
||||
TestData* data = ArenaPushType<TestData>(&arena);
|
||||
Assert(data != nullptr);
|
||||
data->a = 10;
|
||||
data->b = 20.0f;
|
||||
|
||||
TestData* dataArray = ArenaPushArray<TestData>(&arena, 10);
|
||||
Assert(dataArray != nullptr);
|
||||
|
||||
// 4. Scratch Arena
|
||||
MemoryArena* scratch = GetScratchArena();
|
||||
Assert(scratch != nullptr);
|
||||
void* sp = ArenaPush(scratch, 100);
|
||||
Assert(sp != nullptr);
|
||||
ScratchArenaReset();
|
||||
Assert(scratch->Offset == 0);
|
||||
|
||||
printf("All MemoryArena tests passed.\n");
|
||||
}
|
||||
} // namespace Juliet::UnitTest
|
||||
|
||||
#endif
|
||||
0
Juliet/src/Core/Memory/ScratchArena.cpp
Normal file
0
Juliet/src/Core/Memory/ScratchArena.cpp
Normal file
@@ -4,6 +4,7 @@
|
||||
.ProjectName = 'JulietApp'
|
||||
.ProjectPath = 'JulietApp'
|
||||
.JulietIncludePath = ' "-IJuliet/include"'
|
||||
+ ' "-IJuliet/src"'
|
||||
.ProjectDefPath = '$_WORKING_DIR_$/$ProjectName$/$ProjectName$.def'
|
||||
|
||||
// Library
|
||||
|
||||
@@ -376,7 +376,7 @@
|
||||
<NMakeBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration)</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration)</NMakeReBuildCommandLine>
|
||||
<NMakePreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_WIN32;</NMakePreprocessorDefinitions>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;..\Juliet\src;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<AdditionalOptions>/std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 </AdditionalOptions>
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)\bin\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||
<IntDir>$(SolutionDir)\Intermediate</IntDir>
|
||||
@@ -386,7 +386,7 @@
|
||||
<NMakeBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration)</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration)</NMakeReBuildCommandLine>
|
||||
<NMakePreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;RELEASE;PROFILING_ENABLED;JULIET_WIN32;</NMakePreprocessorDefinitions>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;..\Juliet\src;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<AdditionalOptions>/std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 </AdditionalOptions>
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)\bin\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||
<IntDir>$(SolutionDir)\Intermediate</IntDir>
|
||||
@@ -396,7 +396,7 @@
|
||||
<NMakeBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration)</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration)</NMakeReBuildCommandLine>
|
||||
<NMakePreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;RELEASE;JULIET_WIN32;</NMakePreprocessorDefinitions>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;..\Juliet\src;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<AdditionalOptions>/std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 </AdditionalOptions>
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)\bin\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||
<IntDir>$(SolutionDir)\Intermediate</IntDir>
|
||||
@@ -406,7 +406,7 @@
|
||||
<NMakeBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration)</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration)</NMakeReBuildCommandLine>
|
||||
<NMakePreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_WIN32;</NMakePreprocessorDefinitions>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;..\Juliet\src;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<AdditionalOptions>/std:c++20 </AdditionalOptions>
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)\bin\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||
<IntDir>$(SolutionDir)\Intermediate</IntDir>
|
||||
@@ -416,7 +416,7 @@
|
||||
<NMakeBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration)</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration)</NMakeReBuildCommandLine>
|
||||
<NMakePreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;RELEASE;PROFILING_ENABLED;JULIET_WIN32;</NMakePreprocessorDefinitions>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;..\Juliet\src;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<AdditionalOptions>/std:c++20 </AdditionalOptions>
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)\bin\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||
<IntDir>$(SolutionDir)\Intermediate</IntDir>
|
||||
@@ -426,7 +426,7 @@
|
||||
<NMakeBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration)</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration)</NMakeReBuildCommandLine>
|
||||
<NMakePreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;RELEASE;JULIET_WIN32;</NMakePreprocessorDefinitions>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<NMakeIncludeSearchPath>..\;..\Juliet\include;..\Juliet\src;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared;</NMakeIncludeSearchPath>
|
||||
<AdditionalOptions>/std:c++20 </AdditionalOptions>
|
||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)\bin\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||
<IntDir>$(SolutionDir)\Intermediate</IntDir>
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <Core/Common/String.h>
|
||||
#include <Core/Memory/Utils.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Core/Memory/EngineArena.h>
|
||||
#include <cstdlib>
|
||||
|
||||
// TODO : Replace with message box from framework + call main and not winmain + subsystem
|
||||
@@ -33,7 +35,7 @@ using namespace Juliet;
|
||||
|
||||
namespace
|
||||
{
|
||||
using GameInit_t = void (*)(void);
|
||||
using GameInit_t = void (*)(GameInitParams*);
|
||||
using GameShutdown_t = void (*)(void);
|
||||
using GameUpdate_t = void (*)(float deltaTime);
|
||||
struct GameFunctionTable
|
||||
@@ -158,7 +160,10 @@ void JulietApplication::Init()
|
||||
InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
|
||||
if ((Running = GameCode.IsValid))
|
||||
{
|
||||
Game.Init();
|
||||
GameInitParams params;
|
||||
params.GameArena = GetGameArena();
|
||||
params.ScratchArena = GetScratchArena();
|
||||
Game.Init(¶ms);
|
||||
}
|
||||
|
||||
// Initialize DebugDisplay
|
||||
@@ -383,6 +388,9 @@ void JulietApplication::Update()
|
||||
|
||||
// Submit Commands
|
||||
SubmitCommandLists(cmdList);
|
||||
|
||||
// Reset Scratch Arena at the end of the frame
|
||||
ScratchArenaReset();
|
||||
}
|
||||
|
||||
bool JulietApplication::IsRunning()
|
||||
|
||||
@@ -2,8 +2,21 @@
|
||||
setlocal
|
||||
|
||||
:: --- 1. Argument Parsing Logic ---
|
||||
set "ARG1=%~1"
|
||||
set "ARG2=%~2"
|
||||
set "ARG1="
|
||||
set "ARG2="
|
||||
set "AUTOCLOSE=0"
|
||||
|
||||
for %%x in (%*) do (
|
||||
if /I "%%~x"=="autoclose" (
|
||||
set "AUTOCLOSE=1"
|
||||
) else (
|
||||
if not defined ARG1 (
|
||||
set "ARG1=%%~x"
|
||||
) else if not defined ARG2 (
|
||||
set "ARG2=%%~x"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
:: Set Defaults
|
||||
set "COMPILER_TYPE=clang"
|
||||
@@ -44,6 +57,12 @@ if exist "%APP_DIR%\%APP_EXE%" (
|
||||
pushd "%APP_DIR%"
|
||||
start "" "%APP_EXE%"
|
||||
popd
|
||||
|
||||
if "%AUTOCLOSE%"=="1" (
|
||||
echo [AUTOCLOSE] Waiting 5 seconds...
|
||||
timeout /t 5 /nobreak >nul
|
||||
taskkill /IM "%APP_EXE%" /F >nul 2>&1
|
||||
)
|
||||
) else (
|
||||
echo [ERROR] Executable not found at: %APP_DIR%\%APP_EXE%
|
||||
echo Please build first: fbuild JulietApp-%PLATFORM%-%CONFIG%
|
||||
|
||||
@@ -73,5 +73,4 @@ for %%F in ("%SOURCE_DIR%\*.hlsl") do (
|
||||
|
||||
echo.
|
||||
echo Operation terminee.
|
||||
pause
|
||||
endlocal
|
||||
Reference in New Issue
Block a user