diff --git a/Juliet/Juliet.vcxproj b/Juliet/Juliet.vcxproj
index 1a25475..de66553 100644
--- a/Juliet/Juliet.vcxproj
+++ b/Juliet/Juliet.vcxproj
@@ -115,6 +115,7 @@
+
@@ -218,9 +219,10 @@
+
+
-
{ab9c7e88-6c94-4f93-bc2a-7f5284b7d434}
diff --git a/Juliet/Juliet.vcxproj.filters b/Juliet/Juliet.vcxproj.filters
index 863a7bf..9f1d957 100644
--- a/Juliet/Juliet.vcxproj.filters
+++ b/Juliet/Juliet.vcxproj.filters
@@ -192,6 +192,9 @@
src\Core\Common
+
+ src\Core\Container
+
src\Core\HAL\Display
@@ -501,6 +504,12 @@
src\Graphics
+
+ src\UnitTest\Container
+
+
+ src\UnitTest
+
@@ -642,6 +651,11 @@
{f763d340-6c94-4f93-bc2a-7f5284b7d434}
+
+
+ {3e286bee-6c94-4f93-bc2a-7f5284b7d434}
+
+
{82da0982-6c94-4f93-bc2a-7f5284b7d434}
@@ -772,4 +786,14 @@
{0fd13bb0-6c94-4f93-bc2a-7f5284b7d434}
+
+
+ {3fba0971-6c94-4f93-bc2a-7f5284b7d434}
+
+
+
+
+ {a650fa16-6c94-4f93-bc2a-7f5284b7d434}
+
+
\ No newline at end of file
diff --git a/Juliet/include/Core/Common/CoreUtils.h b/Juliet/include/Core/Common/CoreUtils.h
index 58edf80..4da2dba 100644
--- a/Juliet/include/Core/Common/CoreUtils.h
+++ b/Juliet/include/Core/Common/CoreUtils.h
@@ -14,17 +14,62 @@ namespace Juliet
#define global static
+ // 1. Stringify helpers
+#define JULIET_STR(x) #x
+#define JULIET_TOSTRING(x) JULIET_STR(x)
+
+ // 2. Define the pragma operator based on compiler
+#if defined(__clang__) || defined(__GNUC__)
+#define JULIET_PRAGMA(x) _Pragma(#x)
+#define JULIET_SUPPRESS_MSVC(id)
+#define JULIET_SUPPRESS_CLANG(str) JULIET_PRAGMA(clang diagnostic ignored str)
+#elif defined(_MSC_VER)
+#define JULIET_PRAGMA(x) __pragma(x)
+#define JULIET_SUPPRESS_MSVC(id) JULIET_PRAGMA(warning(disable : id))
+#define JULIET_SUPPRESS_CLANG(str)
+#else
+#define JULIET_PRAGMA(x)
+#define JULIET_SUPPRESS_MSVC(id)
+#define JULIET_SUPPRESS_CLANG(str)
+#endif
+
+ // 3. The Agnostic "Push/Pop"
+#if defined(__clang__)
+#define JULIET_WARNING_PUSH JULIET_PRAGMA(clang diagnostic push)
+#define JULIET_WARNING_POP JULIET_PRAGMA(clang diagnostic pop)
+#elif defined(_MSC_VER)
+#define JULIET_WARNING_PUSH JULIET_PRAGMA(warning(push))
+#define JULIET_WARNING_POP JULIET_PRAGMA(warning(pop))
+#else
+#define JULIET_WARNING_PUSH
+#define JULIET_WARNING_POP
+#endif
+
+#if defined(_MSC_VER)
+ // MSVC specific intrinsic
+#define JULIET_PLATFORM_BREAK() (__nop(), __debugbreak())
+#elif defined(__clang__) || defined(__GNUC__)
+ // Clang/GCC specific intrinsic
+#define JULIET_PLATFORM_BREAK() __builtin_trap()
+#else
+#include
+#define JULIET_PLATFORM_BREAK() raise(SIGTRAP)
+#endif
+
#if JULIET_DEBUG
#define JULIET_ASSERT_INTERNAL(expression, message) \
- __pragma(warning(push)) __pragma(warning(disable : 4127)) __pragma(warning(disable : 4548)) do \
+ JULIET_WARNING_PUSH \
+ JULIET_SUPPRESS_CLANG("-Wextra-semi-stmt") \
+ JULIET_SUPPRESS_MSVC(4127) \
+ JULIET_SUPPRESS_MSVC(4548) \
{ \
- if (!(expression)) \
+ if (!(expression)) [[unlikely]] \
{ \
Juliet::JulietAssert(#expression, message); \
} \
} \
- while (0) \
- __pragma(warning(pop))
+ JULIET_WARNING_POP \
+ static_assert(true, "")
#define AssertHR(hr_expression, message) \
do \
@@ -117,11 +162,11 @@ namespace Juliet
return (x + alignment - 1) & ~(alignment - 1);
}
- inline void Swap(auto* Restrict& a, auto* Restrict& b)
+ inline void Swap(auto* Restrict a, auto* Restrict b)
{
- auto* temp = a;
- a = b;
- b = temp;
+ auto temp = *a;
+ *a = *b;
+ *b = temp;
}
// Move to another file dedicated to those
diff --git a/Juliet/include/Core/Container/Vector.h b/Juliet/include/Core/Container/Vector.h
index f542b5d..c3cc240 100644
--- a/Juliet/include/Core/Container/Vector.h
+++ b/Juliet/include/Core/Container/Vector.h
@@ -10,6 +10,7 @@ namespace Juliet
template
struct VectorArena
{
+ public:
VectorArena()
: First(nullptr)
, Count(0)
@@ -39,12 +40,13 @@ namespace Juliet
Assert(index < Count);
Assert(Count > 0);
- Type* baseAdr = First;
Type* elementAdr = First + index;
// Swap Last and element
Swap(Last, elementAdr);
+ --Last;
--Count;
+ ArenaPop(Arena, Stride);
}
void Clear()
diff --git a/Juliet/src/Core/Common/CoreUtils.cpp b/Juliet/src/Core/Common/CoreUtils.cpp
index a2605ed..cecff81 100644
--- a/Juliet/src/Core/Common/CoreUtils.cpp
+++ b/Juliet/src/Core/Common/CoreUtils.cpp
@@ -12,9 +12,7 @@ namespace Juliet
Log(LogLevel::Error, LogCategory::Core, "--- ASSERTION FAILED ---");
Log(LogLevel::Error, LogCategory::Core, "Expression: %s", expression);
Log(LogLevel::Error, LogCategory::Core, "Message: %s", message);
- Log(LogLevel::Error, LogCategory::Core, "Location: %s(%u): %s",
- location.file_name(),
- location.line(),
+ Log(LogLevel::Error, LogCategory::Core, "Location: %s(%u): %s", location.file_name(), location.line(),
location.function_name());
if (handleResult < 0)
@@ -26,14 +24,7 @@ namespace Juliet
Log(LogLevel::Error, LogCategory::Core, "-------------------------");
- if (IsDebuggerPresent())
- {
- __debugbreak();
- }
- else
- {
- exit(1);
- }
+ JULIET_PLATFORM_BREAK();
}
void Free(ByteBuffer& buffer)
diff --git a/Juliet/src/Core/Memory/MemoryArenaTests.cpp b/Juliet/src/Core/Memory/MemoryArenaTests.cpp
index bf9a4bc..cc630e8 100644
--- a/Juliet/src/Core/Memory/MemoryArenaTests.cpp
+++ b/Juliet/src/Core/Memory/MemoryArenaTests.cpp
@@ -89,8 +89,8 @@ namespace Juliet::UnitTest
Assert(reservedSizePreBigArray == testArena->Current->BasePosition);
// TODO Get page size from os kernel call (dwPageSize)
- constexpr uint64 k_PageSize = Kilobytes(4);
- size_t reserve_sizeAlignToPage = AlignPow2(reserve_size, k_PageSize);
+ constexpr uint64 k_PageSizeUnitTest = Kilobytes(4);
+ size_t reserve_sizeAlignToPage = AlignPow2(reserve_size, k_PageSizeUnitTest);
bool isReserveSizeSame = testArena->Current->Reserved == reserve_sizeAlignToPage;
Assert(isReserveSizeSame);
diff --git a/Juliet/src/Engine/Engine.cpp b/Juliet/src/Engine/Engine.cpp
index 7c3b72a..6d1f90b 100644
--- a/Juliet/src/Engine/Engine.cpp
+++ b/Juliet/src/Engine/Engine.cpp
@@ -17,9 +17,9 @@
namespace Juliet
{
- #ifdef JULIET_DEBUG
+#if JULIET_DEBUG
extern void RunUnitTests();
- #endif
+#endif
namespace
{
@@ -135,10 +135,10 @@ namespace Juliet
{
InitializeLogManager();
MemoryArenasInit();
-
- #ifdef JULIET_DEBUG
+
+#if JULIET_DEBUG
RunUnitTests();
- #endif
+#endif
InitFilesystem();
diff --git a/Juliet/src/UnitTest/Container/VectorUnitTest.cpp b/Juliet/src/UnitTest/Container/VectorUnitTest.cpp
index dc69046..3ee8450 100644
--- a/Juliet/src/UnitTest/Container/VectorUnitTest.cpp
+++ b/Juliet/src/UnitTest/Container/VectorUnitTest.cpp
@@ -1,57 +1,117 @@
-#ifdef JULIET_DEBUG
+#if JULIET_DEBUG
-#include
#include
+#include
namespace Juliet
{
void VectorUnitTest()
{
- // Basic usage test
+ // Test 1: Integer VectorArena - Basic PushBack and Access
{
- Vector vec;
- Assert(vec.empty());
- Assert(vec.size() == 0);
+ VectorArena vec;
+ Assert(vec.Size() == 0);
+ Assert(vec.begin() == vec.end());
- vec.push_back(10);
- Assert(!vec.empty());
- Assert(vec.size() == 1);
+ vec.PushBack(10);
+ Assert(vec.Size() == 1);
Assert(vec[0] == 10);
+ Assert(*vec.begin() == 10);
- vec.push_back(20);
- Assert(vec.size() == 2);
+ vec.PushBack(20);
+ Assert(vec.Size() == 2);
+ Assert(vec[0] == 10);
Assert(vec[1] == 20);
- // Test iteration (std::vector iterator compatibility)
+ vec.PushBack(30);
+ Assert(vec.Size() == 3);
+ Assert(vec[2] == 30);
+
+ // Test Iteration
int sum = 0;
for (int val : vec)
{
sum += val;
}
- Assert(sum == 30);
-
- vec.clear();
- Assert(vec.empty());
- Assert(vec.size() == 0);
+ Assert(sum == 60);
}
- // Test with complex types (std::string) to ensure proper construction/destruction
- // Note: Vector.h currently inherits from std::vector, so this tests std::vector really.
+ // Test 2: RemoveAtFast
{
- struct TestStruct
+ VectorArena vec;
+ vec.PushBack(10);
+ vec.PushBack(20);
+ vec.PushBack(30);
+
+ // Initial: [10, 20, 30]
+ // Remove index 0 (value 10). Should swap with Last (30) and pop last.
+ // Expected: [30, 20]
+ vec.RemoveAtFast(0);
+ Assert(vec.Size() == 2);
+ Assert(vec[0] == 30);
+ Assert(vec[1] == 20);
+
+ // Remove index 1 (value 20). Last is 20. Swap 20 with 20.
+ // Expected: [30]
+ vec.RemoveAtFast(1);
+ Assert(vec.Size() == 1);
+ Assert(vec[0] == 30);
+
+ // Remove remaining element
+ vec.RemoveAtFast(0);
+ Assert(vec.Size() == 0);
+ }
+
+ // Test 3: Clear and Reuse
+ {
+ VectorArena vec;
+ vec.PushBack(100);
+ vec.PushBack(200);
+ Assert(vec.Size() == 2);
+
+ vec.Clear();
+ Assert(vec.Size() == 0);
+ Assert(vec.begin() == vec.end());
+
+ // Should be able to push again
+ vec.PushBack(300);
+ Assert(vec.Size() == 1);
+ Assert(vec[0] == 300);
+ }
+
+ // Test 4: Struct VectorArena (Testing Move Semantics and Complex Types)
+ {
+ struct TestItem
{
- int Value;
- bool Active;
+ int A;
+ float B;
+
+ bool operator==(const TestItem& other) const
+ {
+ float diff = B - other.B;
+ return A == other.A && (diff > -0.0001f && diff < 0.0001f);
+ }
};
- Vector structVec;
- structVec.push_back({ 42, true });
-
- Assert(structVec.size() == 1);
- Assert(structVec[0].Value == 42);
- Assert(structVec[0].Active == true);
+ VectorArena vec;
+ vec.PushBack({ 1, 1.0f });
+ vec.PushBack({ 2, 2.0f });
+ vec.PushBack({ 3, 3.0f });
+
+ Assert(vec.Size() == 3);
+ Assert(vec[0].A == 1);
+ Assert(vec[1].A == 2);
+
+ // Remove middle element (index 1, value {2, 2.0f})
+ // Should swap with last ({3, 3.0f})
+ // Result: [{1, 1.0f}, {3, 3.0f}]
+ vec.RemoveAtFast(1);
+ Assert(vec.Size() == 2);
+ // Use operator== to verify entire struct including float
+ Assert(vec[0] == (TestItem{ 1, 1.0f }));
+ Assert(vec[1] == (TestItem{ 3, 3.0f }));
}
}
-}
+} // namespace Juliet
-#endif
\ No newline at end of file
+#endif
diff --git a/Juliet/src/UnitTest/RunUnitTests.cpp b/Juliet/src/UnitTest/RunUnitTests.cpp
index eb342c6..537cc02 100644
--- a/Juliet/src/UnitTest/RunUnitTests.cpp
+++ b/Juliet/src/UnitTest/RunUnitTests.cpp
@@ -1,9 +1,8 @@
-#ifdef JULIET_DEBUG
+#if JULIET_DEBUG
+#include
#include
#include
-#include
-
namespace Juliet
{
@@ -18,6 +17,6 @@ namespace Juliet
LogMessage(LogCategory::Core, "Unit Tests Completed Successfully.");
}
-}
+} // namespace Juliet
-#endif
\ No newline at end of file
+#endif
diff --git a/current_run.log b/current_run.log
new file mode 100644
index 0000000..e69de29
diff --git a/test.txt b/test.txt
new file mode 100644
index 0000000..5669239
--- /dev/null
+++ b/test.txt
@@ -0,0 +1,15 @@
+--- Launching JulietApp.exe ---
+Platform: x64Clang
+Config: Debug
+Running Paged Memory Arena Tests...
+[2026-02-08 02:56:49.1217020] Allocating from W:\Classified\Juliet\Juliet\src\Core\Memory\MemoryArenaTests.cpp : 23l
+[2026-02-08 02:56:49.1220553] Allocating from W:\Classified\Juliet\Juliet\src\Core\Memory\MemoryArena.cpp : 99l
+[Success] Arena Pop
+All Paged MemoryArena tests passed.
+[2026-02-08 02:56:49.1319769] Starting Unit Tests...
+[2026-02-08 02:56:49.1320761] Allocating from Juliet/include\Core/Container/Vector.h : 19l
+[2026-02-08 02:56:49.1321474] --- ASSERTION FAILED ---
+[2026-02-08 02:56:49.1321999] Expression: vec[0] == 30
+[2026-02-08 02:56:49.1322519] Message: No additional information provided.
+[2026-02-08 02:56:49.1323083] Location: W:\Classified\Juliet\Juliet\src\UnitTest\Container\VectorUnitTest.cpp(45): void __cdecl Juliet::VectorUnitTest(void)
+[2026-02-08 02:56:49.1323588] -------------------------