Compare commits

..
2 Commits
28 changed files with 223 additions and 413 deletions
-4
View File
@@ -18,8 +18,6 @@
constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
const Juliet::Class* entity::Kind = &entityKind##entity;
namespace Game
{
using DerivedType = void*;
struct Entity final
@@ -70,5 +68,3 @@ namespace Game
Assert(IsA<EntityType>(entity));
return static_cast<EntityType*>(entity->Derived);
}
} // namespace Game
+10 -13
View File
@@ -2,33 +2,30 @@
#include <Entity/Entity.h>
namespace Game
{
namespace
{
EntityManager Manager;
}
EntityID EntityManager::ID = 0;
void InitEntityManager(Juliet::NonNullPtr<Juliet::Arena> arena)
void InitEntityManager(Juliet::NonNullPtr<World> world)
{
Manager.Arena = arena.Get();
Manager.Entities.Create(arena JULIET_DEBUG_PARAM("Entities"));
EntityManager* newManager = Juliet::ArenaPushStruct<EntityManager>(world->WorldArena);
world->EntityManager = newManager;
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
newManager->Arena = Juliet::ArenaAllocate({} JULIET_DEBUG_PARAM("Entity Arena"));
}
void ShutdownEntityManager()
{
Manager.Entities.Destroy();
GetEntityManager().Entities.Destroy();
}
EntityManager& GetEntityManager()
{
return Manager;
Juliet::NonNullPtr entityManager = GetGameState()->World->EntityManager;
return *entityManager;
}
void RegisterEntity(EntityManager& /*manager*/, Entity* entity)
{
entity->ID = EntityManager::ID++;
}
} // namespace Game
+3 -4
View File
@@ -2,9 +2,8 @@
#include <Core/Common/CoreTypes.h>
#include <Core/Container/Vector.h>
#include <game.h>
namespace Game
{
using EntityID = uint64_t;
struct Entity;
@@ -13,12 +12,12 @@ namespace Game
static EntityID ID;
Juliet::Arena* Arena;
// TODO: Should be a pool
Juliet::VectorArena<Entity, 1024> Entities;
};
void InitEntityManager(Juliet::NonNullPtr<Juliet::Arena> arena);
void InitEntityManager(Juliet::NonNullPtr<World> world);
void ShutdownEntityManager();
EntityManager& GetEntityManager();
void RegisterEntity(EntityManager& manager, Entity* entity);
} // namespace Game
+1
View File
@@ -84,6 +84,7 @@
<ClCompile Include="game.cpp" />
<ClInclude Include="Entity\Entity.h" />
<ClInclude Include="Entity\EntityManager.h" />
<ClInclude Include="game.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
+1
View File
@@ -15,5 +15,6 @@
<ClInclude Include="Entity\EntityManager.h">
<Filter>Entity</Filter>
</ClInclude>
<ClInclude Include="game.h" />
</ItemGroup>
</Project>
+32 -21
View File
@@ -3,6 +3,8 @@
#undef min
#undef max
#include <game.h>
#include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/JulietInit.h>
#include <Core/Logging/LogManager.h>
@@ -10,6 +12,12 @@
#include <Entity/Entity.h>
#include <Entity/EntityManager.h>
GameState* gGameState = nullptr;
GameState* GetGameState()
{
return gGameState;
}
// Test code
namespace Game
{
@@ -26,30 +34,44 @@ namespace Game
int Health;
};
DEFINE_ENTITY(Rock);
} // namespace Game
extern "C" JULIET_API void __cdecl GameShutdown()
{
printf("Shutting down game...\n");
using namespace Juliet;
using namespace Game;
extern "C" JULIET_API void GameInit(GameInitParams* params)
ShutdownEntityManager();
}
extern "C" JULIET_API void __cdecl GameUpdate(Juliet::GameData* params, [[maybe_unused]] float deltaTime)
{
// Example allocation in GameArena
struct GameState
using namespace Juliet;
using namespace Game;
gGameState = params->GameState;
if (!gGameState)
{
float TotalTime;
int Score;
};
Arena* gameStateArena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_PARAM("Game Total Arena"));
auto* gameState = ArenaPushStruct<GameState>(gameStateArena);
gGameState = params->GameState = gameState;
gameState->TotalArena = gameStateArena;
auto* gameState = ArenaPushStruct<GameState>(params->GameArena);
gameState->TotalTime = 0.0f;
gameState->Score = 0;
printf("Game Arena Allocated: %p\n", static_cast<void*>(gameState));
using namespace Game;
// Bootstrap world
auto* worldArena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_PARAM("World Arena"));
World* world = ArenaPushStruct<World>(worldArena JULIET_DEBUG_PARAM("World"));
gameState->World = world;
gameState->World->WorldArena = worldArena;
// Entity Use case
InitEntityManager(params->GameArena);
InitEntityManager(gameState->World);
auto& manager = GetEntityManager();
Door* door = MakeEntity<Door>(manager, 10.0f, 2.0f);
door->IsOpened = true;
@@ -66,16 +88,5 @@ extern "C" JULIET_API void GameInit(GameInitParams* params)
printf("Rock has %d health points\n", rock->Health);
}
extern "C" JULIET_API void __cdecl GameShutdown()
{
printf("Shutting down game...\n");
using namespace Game;
ShutdownEntityManager();
}
extern "C" JULIET_API void __cdecl GameUpdate([[maybe_unused]] float deltaTime)
{
// printf("Updating game...\n");
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include <Core/Memory/MemoryArena.h>
struct EntityManager;
struct World
{
Juliet::Arena* WorldArena;
EntityManager* EntityManager;
};
struct GameState
{
Juliet::Arena* TotalArena;
World* World;
float TotalTime;
int Score;
};
extern GameState* GetGameState();
-9
View File
@@ -24,23 +24,14 @@ Global
{1720427b-c8ba-3195-f931-e97f6d6125c1}.Release|x64.ActiveCfg = Release|x64
{1720427b-c8ba-3195-f931-e97f6d6125c1}.Release|x64.Build.0 = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.ActiveCfg = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.Build.0 = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.ActiveCfg = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.Build.0 = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.ActiveCfg = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.Build.0 = Release|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Debug|x64.ActiveCfg = Debug|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Debug|x64.Build.0 = Debug|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Profile|x64.ActiveCfg = Profile|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Profile|x64.Build.0 = Profile|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Release|x64.ActiveCfg = Release|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Release|x64.Build.0 = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.ActiveCfg = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.Build.0 = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.ActiveCfg = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.Build.0 = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
-3
View File
@@ -147,10 +147,7 @@
<ClInclude Include="include\Core\Common\CoreUtils.h" />
<ClInclude Include="include\Core\Common\CRC32.h" />
<ClInclude Include="include\Core\Common\EnumUtils.h" />
<ClInclude Include="include\Core\Common\NonCopyable.h" />
<ClInclude Include="include\Core\Common\NonMovable.h" />
<ClInclude Include="include\Core\Common\NonNullPtr.h" />
<ClInclude Include="include\Core\Common\Singleton.h" />
<ClInclude Include="include\Core\Common\String.h" />
<ClInclude Include="include\Core\Container\Vector.h" />
<ClInclude Include="include\Core\HAL\Display\Display.h" />
-9
View File
@@ -318,18 +318,9 @@
<ClInclude Include="include\Core\Common\EnumUtils.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\NonCopyable.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\NonMovable.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\NonNullPtr.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\Singleton.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\String.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
+17 -14
View File
@@ -15,7 +15,7 @@ namespace Juliet
class NonNullPtr
{
public:
inline NonNullPtr(Type* ptr)
constexpr NonNullPtr(Type* ptr)
: InternalPtr(ptr)
{
Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
@@ -23,14 +23,14 @@ namespace Juliet
template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*>
NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
constexpr NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
: InternalPtr(otherPtr.Get())
{
Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null.");
}
// Assignment
NonNullPtr& operator=(Type* ptr)
[[nodiscard]] constexpr NonNullPtr& operator=(Type* ptr)
{
Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!");
InternalPtr = ptr;
@@ -39,68 +39,71 @@ namespace Juliet
template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*>
NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
[[nodiscard]] constexpr NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
{
InternalPtr = otherPtr.Get();
return *this;
}
// Accessors
operator Type*() const
[[nodiscard]] constexpr operator Type*() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
Type* Get() const
[[nodiscard]] constexpr Type* Get() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
Type& operator*() const
[[nodiscard]] constexpr Type& operator*() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return *InternalPtr;
}
inline Type* operator->() const
[[nodiscard]] constexpr Type* operator->() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
// Comparisons
bool operator==(const NonNullPtr& otherPtr) const { return InternalPtr == otherPtr.InternalPtr; }
[[nodiscard]] constexpr bool operator==(const NonNullPtr& otherPtr) const
{
return InternalPtr == otherPtr.InternalPtr;
}
template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType>
bool operator==(OtherType* otherRawPtr) const
[[nodiscard]] constexpr bool operator==(OtherType* otherRawPtr) const
{
return InternalPtr == otherRawPtr;
}
template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType>
friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
[[nodiscard]] constexpr friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
{
return otherRawPtr == nonNullPtr.InternalPtr;
}
// Forbid assigning a nullptr at compile time
NonNullPtr(std::nullptr_t)
constexpr NonNullPtr(std::nullptr_t)
: InternalPtr(nullptr)
{
static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value");
}
NonNullPtr& operator=(std::nullptr_t)
[[nodiscard]] constexpr NonNullPtr& operator=(std::nullptr_t)
{
static_assert(sizeof(Type) == 0, "Trying to assign a NonNullPtr with a nullptr value");
return *this;
}
explicit operator bool() const { return true; }
[[nodiscard]] constexpr explicit operator bool() const { return InternalPtr != nullptr; }
private:
Type* InternalPtr;
+5
View File
@@ -18,12 +18,16 @@ namespace Juliet
Count = 0;
Capacity = 0;
Arena = arena;
ArenaPosAtCreation = ArenaPos(Arena);
Reserve(ReserveSize);
}
void Destroy()
{
Assert(ArenaPos(Arena) == ArenaPosAtCreation + sizeof(Type) * Capacity);
ArenaPopTo(Arena, ArenaPosAtCreation);
DataFirst = DataLast = Data = nullptr;
Count = 0;
Capacity = 0;
@@ -203,6 +207,7 @@ namespace Juliet
Type* Data = nullptr;
size_t Count = 0;
size_t Capacity = 0;
index_t ArenaPosAtCreation = 0;
JULIET_DEBUG_ONLY(const char* Name = "VectorArena";)
};
static_assert(std::is_standard_layout_v<VectorArena<int>>,
+2 -2
View File
@@ -15,9 +15,9 @@ namespace Juliet
struct Arena;
struct GameInitParams
struct GameData
{
Arena* GameArena;
struct GameState* GameState;
Arena* ScratchArena;
};
-18
View File
@@ -12,14 +12,6 @@ namespace Juliet
constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64);
constexpr global uint64 k_ArenaHeaderSize = 128;
struct ArenaFreeNode
{
ArenaFreeNode* Next;
ArenaFreeNode* Previous;
index_t Position;
size_t Size;
};
#if JULIET_DEBUG
struct ArenaDebugInfo;
#endif
@@ -41,10 +33,6 @@ namespace Juliet
Arena* FreeBlockLast;
ArenaFreeNode* FreeNodes;
bool AllowRealloc : 1;
JULIET_DEBUG_ONLY(uint16 LostNodeCount;)
JULIET_DEBUG_ONLY(bool CanReserveMore : 1;)
@@ -66,9 +54,6 @@ namespace Juliet
uint64 ReserveSize = g_Arena_Default_Reserve_Size;
uint64 CommitSize = g_Arena_Default_Commit_Size;
// True: All push will be 32 bytes minimum
bool AllowRealloc = false;
// When false, will assert if a new block is reserved.
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
};
@@ -77,12 +62,9 @@ namespace Juliet
const std::source_location& loc = std::source_location::current());
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena);
// Raw Push, can be used but templated helpers exists below
// Raw Push, can be used but templated helpers exists below
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
[[nodiscard]] JULIET_API void* ArenaReallocate(NonNullPtr<Arena> arena, void* oldPtr, size_t oldSize, size_t newSize,
size_t align, bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position);
JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount);
JULIET_API void ArenaClear(NonNullPtr<Arena> arena);
+5 -3
View File
@@ -11,7 +11,7 @@ namespace Juliet
{
void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename)
{
code.Arena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Hot Reload"));
code.Arena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_ONLY(, "Hot Reload"));
// Get the app base path and build the dll path from there.
String basePath = GetBasePath();
@@ -25,7 +25,8 @@ namespace Juliet
const size_t dllFullPathLength =
basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
code.DLLFullPath.Data = static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "DLL Path")));
code.DLLFullPath.Data =
static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "DLL Path")));
int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
{
@@ -38,7 +39,8 @@ 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*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "Lock File Path")));
code.LockFullPath.Data =
static_cast<char*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "Lock File Path")));
writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
if (writtenSize < static_cast<int>(lockPathLength) - 1)
{
@@ -112,11 +112,10 @@ namespace Juliet
else
{
code.IsValid = false;
break;
}
}
}
// Scratch memory, no free needed
}
if (!code.IsValid)
-104
View File
@@ -18,12 +18,6 @@ namespace Juliet
constexpr uint64 k_PageSize = Kilobytes(4);
} // namespace
namespace
{
static_assert(sizeof(ArenaFreeNode) == 32, "ArenaFreeNode should be 32 bytes and not more");
constexpr size_t k_ArenaFreeNodeSize = sizeof(ArenaFreeNode);
} // namespace
// 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)
@@ -51,9 +45,6 @@ namespace Juliet
arena->BasePosition = 0;
arena->Position = k_ArenaHeaderSize;
arena->FreeNodes = nullptr;
arena->AllowRealloc = params.AllowRealloc;
#if JULIET_DEBUG
arena->CanReserveMore = params.CanReserveMore;
arena->FirstDebugInfo = nullptr;
@@ -86,52 +77,6 @@ namespace Juliet
size_t positionPrePush = AlignPow2(current->Position, align);
size_t positionPostPush = positionPrePush + size;
if (arena->AllowRealloc)
{
size = Max(size, k_ArenaFreeNodeSize);
for (ArenaFreeNode* freeNode = current->FreeNodes; freeNode != nullptr; freeNode = freeNode->Next)
{
if (size <= freeNode->Size)
{
index_t position = freeNode->Position;
size_t remainingSize = freeNode->Size - size;
if (remainingSize < k_ArenaFreeNodeSize)
{
ArenaFreeNode* previous = freeNode->Previous;
ArenaFreeNode* next = freeNode->Next;
if (previous)
{
previous->Next = next;
}
if (next)
{
next->Previous = previous;
}
#if JULIET_DEBUG
if (remainingSize > 0)
{
++current->LostNodeCount;
}
#endif
}
else
{
freeNode->Position += size;
}
auto* result = reinterpret_cast<Byte*>(current) + position;
if (shouldBeZeroed)
{
MemoryZero(result, size);
}
return result;
}
}
}
// If allowed and needed, add a new block and chain it to the arena.
if (current->Reserved < positionPostPush /* flags : chaining allowed */)
{
@@ -225,55 +170,6 @@ namespace Juliet
return result;
}
void* ArenaReallocate(NonNullPtr<Arena> arena, void* oldPtr, size_t oldSize, size_t newSize, size_t align,
bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag))
{
void* result = ArenaPush(arena, newSize, align, shouldBeZeroed JULIET_DEBUG_ONLY(, tag));
// Find the correct block to release
Arena* block = nullptr;
for (block = arena->Current; block != nullptr; block = block->Previous)
{
if ((reinterpret_cast<Byte*>(block) < static_cast<Byte*>(oldPtr)) &&
(static_cast<Byte*>(oldPtr) <= (reinterpret_cast<Byte*>(block) + block->Reserved)))
{
break;
}
}
Assert(block != nullptr);
// Copy old to new
MemCopy(result, oldPtr, std::min(oldSize, newSize));
// Zero the old memory
MemoryZero(oldPtr, oldSize);
if (oldSize >= sizeof(ArenaFreeNode))
{
ArenaFreeNode* freeNode = static_cast<ArenaFreeNode*>(oldPtr);
ptrdiff_t posPtr = static_cast<Byte*>(oldPtr) - reinterpret_cast<Byte*>(block);
index_t position = static_cast<index_t>(posPtr);
freeNode->Position = position;
freeNode->Size = oldSize;
// Insert at head of the free list
freeNode->Next = block->FreeNodes;
freeNode->Previous = nullptr;
if (block->FreeNodes)
{
block->FreeNodes->Previous = freeNode;
}
block->FreeNodes = freeNode;
#if JULIET_DEBUG
// Remove the debug info for the old allocation (since it's now free)
size_t oldOffset = static_cast<size_t>(static_cast<Byte*>(oldPtr) - reinterpret_cast<Byte*>(block));
DebugArenaRemoveAllocation(block, oldOffset);
#endif
}
return result;
}
void ArenaPopTo(NonNullPtr<Arena> arena, size_t position)
{
size_t clampedPosition = ClampBottom(k_ArenaHeaderSize, position);
@@ -117,60 +117,6 @@ namespace Juliet::UnitTest
ArenaRelease(testArena);
{
// Test reallocate
Arena* arena = ArenaAllocate({ .AllowRealloc = true } JULIET_DEBUG_ONLY(, "Test Realloc"));
char* charArray = ArenaPushArray<char>(arena, 128);
char* secondCharArray = ArenaPushArray<char>(arena, 128);
char* thirdCharArray = ArenaPushArray<char>(arena, 128);
secondCharArray = static_cast<char*>(ArenaReallocate(arena, secondCharArray, 128, 256, alignof(char), true JULIET_DEBUG_ONLY(, "ReallocChar")));
char* fourthCharArray = ArenaPushArray<char>(arena, 128);
Assert(charArray);
Assert(secondCharArray);
Assert(thirdCharArray);
Assert(fourthCharArray);
ArenaRelease(arena);
}
{
// Test Reallocate Shrink (Buffer Overflow Bug Check)
Arena* arena = ArenaAllocate({ .AllowRealloc = true } JULIET_DEBUG_ONLY(, "Test Shrink"));
size_t largeSize = 100;
char* large = ArenaPushArray<char>(arena, largeSize);
MemSet(large, 'A', largeSize);
size_t smallSize = 50;
char* smallData = static_cast<char*>(ArenaReallocate(arena, large, largeSize, smallSize, alignof(char), true JULIET_DEBUG_ONLY(, "ResizeSmall")));
for (size_t i = 0; i < smallSize; ++i)
{
Assert(smallData[i] == 'A');
}
// Allocate next block (should be immediately after 'small')
// Don't zero it, if overflow happened it will contain 'A's
char* next = static_cast<char*>(ArenaPush(arena, 50, alignof(char), false JULIET_DEBUG_ONLY(, "OverflowCheck")));
bool corrupted = false;
for(size_t i = 0; i < 50; ++i)
{
if (next[i] == 'A')
{
corrupted = true;
break;
}
}
Assert(!corrupted);
ArenaRelease(arena);
}
printf("All Paged MemoryArena tests passed.\n");
}
} // namespace Juliet::UnitTest
@@ -450,24 +450,6 @@ namespace Juliet::Debug
info = info->Next;
ImGui::PopID();
}
// Draw Free Nodes (Holes) if Realloc is enabled
if (arena->AllowRealloc && blk->FreeNodes)
{
ArenaFreeNode* freeNode = blk->FreeNodes;
while (freeNode)
{
float fxStart = pos.x + static_cast<float>(static_cast<double>(freeNode->Position) * scale);
float fWidth = static_cast<float>(static_cast<double>(freeNode->Size) * scale);
ImVec2 fMin(fxStart, pos.y + 1);
ImVec2 fMax(fxStart + fWidth, pos.y + blockHeight - 1);
dl->AddRectFilled(fMin, fMax, IM_COL32(50, 50, 50, 200));
freeNode = freeNode->Next;
}
}
}
pos.y += blockHeight + blockSpacing;
+2 -1
View File
@@ -154,7 +154,8 @@ namespace Juliet
void InitializeEngine(JulietInit_Flags flags)
{
EngineInstance.PlatformArena = ArenaAllocate({ .AllowRealloc = true } JULIET_DEBUG_PARAM("Platform Arena"));
EngineInstance.PlatformArena =
ArenaAllocate({ .ReserveSize = Megabytes(128) } JULIET_DEBUG_PARAM("Platform Arena"));
InitializeLogManager();
@@ -549,8 +549,8 @@ namespace Juliet::D3D12
driver->D3D12SerializeVersionedRootSignatureFct = nullptr;
Assert(ArenaPos(driver->DriverArena) == sizeof(D3D12Driver)); // Verify we didnt forget to release something
ArenaRelease(driver->DriverArena);
Free(driver.Get());
}
bool AttachToWindow(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window)
@@ -698,10 +698,10 @@ namespace Juliet::D3D12
GraphicsDevice* CreateGraphicsDevice(bool enableDebug)
{
auto driver = static_cast<D3D12Driver*>(Calloc(1, sizeof(D3D12Driver)));
Arena* driverArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "D3D12 Driver Arena"));
D3D12Driver* driver = ArenaPushStruct<D3D12Driver>(driverArena JULIET_DEBUG_PARAM("D3D12Driver struct"));
// TODO : Convert everything to arena
driver->DriverArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "D3D12 Driver"));
driver->DriverArena = driverArena;
#if JULIET_DEBUG
#ifdef IDXGIINFOQUEUE_SUPPORTED
@@ -517,13 +517,21 @@ namespace Juliet::D3D12
// Fix SRV format for Depth Buffers (TypeLess -> Typed)
if (createInfo.Format == TextureFormat::D32_FLOAT)
{
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
}
else if (createInfo.Format == TextureFormat::D16_UNORM)
{
srvDesc.Format = DXGI_FORMAT_R16_UNORM;
}
else if (createInfo.Format == TextureFormat::D24_UNORM_S8_UINT)
{
srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
}
else if (createInfo.Format == TextureFormat::D32_FLOAT_S8_UINT)
{
srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
}
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+2 -2
View File
@@ -58,7 +58,6 @@ namespace Juliet
{
if (GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(config.EnableDebug))
{
newDevice->Name = chosenFactory->Name;
return newDevice;
}
@@ -371,7 +370,8 @@ namespace Juliet
GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GraphicsDevice> device, const BufferCreateInfo& createInfo)
{
return device->CreateGraphicsBuffer(device->Driver, createInfo.Size, createInfo.Stride, createInfo.Usage, createInfo.IsDynamic);
return device->CreateGraphicsBuffer(device->Driver, createInfo.Size, createInfo.Stride, createInfo.Usage,
createInfo.IsDynamic);
}
GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, const TransferBufferCreateInfo& createInfo)
+5 -16
View File
@@ -87,17 +87,16 @@ using namespace Juliet;
namespace
{
using GameInit_t = void (*)(GameInitParams*);
using GameShutdown_t = void (*)(void);
using GameUpdate_t = void (*)(float deltaTime);
using GameUpdate_t = void (*)(GameData* params, float deltaTime);
struct GameFunctionTable
{
GameInit_t Init = nullptr;
GameShutdown_t Shutdown = nullptr;
GameUpdate_t Update = nullptr;
} Game;
GameData Data;
const char* GameFunctionTable[] = { "GameInit", "GameShutdown", "GameUpdate" };
const char* GameFunctionTable[] = { "GameShutdown", "GameUpdate" };
LightID RedLightID = 0;
LightID BlueLightID = 0;
@@ -178,13 +177,7 @@ void JulietApplication::Init(NonNullPtr<Arena>)
GameCode.FunctionCount = ArraySize(GameFunctionTable);
GameCode.FunctionNames = GameFunctionTable;
InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
if ((Running = GameCode.IsValid))
{
GameInitParams params;
params.GameArena = GameArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Game Arena"));
params.ScratchArena = GameScratchArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Scratch Arena"));
Game.Init(&params);
}
Running = GameCode.IsValid;
}
}
@@ -429,8 +422,6 @@ void JulietApplication::Update()
ImGui::End();
#endif
ArenaClear(GameScratchArena);
Vector3 redLightPos = { 5.0f, 5.0f, 2.0f };
Vector3 blueLightPos = { -5.0f, 0.0f, 2.0f };
@@ -497,7 +488,7 @@ void JulietApplication::Update()
DebugDisplay_DrawSphere(blueLightPos, 0.5f, { 0.0f, 0.0f, 1.0f, 1.0f }, true);
DebugDisplay_DrawSphere(redLightPos, 0.5f, { 1.0f, 0.0f, 0.0f, 1.0f }, true);
Game.Update(0.0f);
Game.Update(&Data, 0.0f);
if (ShouldReloadCode(GameCode))
{
@@ -545,8 +536,6 @@ void JulietApplication::Update()
Debug::DebugDrawMemoryArena();
#endif
}
ArenaClear(GameScratchArena);
}
void JulietApplication::OnPreRender(CommandList* /*cmd*/) {}
-2
View File
@@ -43,8 +43,6 @@ class JulietApplication : public Juliet::IApplication
Juliet::HotReloadCode GameCode = {};
Juliet::GraphicsPipeline* GraphicsPipeline = {};
Juliet::Texture* DepthBuffer = {};
Juliet::Arena* GameArena = nullptr;
Juliet::Arena* GameScratchArena = nullptr;
int AutoCloseFrameCount = -1;
bool Running = false;
-6
View File
@@ -22,17 +22,11 @@ Global
{c7df05fe-d5d5-db2a-af36-e7d71d325fda}.Release|x64.ActiveCfg = Release|x64
{c7df05fe-d5d5-db2a-af36-e7d71d325fda}.Release|x64.Build.0 = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.ActiveCfg = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.Build.0 = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.ActiveCfg = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.Build.0 = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.ActiveCfg = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.Build.0 = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.ActiveCfg = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.Build.0 = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.ActiveCfg = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.Build.0 = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
-6
View File
@@ -22,17 +22,11 @@ Global
{767620a7-b286-e7a1-9f79-3e14ce9e5ab1}.Release|x64.ActiveCfg = Release|x64
{767620a7-b286-e7a1-9f79-3e14ce9e5ab1}.Release|x64.Build.0 = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.ActiveCfg = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.Build.0 = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.ActiveCfg = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.Build.0 = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.ActiveCfg = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.Build.0 = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.ActiveCfg = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.Build.0 = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.ActiveCfg = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.Build.0 = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+7 -3
View File
@@ -1091,10 +1091,14 @@ static void GenerateSolution(const char* slnName, const char** projectNames, con
const char* configs[] = { "Debug", "Profile", "Release" };
for (int c = 0; c < 3; c++) {
offset += sprintf_s(buf + offset, (4 * 1024 * 1024) - offset,
" {%s}.%s|x64.ActiveCfg = %s|x64\n"
" {%s}.%s|x64.Build.0 = %s|x64\n",
projectGuids[i], configs[c], configs[c],
" {%s}.%s|x64.ActiveCfg = %s|x64\n",
projectGuids[i], configs[c], configs[c]);
if (i == 0) {
offset += sprintf_s(buf + offset, (4 * 1024 * 1024) - offset,
" {%s}.%s|x64.Build.0 = %s|x64\n",
projectGuids[i], configs[c], configs[c]);
}
}
}