Removing named namespace from code base.

This commit is contained in:
2026-08-22 21:39:21 -04:00
parent 678795b793
commit 4180622d6a
158 changed files with 12260 additions and 12648 deletions
+25 -25
View File
@@ -1,4 +1,4 @@
#include <Controller/DebugCameraController.h> #include <Controller/DebugCameraController.h>
#include <Controller/ControllerUtils.h> #include <Controller/ControllerUtils.h>
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
@@ -24,10 +24,10 @@ void ActivateDebugController()
{ {
Assert(gIsDebugCameraActive == false); Assert(gIsDebugCameraActive == false);
Juliet::Camera* currentCam = Juliet::GetCurrentCamera(); Camera* currentCam = GetCurrentCamera();
gPreviousCameraIndex = currentCam->Index; gPreviousCameraIndex = currentCam->Index;
Juliet::SetCurrentCamera(kDebugCamera); SetCurrentCamera(kDebugCamera);
gIsDebugCameraActive = true; gIsDebugCameraActive = true;
gFirstUpdate = true; gFirstUpdate = true;
@@ -41,7 +41,7 @@ void DeactivateDebugController()
gIsDebugCameraActive = false; gIsDebugCameraActive = false;
Juliet::SetCurrentCamera(gPreviousCameraIndex); SetCurrentCamera(gPreviousCameraIndex);
} }
bool IsDebugControllerActive() bool IsDebugControllerActive()
@@ -51,26 +51,26 @@ bool IsDebugControllerActive()
void UpdateDebugController(float dt) void UpdateDebugController(float dt)
{ {
Juliet::Camera* currentCam = Juliet::GetCurrentCamera(); Camera* currentCam = GetCurrentCamera();
if (gFirstUpdate) if (gFirstUpdate)
{ {
Juliet::Vector3 dir = Juliet::Vector3{ 0.0f, 0.0f, 0.0f } - currentCam->Position; Vector3 dir = Vector3{ 0.0f, 0.0f, 0.0f } - currentCam->Position;
dir = Juliet::Normalize(dir); dir = Normalize(dir);
gPitch = asinf(dir.z); gPitch = asinf(dir.z);
gYaw = atan2f(dir.y, dir.x); gYaw = atan2f(dir.y, dir.x);
gFirstUpdate = false; gFirstUpdate = false;
Juliet::Vector3 forward; Vector3 forward;
forward.x = cosf(gPitch) * cosf(gYaw); forward.x = cosf(gPitch) * cosf(gYaw);
forward.y = cosf(gPitch) * sinf(gYaw); forward.y = cosf(gPitch) * sinf(gYaw);
forward.z = sinf(gPitch); forward.z = sinf(gPitch);
Juliet::Vector3 right = Juliet::Normalize(Juliet::Cross(Juliet::Vector3{ 0.0f, 0.0f, 1.0f }, forward)); Vector3 right = Normalize(Cross(Vector3{ 0.0f, 0.0f, 1.0f }, forward));
currentCam->Target = currentCam->Position + forward; currentCam->Target = currentCam->Position + forward;
currentCam->Up = Juliet::Cross(forward, right); currentCam->Up = Cross(forward, right);
} }
bool isRightMouseButtonDown = Juliet::IsMouseButtonDown(Juliet::MouseButton::Right); bool isRightMouseButtonDown = IsMouseButtonDown(MouseButton::Right);
if (isRightMouseButtonDown && !gWasRightMouseButtonDown) if (isRightMouseButtonDown && !gWasRightMouseButtonDown)
{ {
gIsFpsModeActive = !gIsFpsModeActive; gIsFpsModeActive = !gIsFpsModeActive;
@@ -82,7 +82,7 @@ void UpdateDebugController(float dt)
return; return;
} }
Juliet::MousePosition mouseDelta = Juliet::GetMouseDelta(); MousePosition mouseDelta = GetMouseDelta();
float sensitivity = 0.005f; float sensitivity = 0.005f;
gYaw += mouseDelta.X * sensitivity; gYaw += mouseDelta.X * sensitivity;
@@ -91,52 +91,52 @@ void UpdateDebugController(float dt)
gPitch = std::min(gPitch, 1.5f); gPitch = std::min(gPitch, 1.5f);
gPitch = std::max(gPitch, -1.5f); gPitch = std::max(gPitch, -1.5f);
if (Juliet::IsKeyDown(Juliet::ScanCode::Q)) if (IsKeyDown(ScanCode::Q))
{ {
gYaw -= 2.0f * dt; gYaw -= 2.0f * dt;
} }
if (Juliet::IsKeyDown(Juliet::ScanCode::E)) if (IsKeyDown(ScanCode::E))
{ {
gYaw += 2.0f * dt; gYaw += 2.0f * dt;
} }
Juliet::Vector3 forward; Vector3 forward;
forward.x = cosf(gPitch) * cosf(gYaw); forward.x = cosf(gPitch) * cosf(gYaw);
forward.y = cosf(gPitch) * sinf(gYaw); forward.y = cosf(gPitch) * sinf(gYaw);
forward.z = sinf(gPitch); forward.z = sinf(gPitch);
Juliet::Vector3 right = Juliet::Normalize(Juliet::Cross(Juliet::Vector3{ 0.0f, 0.0f, 1.0f }, forward)); Vector3 right = Normalize(Cross(Vector3{ 0.0f, 0.0f, 1.0f }, forward));
Juliet::Vector3 defaultUp = Juliet::Cross(forward, right); Vector3 defaultUp = Cross(forward, right);
static const float kMovementPerFrame = 10.f; // 10m/s static const float kMovementPerFrame = 10.f; // 10m/s
float speedPerFrame = kMovementPerFrame; float speedPerFrame = kMovementPerFrame;
if (Juliet::IsKeyDown(Juliet::ScanCode::LeftShift)) if (IsKeyDown(ScanCode::LeftShift))
{ {
speedPerFrame *= 10.f; // 100m/s speedPerFrame *= 10.f; // 100m/s
} }
if (Juliet::IsKeyDown(Juliet::ScanCode::W)) if (IsKeyDown(ScanCode::W))
{ {
currentCam->Position = currentCam->Position + forward * (speedPerFrame * dt); currentCam->Position = currentCam->Position + forward * (speedPerFrame * dt);
} }
if (Juliet::IsKeyDown(Juliet::ScanCode::S)) if (IsKeyDown(ScanCode::S))
{ {
currentCam->Position = currentCam->Position - forward * (speedPerFrame * dt); currentCam->Position = currentCam->Position - forward * (speedPerFrame * dt);
} }
if (Juliet::IsKeyDown(Juliet::ScanCode::D)) if (IsKeyDown(ScanCode::D))
{ {
currentCam->Position = currentCam->Position + right * (speedPerFrame * dt); currentCam->Position = currentCam->Position + right * (speedPerFrame * dt);
} }
if (Juliet::IsKeyDown(Juliet::ScanCode::A)) if (IsKeyDown(ScanCode::A))
{ {
currentCam->Position = currentCam->Position - right * (speedPerFrame * dt); currentCam->Position = currentCam->Position - right * (speedPerFrame * dt);
} }
if (Juliet::IsKeyDown(Juliet::ScanCode::Space)) if (IsKeyDown(ScanCode::Space))
{ {
currentCam->Position = currentCam->Position + defaultUp * (speedPerFrame * dt); currentCam->Position = currentCam->Position + defaultUp * (speedPerFrame * dt);
} }
if (Juliet::IsKeyDown(Juliet::ScanCode::LeftControl)) if (IsKeyDown(ScanCode::LeftControl))
{ {
currentCam->Position = currentCam->Position - defaultUp * (speedPerFrame * dt); currentCam->Position = currentCam->Position - defaultUp * (speedPerFrame * dt);
} }
@@ -148,7 +148,7 @@ void UpdateDebugController(float dt)
#if JULIET_DEBUG #if JULIET_DEBUG
void RenderImGuiDebugController(float dt) void RenderImGuiDebugController(float dt)
{ {
Juliet::Camera* currentCam = Juliet::GetCurrentCamera(); Camera* currentCam = GetCurrentCamera();
ImGui::Text("Delta time: %f", dt); ImGui::Text("Delta time: %f", dt);
+2 -3
View File
@@ -1,13 +1,12 @@
#include <Debug/DebugTopBar.h> #include <Debug/DebugTopBar.h>
#include <game.h> #include <game.h>
#include <imgui.h> #include <imgui.h>
namespace namespace
{ {
Juliet::String GetGameModeName(GameMode gameMode) String GetGameModeName(GameMode gameMode)
{ {
using namespace Juliet;
switch (gameMode) switch (gameMode)
{ {
case GameMode::Editor: return WrapString("Editor"); case GameMode::Editor: return WrapString("Editor");
+7 -7
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
@@ -8,19 +8,19 @@
#define DECLARE_ENTITY() \ #define DECLARE_ENTITY() \
Entity* Base; \ Entity* Base; \
static const Juliet::Class* Kind; static const Class* Kind;
// Will register the class globally at launch // Will register the class globally at launch
#define DEFINE_ENTITY(entity) \ #define DEFINE_ENTITY(entity) \
constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \ constexpr Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
const Juliet::Class* entity::Kind = &entityKind##entity; const Class* entity::Kind = &entityKind##entity;
using DerivedType = void*; using DerivedType = void*;
struct Entity final struct Entity final
{ {
EntityID ID; EntityID ID;
const Juliet::Class* Kind; const Class* Kind;
DerivedType Derived; DerivedType Derived;
float X, Y; float X, Y;
index_t MeshInstance = indexMax; index_t MeshInstance = indexMax;
@@ -28,7 +28,7 @@ struct Entity final
template <typename EntityType> template <typename EntityType>
concept EntityConcept = requires(EntityType entity) { concept EntityConcept = requires(EntityType entity) {
requires std::same_as<decltype(entity.Kind), const Juliet::Class*>; requires std::same_as<decltype(entity.Kind), const Class*>;
requires std::same_as<decltype(entity.Base), Entity*>; requires std::same_as<decltype(entity.Base), Entity*>;
}; };
@@ -44,7 +44,7 @@ template <typename EntityType>
EntityType* MakeEntity(EntityManager& manager, float x, float y) EntityType* MakeEntity(EntityManager& manager, float x, float y)
{ {
auto* arena = manager.Arena; auto* arena = manager.Arena;
EntityType* result = Juliet::ArenaPushStruct<EntityType>(arena); EntityType* result = ArenaPushStruct<EntityType>(arena);
Entity base; Entity base;
base.X = x; base.X = x;
base.Y = y; base.Y = y;
+6 -6
View File
@@ -1,18 +1,18 @@
#include <Entity/EntityManager.h> #include <Entity/EntityManager.h>
#include <Entity/Entity.h> #include <Entity/Entity.h>
#include <Graphics/MeshRenderer.h> #include <Graphics/MeshRenderer.h>
EntityID EntityManager::ID = 0; EntityID EntityManager::ID = 0;
void InitEntityManager(Juliet::NonNullPtr<World> world) void InitEntityManager(NonNullPtr<World> world)
{ {
EntityManager* newManager = Juliet::ArenaPushStruct<EntityManager>(world->WorldArena); EntityManager* newManager = ArenaPushStruct<EntityManager>(world->WorldArena);
world->EntityManager = newManager; world->EntityManager = newManager;
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities")); newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
newManager->Arena = Juliet::ArenaAllocate({ .Name = "Entity Arena" }); newManager->Arena = ArenaAllocate({ .Name = "Entity Arena" });
} }
void ShutdownEntityManager() void ShutdownEntityManager()
@@ -22,7 +22,7 @@ void ShutdownEntityManager()
EntityManager& GetEntityManager() EntityManager& GetEntityManager()
{ {
Juliet::NonNullPtr entityManager = GetGameState()->World->EntityManager; NonNullPtr entityManager = GetGameState()->World->EntityManager;
return *entityManager; return *entityManager;
} }
@@ -37,7 +37,7 @@ void UpdateEntityManager(EntityManager& manager)
{ {
if (ent.MeshInstance != indexMax) if (ent.MeshInstance != indexMax)
{ {
Juliet::SetMeshInstanceTransform(ent.MeshInstance, Juliet::MatrixTranslation(ent.X, ent.Y, 0.0f)); SetMeshInstanceTransform(ent.MeshInstance, MatrixTranslation(ent.X, ent.Y, 0.0f));
} }
} }
} }
+4 -4
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
@@ -11,13 +11,13 @@ struct EntityManager
{ {
static EntityID ID; static EntityID ID;
Juliet::Arena* Arena; Arena* Arena;
// TODO: Should be a pool // TODO: Should be a pool
Juliet::VectorArena<Entity, 1024> Entities; VectorArena<Entity, 1024> Entities;
}; };
void InitEntityManager(Juliet::NonNullPtr<World> world); void InitEntityManager(NonNullPtr<World> world);
void ShutdownEntityManager(); void ShutdownEntityManager();
EntityManager& GetEntityManager(); EntityManager& GetEntityManager();
void RegisterEntity(EntityManager& manager, Entity* entity); void RegisterEntity(EntityManager& manager, Entity* entity);
+2 -4
View File
@@ -1,4 +1,4 @@
#include <game.h> #include <game.h>
#include <Controller/DebugCameraController.h> #include <Controller/DebugCameraController.h>
#include <Core/HAL/Filesystem/Filesystem.h> #include <Core/HAL/Filesystem/Filesystem.h>
@@ -31,14 +31,12 @@ extern "C" JULIET_API void __cdecl GameShutdown()
{ {
printf("Shutting down game...\n"); printf("Shutting down game...\n");
using namespace Juliet;
ShutdownEntityManager(); ShutdownEntityManager();
} }
extern "C" JULIET_API void __cdecl GameUpdate(Juliet::GameData* params, [[maybe_unused]] float deltaTime) extern "C" JULIET_API void __cdecl GameUpdate(GameData* params, [[maybe_unused]] float deltaTime)
{ {
using namespace Juliet;
gGameState = params->GameState; gGameState = params->GameState;
if (!gGameState) if (!gGameState)
+3 -3
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
@@ -6,7 +6,7 @@ struct EntityManager;
struct World struct World
{ {
Juliet::Arena* WorldArena; Arena* WorldArena;
EntityManager* EntityManager; EntityManager* EntityManager;
}; };
@@ -19,7 +19,7 @@ enum class GameMode
struct GameState struct GameState
{ {
Juliet::Arena* TotalArena; Arena* TotalArena;
World* World; World* World;
@@ -1,13 +1,10 @@
#pragma once #pragma once
#include <Core/Application/IApplication.h> #include <Core/Application/IApplication.h>
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet enum class JulietInit_Flags : uint8;
{
enum class JulietInit_Flags : uint8;
struct Arena; struct Arena;
extern JULIET_API void StartApplication(IApplication& app, JulietInit_Flags flags); extern JULIET_API void StartApplication(IApplication& app, JulietInit_Flags flags);
} // namespace Juliet
+23 -26
View File
@@ -1,32 +1,29 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
namespace Juliet struct Camera;
struct RenderPass;
struct CommandList;
struct Texture;
struct ColorTargetInfo;
struct DepthStencilTargetInfo;
struct Arena;
class IApplication
{ {
struct Camera; public:
struct RenderPass; virtual ~IApplication() = default;
struct CommandList; virtual void Init(NonNullPtr<Arena> arena) = 0;
struct Texture; virtual void Shutdown() = 0;
struct ColorTargetInfo; virtual void Update(float deltaTime) = 0;
struct DepthStencilTargetInfo; virtual bool IsRunning() = 0;
struct Arena;
class IApplication // Accessors for Engine Systems
{ virtual struct Window* GetPlatformWindow() = 0;
public: virtual struct GraphicsDevice* GetGraphicsDevice() = 0;
virtual ~IApplication() = default;
virtual void Init(NonNullPtr<Arena> arena) = 0;
virtual void Shutdown() = 0;
virtual void Update(float deltaTime) = 0;
virtual bool IsRunning() = 0;
// Accessors for Engine Systems // Render Lifecycle (Engine-Managed Render Loop)
virtual struct Window* GetPlatformWindow() = 0; virtual ColorTargetInfo GetColorTargetInfo(Texture* swapchainTexture) = 0;
virtual struct GraphicsDevice* GetGraphicsDevice() = 0; virtual DepthStencilTargetInfo* GetDepthTargetInfo() = 0;
};
// Render Lifecycle (Engine-Managed Render Loop)
virtual ColorTargetInfo GetColorTargetInfo(Texture* swapchainTexture) = 0;
virtual DepthStencilTargetInfo* GetDepthTargetInfo() = 0;
};
} // namespace Juliet
+46 -49
View File
@@ -1,58 +1,55 @@
#pragma once #pragma once
// From https://web.mit.edu/freebsd/head/sys/libkern/crc32.c // From https://web.mit.edu/freebsd/head/sys/libkern/crc32.c
namespace Juliet namespace details
{ {
namespace details constexpr uint32_t crc32_tab[] = {
{ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832,
constexpr uint32_t crc32_tab[] = { 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a,
0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074,
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525,
0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, };
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }
};
}
consteval uint32 crc32(const char* str, size_t length) consteval uint32 crc32(const char* str, size_t length)
{
const char* p = str;
uint32_t crc = ~0U;
while (length--)
{ {
const char* p = str; crc = details::crc32_tab[(crc ^ static_cast<uint8>(*p++)) & 0xFF] ^ (crc >> 8);
uint32_t crc = ~0U;
while (length--)
{
crc = details::crc32_tab[(crc ^ static_cast<uint8>(*p++)) & 0xFF] ^ (crc >> 8);
}
return crc ^ ~0U;
} }
return crc ^ ~0U;
}
consteval uint32 operator""_crc32(const char* str, size_t length) consteval uint32 operator""_crc32(const char* str, size_t length)
{ {
return crc32(str, length); return crc32(str, length);
} }
} // namespace Juliet
+119 -122
View File
@@ -1,18 +1,16 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet
{
#define global static #define global static
// 1. Stringify helpers // 1. Stringify helpers
#define JULIET_STR(x) #x #define JULIET_STR(x) #x
#define JULIET_TOSTRING(x) JULIET_STR(x) #define JULIET_TOSTRING(x) JULIET_STR(x)
// 2. Define the pragma operator based on compiler // 2. Define the pragma operator based on compiler
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#define JULIET_PRAGMA(x) _Pragma(#x) #define JULIET_PRAGMA(x) _Pragma(#x)
#define JULIET_SUPPRESS_MSVC(id) #define JULIET_SUPPRESS_MSVC(id)
@@ -27,7 +25,7 @@ namespace Juliet
#define JULIET_SUPPRESS_CLANG(str) #define JULIET_SUPPRESS_CLANG(str)
#endif #endif
// 3. The Agnostic "Push/Pop" // 3. The Agnostic "Push/Pop"
#if defined(__clang__) #if defined(__clang__)
#define JULIET_WARNING_PUSH JULIET_PRAGMA(clang diagnostic push) #define JULIET_WARNING_PUSH JULIET_PRAGMA(clang diagnostic push)
#define JULIET_WARNING_POP JULIET_PRAGMA(clang diagnostic pop) #define JULIET_WARNING_POP JULIET_PRAGMA(clang diagnostic pop)
@@ -40,10 +38,10 @@ namespace Juliet
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
// MSVC specific intrinsic // MSVC specific intrinsic
#define JULIET_PLATFORM_BREAK() (__nop(), __debugbreak()) #define JULIET_PLATFORM_BREAK() (__nop(), __debugbreak())
#elif defined(__clang__) || defined(__GNUC__) #elif defined(__clang__) || defined(__GNUC__)
// Clang/GCC specific intrinsic // Clang/GCC specific intrinsic
#define JULIET_PLATFORM_BREAK() __builtin_trap() #define JULIET_PLATFORM_BREAK() __builtin_trap()
#else #else
#include <signal.h> #include <signal.h>
@@ -52,40 +50,40 @@ namespace Juliet
#if JULIET_DEBUG #if JULIET_DEBUG
#define JULIET_ASSERT_INTERNAL(expression, message) \ #define JULIET_ASSERT_INTERNAL(expression, message) \
JULIET_WARNING_PUSH \ JULIET_WARNING_PUSH \
JULIET_SUPPRESS_CLANG("-Wextra-semi-stmt") \ JULIET_SUPPRESS_CLANG("-Wextra-semi-stmt") \
JULIET_SUPPRESS_MSVC(4127) \ JULIET_SUPPRESS_MSVC(4127) \
JULIET_SUPPRESS_MSVC(4548) \ JULIET_SUPPRESS_MSVC(4548) \
{ \ { \
if (!(expression)) [[unlikely]] \ if (!(expression)) [[unlikely]] \
{ \ { \
Juliet::JulietAssert(#expression, message); \ JulietAssert(#expression, message); \
} \ } \
} \ } \
JULIET_WARNING_POP \ JULIET_WARNING_POP \
static_assert(true, "") static_assert(true, "")
#define AssertHR(hr_expression, message) \ #define AssertHR(hr_expression, message) \
do \ do \
{ \ { \
long hr_val = (hr_expression); \ long hr_val = (hr_expression); \
if (hr_val < 0) \ if (hr_val < 0) \
{ \ { \
Juliet::JulietAssert(#hr_expression, message, std::source_location::current(), hr_val); \ JulietAssert(#hr_expression, message, std::source_location::current(), hr_val); \
} \ } \
} \ } \
while (0) while (0)
#define GET_ASSERT_MACRO(_1, _2, NAME, ...) NAME #define GET_ASSERT_MACRO(_1, _2, NAME, ...) NAME
#define Assert(...) GET_ASSERT_MACRO(__VA_ARGS__, JULIET_ASSERT_INTERNAL, JULIET_ASSERT_NO_MSG)(__VA_ARGS__) #define Assert(...) GET_ASSERT_MACRO(__VA_ARGS__, JULIET_ASSERT_INTERNAL, JULIET_ASSERT_NO_MSG)(__VA_ARGS__)
#define JULIET_ASSERT_NO_MSG(expression) JULIET_ASSERT_INTERNAL(expression, "No additional information provided.") #define JULIET_ASSERT_NO_MSG(expression) JULIET_ASSERT_INTERNAL(expression, "No additional information provided.")
#define Unimplemented() \ #define Unimplemented() \
do \ do \
{ \ { \
Juliet::JulietAssert("UNIMPLEMENTED", "This code path is not yet functional."); \ JulietAssert("UNIMPLEMENTED", "This code path is not yet functional."); \
} \ } \
while (0) while (0)
#else #else
#define Assert(...) ((void)0) #define Assert(...) ((void)0)
@@ -93,85 +91,85 @@ namespace Juliet
#define Unimplemented() ((void)0) #define Unimplemented() ((void)0)
#endif #endif
JULIET_API extern void JulietAssert(const char* expression, const char* message, JULIET_API extern void JulietAssert(const char* expression, const char* message,
std::source_location location = std::source_location::current(), long handleResult = 0); std::source_location location = std::source_location::current(), long handleResult = 0);
#define ZeroStruct(structInstance) ZeroSize(sizeof(structInstance), &(structInstance)) #define ZeroStruct(structInstance) ZeroSize(sizeof(structInstance), &(structInstance))
#define ZeroArray(array) ZeroSize(sizeof((array)), (array)) #define ZeroArray(array) ZeroSize(sizeof((array)), (array))
#define ZeroDynArray(Count, Pointer) ZeroSize((Count) * sizeof((Pointer)[0]), Pointer) #define ZeroDynArray(Count, Pointer) ZeroSize((Count) * sizeof((Pointer)[0]), Pointer)
inline void ZeroSize(size_t size, void* ptr) inline void ZeroSize(size_t size, void* ptr)
{
auto Byte = (uint8*)ptr;
while (size--)
{ {
auto Byte = (uint8*)ptr; *Byte++ = 0;
while (size--)
{
*Byte++ = 0;
}
} }
}
#define Restrict __restrict #define Restrict __restrict
template <class Function> template <class Function>
class DeferredFunction class DeferredFunction
{
public:
explicit DeferredFunction(const Function& otherFct) noexcept
: Callback(otherFct)
{ {
public: }
explicit DeferredFunction(const Function& otherFct) noexcept explicit DeferredFunction(Function&& otherFct) noexcept
: Callback(otherFct) : Callback(std::move(otherFct))
{
}
explicit DeferredFunction(Function&& otherFct) noexcept
: Callback(std::move(otherFct))
{
}
~DeferredFunction() noexcept { Callback(); }
DeferredFunction(const DeferredFunction&) = delete;
DeferredFunction(const DeferredFunction&&) = delete;
void operator=(const DeferredFunction&) = delete;
void operator=(DeferredFunction&&) = delete;
private:
Function Callback;
};
template <class Function>
auto Defer(Function&& fct) noexcept
{ {
return DeferredFunction<std::decay_t<Function>>{ std::forward<Function>(fct) };
} }
inline bool IsValid(ByteBuffer buffer) ~DeferredFunction() noexcept { Callback(); }
{
return buffer.Size > 0 && buffer.Data;
}
extern JULIET_API void Free(ByteBuffer& buffer); DeferredFunction(const DeferredFunction&) = delete;
DeferredFunction(const DeferredFunction&&) = delete;
void operator=(const DeferredFunction&) = delete;
void operator=(DeferredFunction&&) = delete;
template <std::integral T> private:
[[nodiscard]] constexpr T AlignPow2(T x, T alignment) Function Callback;
{ };
// Safety Check:
Assert(std::has_single_bit(static_cast<size_t>(alignment)));
return (x + alignment - 1) & ~(alignment - 1); template <class Function>
} auto Defer(Function&& fct) noexcept
{
return DeferredFunction<std::decay_t<Function>>{ std::forward<Function>(fct) };
}
template <typename T> inline bool IsValid(ByteBuffer buffer)
inline void Swap(T* Restrict a, T* Restrict b) {
{ return buffer.Size > 0 && buffer.Data;
T temp = std::move(*a); }
*a = std::move(*b);
*b = std::move(temp);
}
// Move to another file dedicated to those extern JULIET_API void Free(ByteBuffer& buffer);
template <std::integral T>
[[nodiscard]] constexpr T AlignPow2(T x, T alignment)
{
// Safety Check:
Assert(std::has_single_bit(static_cast<size_t>(alignment)));
return (x + alignment - 1) & ~(alignment - 1);
}
template <typename T>
inline void Swap(T* Restrict a, T* Restrict b)
{
T temp = std::move(*a);
*a = std::move(*b);
*b = std::move(temp);
}
// Move to another file dedicated to those
#if defined(__clang__) #if defined(__clang__)
#define COMPILER_CLANG 1 #define COMPILER_CLANG 1
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define COMPILER_MSVC 1 #define COMPILER_MSVC 1
#endif #endif
// Undef anything not defined // Undef anything not defined
#if !defined(COMPILER_CLANG) #if !defined(COMPILER_CLANG)
#define COMPILER_CLANG 0 #define COMPILER_CLANG 0
#endif #endif
@@ -189,43 +187,42 @@ namespace Juliet
#error AlignOf not defined for this compiler. #error AlignOf not defined for this compiler.
#endif #endif
template <typename T> template <typename T>
[[nodiscard]] constexpr const char* GetTypeName() [[nodiscard]] constexpr const char* GetTypeName()
{ {
#if COMPILER_CLANG #if COMPILER_CLANG
return __PRETTY_FUNCTION__; return __PRETTY_FUNCTION__;
#elif COMPILER_MSVC #elif COMPILER_MSVC
return __FUNCSIG__; return __FUNCSIG__;
#elif COMPILER_GCC #elif COMPILER_GCC
return __PRETTY_FUNCTION__; return __PRETTY_FUNCTION__;
#else #else
return "UnknownType"; return "UnknownType";
#endif #endif
} }
inline uint16 safe_cast_uint16(uint32 value) inline uint16 safe_cast_uint16(uint32 value)
{ {
Assert(value <= uint16Max); Assert(value <= uint16Max);
uint16 result = (uint16)value; uint16 result = (uint16)value;
return result; return result;
} }
const uint32 bitmask1 = 0b0000'0001; const uint32 bitmask1 = 0b0000'0001;
const uint32 bitmask2 = 0b0000'0011; const uint32 bitmask2 = 0b0000'0011;
const uint32 bitmask3 = 0b0000'0111; const uint32 bitmask3 = 0b0000'0111;
const uint32 bitmask4 = 0b0000'1111; const uint32 bitmask4 = 0b0000'1111;
const uint32 bitmask5 = 0b0001'1111; const uint32 bitmask5 = 0b0001'1111;
const uint32 bitmask6 = 0b0011'1111; const uint32 bitmask6 = 0b0011'1111;
const uint32 bitmask7 = 0b0111'1111; const uint32 bitmask7 = 0b0111'1111;
const uint32 bitmask8 = 0b1111'1111; const uint32 bitmask8 = 0b1111'1111;
const uint32 bitmask9 = 0x0000'01ff; const uint32 bitmask9 = 0x0000'01ff;
const uint32 bitmask10 = 0x0000'03ff; const uint32 bitmask10 = 0x0000'03ff;
const uint32 bitmask11 = 0x0000'07ff; const uint32 bitmask11 = 0x0000'07ff;
const uint32 bitmask12 = 0x0000'0fff; const uint32 bitmask12 = 0x0000'0fff;
const uint32 bitmask13 = 0x0000'1fff; const uint32 bitmask13 = 0x0000'1fff;
const uint32 bitmask14 = 0x0000'3fff; const uint32 bitmask14 = 0x0000'3fff;
const uint32 bitmask15 = 0x0000'7fff; const uint32 bitmask15 = 0x0000'7fff;
const uint32 bitmask16 = 0x0000'ffff; const uint32 bitmask16 = 0x0000'ffff;
// ... // ...
const uint32 bitmask32 = 0xffff'ffff; const uint32 bitmask32 = 0xffff'ffff;
} // namespace Juliet
+72 -75
View File
@@ -1,89 +1,86 @@
#pragma once #pragma once
namespace Juliet template <typename T>
concept IsEnum = std::is_enum_v<T>;
template <IsEnum E>
constexpr E operator~(E lhs) noexcept
{ {
template <typename T> return static_cast<E>(~static_cast<std::underlying_type_t<E>>(lhs));
concept IsEnum = std::is_enum_v<T>; }
template <IsEnum E> template <IsEnum E>
constexpr E operator~(E lhs) noexcept constexpr E operator|(E lhs, E rhs) noexcept
{ {
return static_cast<E>(~static_cast<std::underlying_type_t<E>>(lhs)); return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) | static_cast<std::underlying_type_t<E>>(rhs));
} }
template <IsEnum E> template <IsEnum E>
constexpr E operator|(E lhs, E rhs) noexcept constexpr E& operator|=(E& lhs, E rhs) noexcept
{ {
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) | static_cast<std::underlying_type_t<E>>(rhs)); return lhs = (lhs | rhs);
} }
template <IsEnum E> template <IsEnum E>
constexpr E& operator|=(E& lhs, E rhs) noexcept constexpr E operator&(E lhs, E rhs) noexcept
{ {
return lhs = (lhs | rhs); return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) & static_cast<std::underlying_type_t<E>>(rhs));
} }
template <IsEnum E> template <IsEnum E>
constexpr E operator&(E lhs, E rhs) noexcept constexpr E& operator&=(E& lhs, E rhs) noexcept
{ {
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) & static_cast<std::underlying_type_t<E>>(rhs)); return lhs = (lhs & rhs);
} }
template <IsEnum E> template <IsEnum E>
constexpr E& operator&=(E& lhs, E rhs) noexcept constexpr E operator^(E lhs, E rhs) noexcept
{ {
return lhs = (lhs & rhs); return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) ^ static_cast<std::underlying_type_t<E>>(rhs));
} }
template <IsEnum E> template <IsEnum E>
constexpr E operator^(E lhs, E rhs) noexcept constexpr E& operator^=(E& lhs, E rhs) noexcept
{ {
return static_cast<E>(static_cast<std::underlying_type_t<E>>(lhs) ^ static_cast<std::underlying_type_t<E>>(rhs)); return lhs = (lhs ^ rhs);
} }
template <IsEnum E> template <IsEnum E>
constexpr E& operator^=(E& lhs, E rhs) noexcept constexpr std::underlying_type_t<E> operator-(E lhs, E rhs) noexcept
{ {
return lhs = (lhs ^ rhs); using T = std::underlying_type_t<E>;
} return static_cast<T>(static_cast<T>(lhs) - static_cast<T>(rhs));
}
template <IsEnum E> template <IsEnum E>
constexpr std::underlying_type_t<E> operator-(E lhs, E rhs) noexcept constexpr std::underlying_type_t<E> operator+(E lhs, E rhs) noexcept
{ {
using T = std::underlying_type_t<E>; using T = std::underlying_type_t<E>;
return static_cast<T>(static_cast<T>(lhs) - static_cast<T>(rhs)); return static_cast<T>(static_cast<T>(lhs) + static_cast<T>(rhs));
} }
template <IsEnum E> template <IsEnum E>
constexpr std::underlying_type_t<E> operator+(E lhs, E rhs) noexcept constexpr E operator-(E lhs, std::underlying_type_t<E> rhs) noexcept
{ {
using T = std::underlying_type_t<E>; using T = std::underlying_type_t<E>;
return static_cast<T>(static_cast<T>(lhs) + static_cast<T>(rhs)); return static_cast<E>(static_cast<T>(static_cast<T>(lhs) - rhs));
} }
template <IsEnum E> template <IsEnum E>
constexpr E operator-(E lhs, std::underlying_type_t<E> rhs) noexcept constexpr E operator+(E lhs, std::underlying_type_t<E> rhs) noexcept
{ {
using T = std::underlying_type_t<E>; using T = std::underlying_type_t<E>;
return static_cast<E>(static_cast<T>(static_cast<T>(lhs) - rhs)); return static_cast<E>(static_cast<T>(static_cast<T>(lhs) + rhs));
} }
template <IsEnum E> template <IsEnum E>
constexpr E operator+(E lhs, std::underlying_type_t<E> rhs) noexcept constexpr std::underlying_type_t<E> ToUnderlying(E enm) noexcept
{ {
using T = std::underlying_type_t<E>; return static_cast<std::underlying_type_t<E>>(enm);
return static_cast<E>(static_cast<T>(static_cast<T>(lhs) + rhs)); }
}
template <IsEnum E> template <IsEnum E>
constexpr std::underlying_type_t<E> ToUnderlying(E enm) noexcept constexpr E ToEnum(std::underlying_type_t<E> value) noexcept
{ {
return static_cast<std::underlying_type_t<E>>(enm); return static_cast<E>(value);
} }
template <IsEnum E>
constexpr E ToEnum(std::underlying_type_t<E> value) noexcept
{
return static_cast<E>(value);
}
} // namespace Juliet
+90 -93
View File
@@ -1,113 +1,110 @@
#pragma once #pragma once
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
namespace Juliet template <typename Type, typename OtherType>
concept NonNullPtr_Convertible = std::is_convertible_v<OtherType*, Type*>;
template <typename Type, typename OtherType>
concept NonNullPtr_SameType = std::is_same_v<OtherType*, Type*>;
template <typename Type>
class NonNullPtr
{ {
template <typename Type, typename OtherType> public:
concept NonNullPtr_Convertible = std::is_convertible_v<OtherType*, Type*>; constexpr NonNullPtr(Type* ptr)
: InternalPtr(ptr)
template <typename Type, typename OtherType>
concept NonNullPtr_SameType = std::is_same_v<OtherType*, Type*>;
template <typename Type>
class NonNullPtr
{ {
public: Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
constexpr NonNullPtr(Type* ptr) }
: InternalPtr(ptr)
{
Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
}
template <typename OtherType> template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*> requires NonNullPtr_Convertible<OtherType*, Type*>
constexpr NonNullPtr(const NonNullPtr<OtherType>& otherPtr) constexpr NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
: InternalPtr(otherPtr.Get()) : InternalPtr(otherPtr.Get())
{ {
Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null."); Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null.");
} }
// Assignment // Assignment
[[nodiscard]] constexpr NonNullPtr& operator=(Type* ptr) [[nodiscard]] constexpr NonNullPtr& operator=(Type* ptr)
{ {
Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!"); Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!");
InternalPtr = ptr; InternalPtr = ptr;
return *this; return *this;
} }
template <typename OtherType> template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*> requires NonNullPtr_Convertible<OtherType*, Type*>
[[nodiscard]] constexpr NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr) [[nodiscard]] constexpr NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
{ {
InternalPtr = otherPtr.Get(); InternalPtr = otherPtr.Get();
return *this; return *this;
} }
// Accessors // Accessors
[[nodiscard]] constexpr operator Type*() const [[nodiscard]] constexpr operator Type*() const
{ {
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null"); Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr; return InternalPtr;
} }
[[nodiscard]] constexpr Type* Get() const [[nodiscard]] constexpr Type* Get() const
{ {
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null"); Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr; return InternalPtr;
} }
[[nodiscard]] constexpr Type& operator*() const [[nodiscard]] constexpr Type& operator*() const
{ {
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null"); Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return *InternalPtr; return *InternalPtr;
} }
[[nodiscard]] constexpr Type* operator->() const [[nodiscard]] constexpr Type* operator->() const
{ {
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null"); Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr; return InternalPtr;
} }
// Comparisons // Comparisons
[[nodiscard]] constexpr bool operator==(const NonNullPtr& otherPtr) const [[nodiscard]] constexpr bool operator==(const NonNullPtr& otherPtr) const
{ {
return InternalPtr == otherPtr.InternalPtr; return InternalPtr == otherPtr.InternalPtr;
} }
template <typename OtherType> template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType> requires NonNullPtr_SameType<Type, OtherType>
[[nodiscard]] constexpr bool operator==(OtherType* otherRawPtr) const [[nodiscard]] constexpr bool operator==(OtherType* otherRawPtr) const
{ {
return InternalPtr == otherRawPtr; return InternalPtr == otherRawPtr;
} }
template <typename OtherType> template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType> requires NonNullPtr_SameType<Type, OtherType>
[[nodiscard]] constexpr friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr) [[nodiscard]] constexpr friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
{ {
return otherRawPtr == nonNullPtr.InternalPtr; return otherRawPtr == nonNullPtr.InternalPtr;
} }
// Forbid assigning a nullptr at compile time // Forbid assigning a nullptr at compile time
constexpr NonNullPtr(std::nullptr_t) constexpr NonNullPtr(std::nullptr_t)
: InternalPtr(nullptr) : InternalPtr(nullptr)
{ {
static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value"); static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value");
} }
[[nodiscard]] constexpr 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"); static_assert(sizeof(Type) == 0, "Trying to assign a NonNullPtr with a nullptr value");
return *this; return *this;
} }
[[nodiscard]] constexpr explicit operator bool() const { return InternalPtr != nullptr; } [[nodiscard]] constexpr explicit operator bool() const { return InternalPtr != nullptr; }
private: private:
Type* InternalPtr; Type* InternalPtr;
}; };
template <typename T> template <typename T>
NonNullPtr(T*) -> NonNullPtr<T>; NonNullPtr(T*) -> NonNullPtr<T>;
} // namespace Juliet
+137 -140
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Math/MathUtils.h> #include <Core/Math/MathUtils.h>
@@ -14,170 +14,167 @@
#undef RESTORE_GLOBAL #undef RESTORE_GLOBAL
#endif #endif
namespace Juliet struct Arena;
{
struct Arena;
#define ConstString(str) { const_cast<char*>((str)), sizeof(str) - 1 } #define ConstString(str) { const_cast<char*>((str)), sizeof(str) - 1 }
#define CStr(str) ((str).Str) #define CStr(str) ((str).Str)
#define InplaceString(name, size) \ #define InplaceString(name, size) \
char name##_[size]; \ char name##_[size]; \
MemSet(name##_, 0, sizeof(uint32)); \ MemSet(name##_, 0, sizeof(uint32)); \
String name = { name##_, 0 } String name = { name##_, 0 }
// Everything is Little Endian // Everything is Little Endian
enum class StringEncoding : uint8 enum class StringEncoding : uint8
{
Unknown = 0,
ASCII,
LATIN1,
UTF8,
UTF16,
UTF32,
UCS2,
UCS4,
};
// Represents a UTF-8 String.
// Not null terminated.
struct String8
{
char* Str;
size_t Size;
};
using String = String8;
struct String16
{
uint16* Str;
size_t Size;
};
struct StringBuffer : String
{
size_t Capacity;
};
struct UnicodeDecode
{
uint32 Increment;
uint32 Codepoint;
};
constexpr uint32 kInvalidUTF8 = 0xFFFD;
inline size_t StringLength(String str)
{
return str.Size;
}
inline size_t StringLength(const char* str)
{
size_t length = 0;
if (str)
{ {
Unknown = 0, while (*str)
ASCII,
LATIN1,
UTF8,
UTF16,
UTF32,
UCS2,
UCS4,
};
// Represents a UTF-8 String.
// Not null terminated.
struct String8
{
char* Str;
size_t Size;
};
using String = String8;
struct String16
{
uint16* Str;
size_t Size;
};
struct StringBuffer : String
{
size_t Capacity;
};
struct UnicodeDecode
{
uint32 Increment;
uint32 Codepoint;
};
constexpr uint32 kInvalidUTF8 = 0xFFFD;
inline size_t StringLength(String str)
{
return str.Size;
}
inline size_t StringLength(const char* str)
{
size_t length = 0;
if (str)
{ {
while (*str) ++length;
{ ++str;
++length;
++str;
}
} }
return length;
} }
inline bool IsValid(String str) return length;
{ }
return str.Size > 0 && str.Str != nullptr && *str.Str;
}
inline String WrapString(const char* str) inline bool IsValid(String str)
{ {
String result = {}; return str.Size > 0 && str.Str != nullptr && *str.Str;
result.Str = const_cast<char*>(str); }
result.Size = str ? strlen(str) : 0;
return result;
}
inline String FindChar(String str, char c) inline String WrapString(const char* str)
{
String result = {};
result.Str = const_cast<char*>(str);
result.Size = str ? strlen(str) : 0;
return result;
}
inline String FindChar(String str, char c)
{
String result = str;
while (result.Size)
{ {
String result = str; if (*result.Str != c)
while (result.Size)
{ {
if (*result.Str != c) ++result.Str;
{ --result.Size;
++result.Str;
--result.Size;
}
else
{
return result;
}
} }
return {}; else
}
inline bool ContainsChar(String str, char c)
{
return IsValid(FindChar(str, c));
}
// Return:
// - < 0 if str1 < str2
// - = 0 : Both strings are equals
// - > 0 if str1 > str2
inline int32 StringCompare(String str1, String str2)
{
size_t len1 = StringLength(str1);
size_t len2 = StringLength(str2);
size_t minLen = Min(len1, len2);
int32 result = MemCompare(CStr(str1), CStr(str2), minLen);
if (result == 0)
{ {
if (len1 > len2) return result;
{
return 1;
}
if (len1 < len2)
{
return -1;
}
return 0;
} }
return result;
} }
return {};
}
JULIET_API uint32 StepUTF8(String& inStr); inline bool ContainsChar(String str, char c)
JULIET_API String FindString(String strLeft, String strRight); {
return IsValid(FindChar(str, c));
}
// Case insensitive compare. Supports ASCII only // Return:
// TODO: Support UNICODE // - < 0 if str1 < str2
extern JULIET_API int8 StringCompareCaseInsensitive(String str1, String str2); // - = 0 : Both strings are equals
// - > 0 if str1 > str2
// Do not allocate anything, you must allocate your out buffer yourself inline int32 StringCompare(String str1, String str2)
// TODO: Version taking arena that can allocate {
// Do not take String type because we dont know the string encoding we are going from/to size_t len1 = StringLength(str1);
// src and dst will be casted based on the encoding. size_t len2 = StringLength(str2);
// size will correspond to the number of characters size_t minLen = Min(len1, len2);
// Will convert \0 character if present. int32 result = MemCompare(CStr(str1), CStr(str2), minLen);
extern JULIET_API bool ConvertString(StringEncoding from, StringEncoding to, String src, StringBuffer& dst, bool nullTerminate); if (result == 0)
extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst, bool nullTerminate);
JULIET_API String StringCopy(NonNullPtr<Arena> arena, String str);
JULIET_API String16 str16_from_8(NonNullPtr<Arena> arena, String8 str);
template <typename... Args>
String Format(NonNullPtr<Arena> arena, const char* formatStr, Args&&... args)
{ {
std::string result = std::vformat(formatStr, std::make_format_args(args...)); if (len1 > len2)
return StringCopy(arena, WrapString(result.c_str())); {
return 1;
}
if (len1 < len2)
{
return -1;
}
return 0;
} }
return result;
}
JULIET_API uint32 StepUTF8(String& inStr);
JULIET_API String FindString(String strLeft, String strRight);
// Case insensitive compare. Supports ASCII only
// TODO: Support UNICODE
extern JULIET_API int8 StringCompareCaseInsensitive(String str1, String str2);
// Do not allocate anything, you must allocate your out buffer yourself
// TODO: Version taking arena that can allocate
// Do not take String type because we dont know the string encoding we are going from/to
// src and dst will be casted based on the encoding.
// size will correspond to the number of characters
// Will convert \0 character if present.
extern JULIET_API bool ConvertString(StringEncoding from, StringEncoding to, String src, StringBuffer& dst, bool nullTerminate);
extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst, bool nullTerminate);
JULIET_API String StringCopy(NonNullPtr<Arena> arena, String str);
JULIET_API String16 str16_from_8(NonNullPtr<Arena> arena, String8 str);
template <typename... Args>
String Format(NonNullPtr<Arena> arena, const char* formatStr, Args&&... args)
{
std::string result = std::vformat(formatStr, std::make_format_args(args...));
return StringCopy(arena, WrapString(result.c_str()));
}
#define juliet_snprintf snprintf #define juliet_snprintf snprintf
} // namespace Juliet
#ifdef UNIT_TEST #ifdef UNIT_TEST
namespace Juliet::UnitTest namespace UnitTest
{ {
inline void TestFindChar() inline void TestFindChar()
{ {
@@ -192,5 +189,5 @@ namespace Juliet::UnitTest
Assert(FindChar(s2, 'f').Str - s2.Str == 5); Assert(FindChar(s2, 'f').Str - s2.Str == 5);
Assert(FindChar(s3, '1').Str - s3.Str == 0); Assert(FindChar(s3, '1').Str - s3.Str == 0);
} }
} // namespace Juliet::UnitTest } // namespace UnitTest
#endif #endif
+182 -185
View File
@@ -1,214 +1,211 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
namespace Juliet template <typename Type, size_t ReserveSize = 16>
struct VectorArena
{ {
template <typename Type, size_t ReserveSize = 16> void Create(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(const char* name = nullptr))
struct VectorArena
{ {
void Create(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(const char* name = nullptr)) Assert(!Arena);
JULIET_DEBUG_ONLY(Name = name ? name : Name;)
DataFirst = DataLast = Data = nullptr;
Count = 0;
Capacity = 0;
Arena = arena;
Reserve(ReserveSize);
}
void Destroy()
{
DataFirst = DataLast = Data = nullptr;
Count = 0;
Capacity = 0;
Arena = nullptr;
}
void Reserve(size_t newCapacity)
{
Assert(Arena);
Assert(newCapacity <= ReserveSize && "VectorArena capacity should be <= ReserveSize.");
if (Data == nullptr)
{ {
Assert(!Arena); Data = ArenaPushArray<Type>(Arena, newCapacity JULIET_DEBUG_PARAM(Name));
Capacity = newCapacity;
}
else
{
Unimplemented();
}
}
JULIET_DEBUG_ONLY(Name = name ? name : Name;) void Resize(size_t newCount)
{
Assert(Arena);
if (newCount == Count)
{
return;
}
DataFirst = DataLast = Data = nullptr; if (Data == nullptr)
Count = 0; {
Capacity = 0; size_t initialCapacity = newCount > ReserveSize ? newCount : ReserveSize;
Arena = arena; Reserve(initialCapacity);
}
Assert(newCount <= Capacity && "VectorArena capacity exceeded!");
Count = newCount;
if (Count > 0)
{
DataFirst = Data;
DataLast = Data + Count - 1;
}
else
{
DataFirst = DataLast = nullptr;
}
}
void PushBack(const Type* buffer, size_t amount)
{
Assert(Arena);
Assert(buffer || amount == 0);
if (amount == 0)
{
return;
}
if (Data == nullptr)
{
size_t initialCapacity = amount > ReserveSize ? amount : ReserveSize;
Reserve(initialCapacity);
}
Assert(Count + amount <= Capacity && "VectorArena capacity exceeded!");
Type* dst = Data + Count;
MemCopy(dst, buffer, amount * sizeof(Type));
if (Count == 0)
{
DataFirst = dst;
}
DataLast = dst + amount - 1;
Count += amount;
}
void PushBack(const Type& value)
{
Assert(Arena);
if (Data == nullptr)
{
Reserve(ReserveSize); Reserve(ReserveSize);
} }
void Destroy() Assert(Count + 1 <= Capacity && "VectorArena capacity exceeded!");
Type* entry = Data + Count;
*entry = value;
if (Count == 0)
{ {
DataFirst = DataLast = Data = nullptr; DataFirst = entry;
Count = 0; }
Capacity = 0; DataLast = entry;
Arena = nullptr; ++Count;
}
void PushBack(Type&& value)
{
Assert(Arena);
if (Data == nullptr)
{
Reserve(ReserveSize);
} }
void Reserve(size_t newCapacity) Assert(Count + 1 <= Capacity && "VectorArena capacity exceeded!");
{
Assert(Arena);
Assert(newCapacity <= ReserveSize && "VectorArena capacity should be <= ReserveSize.");
if (Data == nullptr) Type* entry = Data + Count;
{ *entry = std::move(value);
Data = ArenaPushArray<Type>(Arena, newCapacity JULIET_DEBUG_PARAM(Name));
Capacity = newCapacity; if (Count == 0)
} {
else DataFirst = entry;
{ }
Unimplemented(); DataLast = entry;
} ++Count;
}
void RemoveAtFast(index_t index)
{
Assert(Arena);
Assert(index < Count);
Assert(Count > 0);
Type* elementAdr = DataFirst + index;
// Swap DataLast and element
if (DataLast != elementAdr)
{
Swap(DataLast, elementAdr);
} }
void Resize(size_t newCount) --DataLast;
--Count;
if (Count == 0)
{ {
Assert(Arena);
if (newCount == Count)
{
return;
}
if (Data == nullptr)
{
size_t initialCapacity = newCount > ReserveSize ? newCount : ReserveSize;
Reserve(initialCapacity);
}
Assert(newCount <= Capacity && "VectorArena capacity exceeded!");
Count = newCount;
if (Count > 0)
{
DataFirst = Data;
DataLast = Data + Count - 1;
}
else
{
DataFirst = DataLast = nullptr;
}
}
void PushBack(const Type* buffer, size_t amount)
{
Assert(Arena);
Assert(buffer || amount == 0);
if (amount == 0)
{
return;
}
if (Data == nullptr)
{
size_t initialCapacity = amount > ReserveSize ? amount : ReserveSize;
Reserve(initialCapacity);
}
Assert(Count + amount <= Capacity && "VectorArena capacity exceeded!");
Type* dst = Data + Count;
MemCopy(dst, buffer, amount * sizeof(Type));
if (Count == 0)
{
DataFirst = dst;
}
DataLast = dst + amount - 1;
Count += amount;
}
void PushBack(const Type& value)
{
Assert(Arena);
if (Data == nullptr)
{
Reserve(ReserveSize);
}
Assert(Count + 1 <= Capacity && "VectorArena capacity exceeded!");
Type* entry = Data + Count;
*entry = value;
if (Count == 0)
{
DataFirst = entry;
}
DataLast = entry;
++Count;
}
void PushBack(Type&& value)
{
Assert(Arena);
if (Data == nullptr)
{
Reserve(ReserveSize);
}
Assert(Count + 1 <= Capacity && "VectorArena capacity exceeded!");
Type* entry = Data + Count;
*entry = std::move(value);
if (Count == 0)
{
DataFirst = entry;
}
DataLast = entry;
++Count;
}
void RemoveAtFast(index_t index)
{
Assert(Arena);
Assert(index < Count);
Assert(Count > 0);
Type* elementAdr = DataFirst + index;
// Swap DataLast and element
if (DataLast != elementAdr)
{
Swap(DataLast, elementAdr);
}
--DataLast;
--Count;
if (Count == 0)
{
DataFirst = DataLast = nullptr;
}
}
void Clear()
{
Assert(Arena);
DataFirst = DataLast = nullptr; DataFirst = DataLast = nullptr;
Count = 0;
} }
}
[[nodiscard]] bool IsEmpty() const { return Count == 0; } void Clear()
{
Assert(Arena);
// C++ Accessors for loop supports and Index based access DataFirst = DataLast = nullptr;
[[nodiscard]] Type& operator[](size_t index) { return DataFirst[index]; } Count = 0;
[[nodiscard]] const Type& operator[](size_t index) const { return DataFirst[index]; } }
[[nodiscard]] Type* begin() { return DataFirst; } [[nodiscard]] bool IsEmpty() const { return Count == 0; }
[[nodiscard]] Type* end() { return DataFirst + Count; }
[[nodiscard]] const Type* begin() const { return DataFirst; } // C++ Accessors for loop supports and Index based access
[[nodiscard]] const Type* end() const { return DataFirst + Count; } [[nodiscard]] Type& operator[](size_t index) { return DataFirst[index]; }
[[nodiscard]] const Type& operator[](size_t index) const { return DataFirst[index]; }
[[nodiscard]] Type* First() { return DataFirst; } [[nodiscard]] Type* begin() { return DataFirst; }
[[nodiscard]] Type* Front() { return DataFirst; } [[nodiscard]] Type* end() { return DataFirst + Count; }
[[nodiscard]] Type* Last() { return DataLast; }
[[nodiscard]] Type* Back() { return DataLast; }
[[nodiscard]] Type* DataPtr() { return Data; }
[[nodiscard]] const Type* DataPtr() const { return Data; }
[[nodiscard]] size_t Size() const { return Count; } [[nodiscard]] const Type* begin() const { return DataFirst; }
[[nodiscard]] const Type* end() const { return DataFirst + Count; }
Arena* Arena = nullptr; [[nodiscard]] Type* First() { return DataFirst; }
Type* DataFirst = nullptr; [[nodiscard]] Type* Front() { return DataFirst; }
Type* DataLast = nullptr; [[nodiscard]] Type* Last() { return DataLast; }
Type* Data = nullptr; [[nodiscard]] Type* Back() { return DataLast; }
size_t Count = 0; [[nodiscard]] Type* DataPtr() { return Data; }
size_t Capacity = 0; [[nodiscard]] const Type* DataPtr() const { return Data; }
JULIET_DEBUG_ONLY(const char* Name = "VectorArena";)
}; [[nodiscard]] size_t Size() const { return Count; }
static_assert(std::is_standard_layout_v<VectorArena<int>>,
"VectorArena must have a standard layout to remain POD-like."); Arena* Arena = nullptr;
static_assert(std::is_trivially_copyable_v<VectorArena<int>>, Type* DataFirst = nullptr;
"VectorArena must be trivially copyable (no custom destructors/assignment)."); Type* DataLast = nullptr;
} // namespace Juliet Type* Data = nullptr;
size_t Count = 0;
size_t Capacity = 0;
JULIET_DEBUG_ONLY(const char* Name = "VectorArena";)
};
static_assert(std::is_standard_layout_v<VectorArena<int>>,
"VectorArena must have a standard layout to remain POD-like.");
static_assert(std::is_trivially_copyable_v<VectorArena<int>>,
"VectorArena must be trivially copyable (no custom destructors/assignment).");
+9 -12
View File
@@ -1,21 +1,18 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet struct Window;
{
struct Window;
using WindowID = uint8; using WindowID = uint8;
extern JULIET_API Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int flags = 0 /* unused */); extern JULIET_API Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int flags = 0 /* unused */);
extern JULIET_API void DestroyPlatformWindow(NonNullPtr<Window> window); extern JULIET_API void DestroyPlatformWindow(NonNullPtr<Window> window);
extern JULIET_API void ShowWindow(NonNullPtr<Window> window); extern JULIET_API void ShowWindow(NonNullPtr<Window> window);
extern JULIET_API void HideWindow(NonNullPtr<Window> window); extern JULIET_API void HideWindow(NonNullPtr<Window> window);
extern JULIET_API WindowID GetWindowID(NonNullPtr<Window> window); extern JULIET_API WindowID GetWindowID(NonNullPtr<Window> window);
extern JULIET_API void SetWindowTitle(NonNullPtr<Window> window, String title); extern JULIET_API void SetWindowTitle(NonNullPtr<Window> window, String title);
} // namespace Juliet
@@ -1,12 +1,9 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
namespace Juliet struct DynamicLibrary;
{
struct DynamicLibrary;
extern JULIET_API DynamicLibrary* LoadDynamicLibrary(const char* filename); extern JULIET_API DynamicLibrary* LoadDynamicLibrary(const char* filename);
extern JULIET_API FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName); extern JULIET_API FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName);
extern JULIET_API void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib); extern JULIET_API void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib);
} // namespace Juliet
+93 -96
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/HAL/Display/Display.h> #include <Core/HAL/Display/Display.h>
#include <Core/HAL/Keyboard/Keyboard.h> #include <Core/HAL/Keyboard/Keyboard.h>
@@ -9,115 +9,112 @@
// Handles all events from systems handling the Hardware // Handles all events from systems handling the Hardware
// Very inspired by SDL3 // Very inspired by SDL3
namespace Juliet enum class EventType : uint32
{ {
enum class EventType : uint32 None = 0,
{ First = None,
None = 0,
First = None,
// Application Events // Application Events
// User querying an exit // User querying an exit
Application_Exit = 100, Application_Exit = 100,
// OS terminating the application // OS terminating the application
Application_OS_Terminate, Application_OS_Terminate,
Application_Begin = Application_Exit, Application_Begin = Application_Exit,
Application_End = Application_OS_Terminate, Application_End = Application_OS_Terminate,
// Window Events // Window Events
Window_Close_Request = 200, Window_Close_Request = 200,
Window_Begin = Window_Close_Request, Window_Begin = Window_Close_Request,
Window_End = Window_Close_Request, Window_End = Window_Close_Request,
// Keyboard Event // Keyboard Event
Key_Down = 300, Key_Down = 300,
Key_Up, Key_Up,
Keyboard_Begin = Key_Down, Keyboard_Begin = Key_Down,
Keyboard_End = Key_Up, Keyboard_End = Key_Up,
// Mouse Event // Mouse Event
Mouse_Move = 400, Mouse_Move = 400,
Mouse_ButtonPressed, Mouse_ButtonPressed,
Mouse_ButtonReleased, Mouse_ButtonReleased,
Mouse_Begin = Mouse_Move, Mouse_Begin = Mouse_Move,
Mouse_End = Mouse_ButtonReleased, Mouse_End = Mouse_ButtonReleased,
Last // Get value from the previous one Last // Get value from the previous one
}; };
struct WindowEvent struct WindowEvent
{ {
WindowID AssociatedWindowID; WindowID AssociatedWindowID;
uint32 DataPadding[2]; // TODO : define how much data param we need uint32 DataPadding[2]; // TODO : define how much data param we need
}; };
struct KeyboardEvent struct KeyboardEvent
{ {
KeyboardID AssociatedKeyboardID; KeyboardID AssociatedKeyboardID;
WindowID WindowID; WindowID WindowID;
Key Key; Key Key;
KeyState KeyState; KeyState KeyState;
KeyMod KeyModeState; KeyMod KeyModeState;
}; };
// ===================================================== // =====================================================
// Mouse Events // Mouse Events
// ===================================================== // =====================================================
struct MouseMovementEvent struct MouseMovementEvent
{ {
MouseID AssociatedMouseID; MouseID AssociatedMouseID;
WindowID WindowID; WindowID WindowID;
float X; float X;
float Y; float Y;
float X_Displacement; float X_Displacement;
float Y_Displacement; float Y_Displacement;
MouseButton ButtonState; MouseButton ButtonState;
}; };
struct MouseButtonEvent struct MouseButtonEvent
{ {
MouseID AssociatedMouseID; MouseID AssociatedMouseID;
WindowID WindowID; WindowID WindowID;
float X; float X;
float Y; float Y;
MouseButton ButtonState; MouseButton ButtonState;
bool IsPressed : 1; bool IsPressed : 1;
}; };
// Tagged union representing ALL possible system events + a bit of data for custom event if needed // Tagged union representing ALL possible system events + a bit of data for custom event if needed
union AllSystemEventUnion union AllSystemEventUnion
{ {
WindowEvent Window; WindowEvent Window;
KeyboardEvent Keyboard; KeyboardEvent Keyboard;
MouseMovementEvent MouseMovement; MouseMovementEvent MouseMovement;
MouseButtonEvent MouseButton; MouseButtonEvent MouseButton;
uint8 Padding[128]; // Make sure that the union is fixed in size and big enough on all platforms. uint8 Padding[128]; // Make sure that the union is fixed in size and big enough on all platforms.
}; };
// Make sure we do not bust the union size // Make sure we do not bust the union size
static_assert(sizeof(AllSystemEventUnion) == sizeof(((AllSystemEventUnion*)nullptr)->Padding)); static_assert(sizeof(AllSystemEventUnion) == sizeof(((AllSystemEventUnion*)nullptr)->Padding));
struct SystemEvent struct SystemEvent
{ {
EventType Type; EventType Type;
uint64 Timestamp; uint64 Timestamp;
AllSystemEventUnion Data; AllSystemEventUnion Data;
}; };
// Poll for any event, return false if no event is available. // Poll for any event, return false if no event is available.
// Equivalent to WaitEvent(event, 0); // Equivalent to WaitEvent(event, 0);
// Will not block // Will not block
extern JULIET_API bool GetEvent(SystemEvent& event); extern JULIET_API bool GetEvent(SystemEvent& event);
// TODO : use chrono to tag the timeout correctly with nanosec // TODO : use chrono to tag the timeout correctly with nanosec
// timeout == -1 means wait for any event before pursuing // timeout == -1 means wait for any event before pursuing
// timeout == 0 means checking once for the frame and getting out // timeout == 0 means checking once for the frame and getting out
// timeout > 0 means wait until time is out // timeout > 0 means wait until time is out
extern JULIET_API bool WaitEvent(SystemEvent& event, int32 timeoutInNS = -1); extern JULIET_API bool WaitEvent(SystemEvent& event, int32 timeoutInNS = -1);
// Add an event onto the event queue. // Add an event onto the event queue.
// TODO : support array of events // TODO : support array of events
extern JULIET_API bool AddEvent(SystemEvent& event); extern JULIET_API bool AddEvent(SystemEvent& event);
extern void Events_NewFrame(float deltaTime); extern void Events_NewFrame(float deltaTime);
} // namespace Juliet
+11 -14
View File
@@ -1,20 +1,17 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
namespace Juliet // Returns the path to the application directory
{ [[nodiscard]] extern JULIET_API String GetBasePath();
// Returns the path to the application directory
[[nodiscard]] extern JULIET_API String GetBasePath();
// Returns the resolved base path to the compiled shaders directory. // Returns the resolved base path to the compiled shaders directory.
// In dev, this resolves to ../../Assets/compiled/ relative to the exe. // In dev, this resolves to ../../Assets/compiled/ relative to the exe.
// In shipping, this resolves to Assets/Shaders/ next to the exe. // In shipping, this resolves to Assets/Shaders/ next to the exe.
[[nodiscard]] extern JULIET_API String GetAssetBasePath(); [[nodiscard]] extern JULIET_API String GetAssetBasePath();
// Builds a full path to an asset file given its filename (e.g. "Triangle.vert.dxil"). // Builds a full path to an asset file given its filename (e.g. "Triangle.vert.dxil").
// The caller owns the returned buffer and must free it. // The caller owns the returned buffer and must free it.
[[nodiscard]] extern JULIET_API String GetAssetPath(NonNullPtr<Arena> arena, String filename); [[nodiscard]] extern JULIET_API String GetAssetPath(NonNullPtr<Arena> arena, String filename);
[[nodiscard]] extern JULIET_API bool IsAbsolutePath(String path); [[nodiscard]] extern JULIET_API bool IsAbsolutePath(String path);
} // namespace Juliet
+47 -50
View File
@@ -1,69 +1,66 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet // Opaque type
struct IOStream;
struct IOStreamDataPayload
{ {
// Opaque type };
struct IOStream;
struct IOStreamDataPayload enum class IOStreamStatus : uint8
{ {
}; Ready,
Error,
EndOfFile,
NotReady,
ReadOnly,
WriteOnly
};
enum class IOStreamStatus : uint8 enum class IOStreamSeekPivot : uint8
{ {
Ready, Begin,
Error, Current,
EndOfFile, End,
NotReady, Count
ReadOnly, };
WriteOnly
};
enum class IOStreamSeekPivot : uint8 // IOStream can be opened on a file or memory, or anything else.
{ // Use the interface to make it transparent to the user.
Begin, struct IOStreamInterface
Current, {
End, uint32 Version;
Count
};
// IOStream can be opened on a file or memory, or anything else. int64 (*Size)(NonNullPtr<IOStreamDataPayload> data);
// Use the interface to make it transparent to the user.
struct IOStreamInterface
{
uint32 Version;
int64 (*Size)(NonNullPtr<IOStreamDataPayload> data); int64 (*Seek)(NonNullPtr<IOStreamDataPayload> data, int64 offset, IOStreamSeekPivot pivot);
size_t (*Read)(NonNullPtr<IOStreamDataPayload> data, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status);
size_t (*Write)(NonNullPtr<IOStreamDataPayload> data, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status);
bool (*Flush)(NonNullPtr<IOStreamDataPayload> data, NonNullPtr<IOStreamStatus> status);
int64 (*Seek)(NonNullPtr<IOStreamDataPayload> data, int64 offset, IOStreamSeekPivot pivot); bool (*Close)(NonNullPtr<IOStreamDataPayload> data);
size_t (*Read)(NonNullPtr<IOStreamDataPayload> data, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status); };
size_t (*Write)(NonNullPtr<IOStreamDataPayload> data, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status);
bool (*Flush)(NonNullPtr<IOStreamDataPayload> data, NonNullPtr<IOStreamStatus> status);
bool (*Close)(NonNullPtr<IOStreamDataPayload> data); extern JULIET_API IOStream* IOFromFile(NonNullPtr<Arena> arena, 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<Arena> arena, NonNullPtr<const IOStreamInterface> streamInterface,
NonNullPtr<IOStreamDataPayload> payload);
// Let you use an interface to open any io. Is used internally by IOFromFile // Write formatted string into the stream.
extern JULIET_API IOStream* IOFromInterface(NonNullPtr<Arena> arena, NonNullPtr<const IOStreamInterface> streamInterface, extern JULIET_API size_t IOPrintf(NonNullPtr<IOStream> stream, _Printf_format_string_ const char* format, ...);
NonNullPtr<IOStreamDataPayload> payload); extern JULIET_API size_t IOWrite(NonNullPtr<IOStream> stream, ByteBuffer inBuffer);
// Write formatted string into the stream. extern JULIET_API size_t IORead(NonNullPtr<IOStream> stream, void* ptr, size_t size);
extern JULIET_API size_t IOPrintf(NonNullPtr<IOStream> stream, _Printf_format_string_ const char* format, ...); extern JULIET_API int64 IOSeek(NonNullPtr<IOStream> stream, int64 offset, IOStreamSeekPivot pivot);
extern JULIET_API size_t IOWrite(NonNullPtr<IOStream> stream, ByteBuffer inBuffer);
extern JULIET_API size_t IORead(NonNullPtr<IOStream> stream, void* ptr, size_t size); extern JULIET_API int64 IOSize(NonNullPtr<IOStream> stream);
extern JULIET_API int64 IOSeek(NonNullPtr<IOStream> stream, int64 offset, IOStreamSeekPivot pivot);
extern JULIET_API int64 IOSize(NonNullPtr<IOStream> stream); 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 ByteBuffer LoadFile(NonNullPtr<Arena> arena, String filename); extern JULIET_API bool IOClose(NonNullPtr<IOStream> stream);
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<Arena> arena, NonNullPtr<IOStream> stream, bool closeStreamWhenDone);
extern JULIET_API bool IOClose(NonNullPtr<IOStream> stream);
} // namespace Juliet
+184 -187
View File
@@ -1,193 +1,190 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
namespace Juliet // Represents a Virtual Key corresponding to the Physical key, but localized using the keyboard layout
// ScanCode reprensent US ASCII Keyboard
// WASD Scan codes are ZQSD in KeyCode for French keyboard
// We use the ASCII value of the generated character as value, when possible.
// Keys that do not produce a character are converted to an abritrary value high enough to not conflict
// Reference: https://www.asciitable.com/
// Reference: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa299374(v=vs.60)
enum class KeyCode : uint32
{ {
// Represents a Virtual Key corresponding to the Physical key, but localized using the keyboard layout Unknown = 0x0, // 0
// ScanCode reprensent US ASCII Keyboard Unsupported = 0x0, // 0
// WASD Scan codes are ZQSD in KeyCode for French keyboard Return = 0X0Du, // '\r'
// We use the ASCII value of the generated character as value, when possible. Escape = 0X1Bu, // '\X1B'
// Keys that do not produce a character are converted to an abritrary value high enough to not conflict Backspace = 0X08u, // '\b'
// Reference: https://www.asciitable.com/ Tab = 0X09u, // '\t'
// Reference: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa299374(v=vs.60) Space = 0X20u, // ' '
enum class KeyCode : uint32 ExclamationPoint = 0X21u, // '!'
{ DoubleApostrophe = 0X22u, // '"'
Unknown = 0x0, // 0 Hash = 0X23u, // '#'
Unsupported = 0x0, // 0 Dollar = 0X24u, // '$'
Return = 0X0Du, // '\r' Percent = 0X25u, // '%'
Escape = 0X1Bu, // '\X1B' Ampersand = 0X26u, // '&'
Backspace = 0X08u, // '\b' Apostrophe = 0X27u, // '\''
Tab = 0X09u, // '\t' LeftParenthesis = 0X28u, // '('
Space = 0X20u, // ' ' RightParenthesis = 0X29u, // ')'
ExclamationPoint = 0X21u, // '!' Asterisk = 0X2Au, // '*'
DoubleApostrophe = 0X22u, // '"' Plus = 0X2Bu, // '+'
Hash = 0X23u, // '#' Comma = 0X2Cu, // ','
Dollar = 0X24u, // '$' Minus = 0X2Du, // '-'
Percent = 0X25u, // '%' Period = 0X2Eu, // '.'
Ampersand = 0X26u, // '&' Slash = 0X2Fu, // '/'
Apostrophe = 0X27u, // '\'' Num0 = 0X30u, // '0'
LeftParenthesis = 0X28u, // '(' Num1 = 0X31u, // '1'
RightParenthesis = 0X29u, // ')' Num2 = 0X32u, // '2'
Asterisk = 0X2Au, // '*' Num3 = 0X33u, // '3'
Plus = 0X2Bu, // '+' Num4 = 0X34u, // '4'
Comma = 0X2Cu, // ',' Num5 = 0X35u, // '5'
Minus = 0X2Du, // '-' Num6 = 0X36u, // '6'
Period = 0X2Eu, // '.' Num7 = 0X37u, // '7'
Slash = 0X2Fu, // '/' Num8 = 0X38u, // '8'
Num0 = 0X30u, // '0' Num9 = 0X39u, // '9'
Num1 = 0X31u, // '1' Colon = 0X3Au, // ':'
Num2 = 0X32u, // '2' Semicolon = 0X3Bu, // ';'
Num3 = 0X33u, // '3' LessThan = 0X3Cu, // '<'
Num4 = 0X34u, // '4' Equals = 0X3Du, // '='
Num5 = 0X35u, // '5' GreaterThan = 0X3Eu, // '>'
Num6 = 0X36u, // '6' QuestionMark = 0X3Fu, // '?'
Num7 = 0X37u, // '7' CommercialAt = 0x40u, // '@'
Num8 = 0X38u, // '8' LeftBracket = 0X5Bu, // '['
Num9 = 0X39u, // '9' Backslash = 0X5Cu, // '\\'
Colon = 0X3Au, // ':' RightBracket = 0X5DU, // ']'
Semicolon = 0X3Bu, // ';' Caret = 0X5Eu, // '^'
LessThan = 0X3Cu, // '<' Underscore = 0X5Fu, // '_'
Equals = 0X3Du, // '=' GraveAccent = 0X60u, // '`'
GreaterThan = 0X3Eu, // '>' A = 0x61u, // 'a'
QuestionMark = 0X3Fu, // '?' B = 0x62u, // 'b'
CommercialAt = 0x40u, // '@' C = 0x63u, // 'c'
LeftBracket = 0X5Bu, // '[' D = 0x64u, // 'd'
Backslash = 0X5Cu, // '\\' E = 0x65u, // 'e'
RightBracket = 0X5DU, // ']' F = 0x66u, // 'f'
Caret = 0X5Eu, // '^' G = 0x67u, // 'g'
Underscore = 0X5Fu, // '_' H = 0x68u, // 'h'
GraveAccent = 0X60u, // '`' I = 0x69u, // 'i'
A = 0x61u, // 'a' J = 0x6Au, // 'j'
B = 0x62u, // 'b' K = 0x6Bu, // 'k'
C = 0x63u, // 'c' L = 0x6CU, // 'l'
D = 0x64u, // 'd' M = 0x6DU, // 'm'
E = 0x65u, // 'e' N = 0x6Eu, // 'n'
F = 0x66u, // 'f' O = 0x6Fu, // 'o'
G = 0x67u, // 'g' P = 0x70u, // 'p'
H = 0x68u, // 'h' Q = 0x71u, // 'q'
I = 0x69u, // 'i' R = 0x72u, // 'r'
J = 0x6Au, // 'j' S = 0x73u, // 's'
K = 0x6Bu, // 'k' T = 0x74u, // 't'
L = 0x6CU, // 'l' U = 0x75u, // 'y'
M = 0x6DU, // 'm' V = 0x76u, // 'v'
N = 0x6Eu, // 'n' W = 0x77u, // 'w'
O = 0x6Fu, // 'o' X = 0x78u, // 'x'
P = 0x70u, // 'p' Y = 0x79u, // 'y'
Q = 0x71u, // 'q' Z = 0x7Au, // 'z'
R = 0x72u, // 'r' LeftBrace = 0x7BU, // '{'
S = 0x73u, // 's' Pipe = 0x7CU, // '|'
T = 0x74u, // 't' RightBrace = 0x7DU, // '}'
U = 0x75u, // 'y' Tilde = 0x7Eu, // '~'
V = 0x76u, // 'v' Delete = 0x7Fu, // '\x7F'
W = 0x77u, // 'w' PlusMinus = 0xb1u, // '\xB1'
X = 0x78u, // 'x'
Y = 0x79u, // 'y'
Z = 0x7Au, // 'z'
LeftBrace = 0x7BU, // '{'
Pipe = 0x7CU, // '|'
RightBrace = 0x7DU, // '}'
Tilde = 0x7Eu, // '~'
Delete = 0x7Fu, // '\x7F'
PlusMinus = 0xb1u, // '\xB1'
// Keys not producing a character // Keys not producing a character
// Based on SDL Algo: ScanCode | 0x40000000 // Based on SDL Algo: ScanCode | 0x40000000
CapsLock = 0x40000039u, CapsLock = 0x40000039u,
F1 = 0x4000003Au, F1 = 0x4000003Au,
F2 = 0x4000003Bu, F2 = 0x4000003Bu,
F3 = 0x4000003CU, F3 = 0x4000003CU,
F4 = 0x4000003DU, F4 = 0x4000003DU,
F5 = 0x4000003Eu, F5 = 0x4000003Eu,
F6 = 0x4000003Fu, F6 = 0x4000003Fu,
F7 = 0x40000040u, F7 = 0x40000040u,
F8 = 0x40000041u, F8 = 0x40000041u,
F9 = 0x40000042u, F9 = 0x40000042u,
F10 = 0x40000043u, F10 = 0x40000043u,
F11 = 0x40000044u, F11 = 0x40000044u,
F12 = 0x40000045u, F12 = 0x40000045u,
PrintScreen = 0x40000046u, PrintScreen = 0x40000046u,
ScrollLock = 0x40000047u, ScrollLock = 0x40000047u,
Pause = 0x40000048u, Pause = 0x40000048u,
Insert = 0x40000049u, Insert = 0x40000049u,
Home = 0x4000004Au, Home = 0x4000004Au,
PageUp = 0x4000004Bu, PageUp = 0x4000004Bu,
End = 0x4000004DU, End = 0x4000004DU,
PageDown = 0x4000004Eu, PageDown = 0x4000004Eu,
RightArrow = 0x4000004Fu, RightArrow = 0x4000004Fu,
LeftArrow = 0x40000050u, LeftArrow = 0x40000050u,
DownArrow = 0x40000051u, DownArrow = 0x40000051u,
UpArrow = 0x40000052u, UpArrow = 0x40000052u,
NumlockClear = 0x40000053u, NumlockClear = 0x40000053u,
KeyPad_Divide = 0x40000054u, KeyPad_Divide = 0x40000054u,
KeyPad_Multiply = 0x40000055u, KeyPad_Multiply = 0x40000055u,
KeyPad_Minus = 0x40000056u, KeyPad_Minus = 0x40000056u,
KeyPad_Plus = 0x40000057u, KeyPad_Plus = 0x40000057u,
KeyPad_Enter = 0x40000058u, KeyPad_Enter = 0x40000058u,
KeyPad_Num1 = 0x40000059u, KeyPad_Num1 = 0x40000059u,
KeyPad_Num2 = 0x4000005Au, KeyPad_Num2 = 0x4000005Au,
KeyPad_Num3 = 0x4000005Bu, KeyPad_Num3 = 0x4000005Bu,
KeyPad_Num4 = 0x4000005Cu, KeyPad_Num4 = 0x4000005Cu,
KeyPad_Num5 = 0x4000005Du, KeyPad_Num5 = 0x4000005Du,
KeyPad_Num6 = 0x4000005Eu, KeyPad_Num6 = 0x4000005Eu,
KeyPad_Num7 = 0x4000005Fu, KeyPad_Num7 = 0x4000005Fu,
KeyPad_Num8 = 0x40000060u, KeyPad_Num8 = 0x40000060u,
KeyPad_Num9 = 0x40000061u, KeyPad_Num9 = 0x40000061u,
KeyPad_Num0 = 0x40000062u, KeyPad_Num0 = 0x40000062u,
KeyPad_Period = 0x40000063u, KeyPad_Period = 0x40000063u,
Power = 0x40000066u, Power = 0x40000066u,
KeyPad_Equals = 0x40000067u, KeyPad_Equals = 0x40000067u,
F13 = 0x40000068u, F13 = 0x40000068u,
F14 = 0x40000069u, F14 = 0x40000069u,
F15 = 0x4000006Au, F15 = 0x4000006Au,
F16 = 0x4000006Bu, F16 = 0x4000006Bu,
F17 = 0x4000006Cu, F17 = 0x4000006Cu,
F18 = 0x4000006Du, F18 = 0x4000006Du,
F19 = 0x4000006Eu, F19 = 0x4000006Eu,
F20 = 0x4000006Fu, F20 = 0x4000006Fu,
F21 = 0x40000070u, F21 = 0x40000070u,
F22 = 0x40000071u, F22 = 0x40000071u,
F23 = 0x40000072u, F23 = 0x40000072u,
F24 = 0x40000073u, F24 = 0x40000073u,
Mute = 0x4000007Fu, Mute = 0x4000007Fu,
VolumeUp = 0x40000080u, VolumeUp = 0x40000080u,
VolumeDown = 0x40000081u, VolumeDown = 0x40000081u,
KeyPad_Comma = 0x40000085u, KeyPad_Comma = 0x40000085u,
LeftControl = 0x400000E0u, LeftControl = 0x400000E0u,
LeftShift = 0x400000E1u, LeftShift = 0x400000E1u,
LeftAlt = 0x400000E2u, LeftAlt = 0x400000E2u,
LeftOSCommand = 0x400000E3u, LeftOSCommand = 0x400000E3u,
RightControl = 0x400000E4u, RightControl = 0x400000E4u,
RightShift = 0x400000E5u, RightShift = 0x400000E5u,
RightAlt = 0x400000E6u, RightAlt = 0x400000E6u,
RightOSCommand = 0x400000E7u, RightOSCommand = 0x400000E7u,
Sleep = 0x40000102u, Sleep = 0x40000102u,
WakeUp = 0x40000103u, WakeUp = 0x40000103u,
Media_NextTrack = 0x4000010Bu, Media_NextTrack = 0x4000010Bu,
Media_PreviousTrack = 0x4000010Cu, Media_PreviousTrack = 0x4000010Cu,
Media_Stop = 0x4000010Du, Media_Stop = 0x4000010Du,
Media_Eject = 0x4000010Eu, Media_Eject = 0x4000010Eu,
Media_PlayPause = 0x4000010Fu, Media_PlayPause = 0x4000010Fu,
Media_Select = 0x40000110u, Media_Select = 0x40000110u,
}; };
enum class KeyMod : uint16 enum class KeyMod : uint16
{ {
None = 0b0, None = 0b0,
LeftShift = 0b0000'0000'0001u, LeftShift = 0b0000'0000'0001u,
RightShift = 0b0000'0000'0010u, RightShift = 0b0000'0000'0010u,
LeftControl = 0b0000'0000'0100u, LeftControl = 0b0000'0000'0100u,
RightControl = 0b0000'0000'1000u, RightControl = 0b0000'0000'1000u,
LeftAlt = 0b0000'0001'000u, LeftAlt = 0b0000'0001'000u,
RightAlt = 0b0000'0010'0000u, RightAlt = 0b0000'0010'0000u,
LeftOSCommand = 0b0000'0100'0000u, LeftOSCommand = 0b0000'0100'0000u,
RightOSCommand = 0b0000'1000'0000u, RightOSCommand = 0b0000'1000'0000u,
NumLock = 0b0001'0000'0000u, NumLock = 0b0001'0000'0000u,
CapsLock = 0b0010'0000'0000u, CapsLock = 0b0010'0000'0000u,
ScrollLock = 0b0100'0000'0000u, ScrollLock = 0b0100'0000'0000u,
Control = LeftControl | RightControl, Control = LeftControl | RightControl,
Shift = LeftShift | RightShift, Shift = LeftShift | RightShift,
Alt = LeftAlt | RightAlt, Alt = LeftAlt | RightAlt,
OSCommand = LeftOSCommand | RightOSCommand, OSCommand = LeftOSCommand | RightOSCommand,
}; };
} // namespace Juliet
+22 -25
View File
@@ -1,35 +1,32 @@
#pragma once #pragma once
#include <Core/HAL/Keyboard/KeyCode.h> #include <Core/HAL/Keyboard/KeyCode.h>
#include <Core/HAL/Keyboard/ScanCode.h> #include <Core/HAL/Keyboard/ScanCode.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet using KeyboardID = uint8;
enum class KeyPosition : bool
{ {
using KeyboardID = uint8; Up = false,
Down = true
};
enum class KeyPosition : bool struct KeyState
{ {
Up = false, KeyPosition Position;
Down = true float Time;
}; };
struct KeyState struct Key
{ {
KeyPosition Position; ScanCode ScanCode;
float Time; KeyCode KeyCode;
}; uint16 Raw;
};
struct Key extern JULIET_API bool IsKeyDown(ScanCode scanCode);
{ extern JULIET_API bool IsKeyPressed(ScanCode scanCode);
ScanCode ScanCode;
KeyCode KeyCode;
uint16 Raw;
};
extern JULIET_API bool IsKeyDown(ScanCode scanCode); extern JULIET_API KeyMod GetKeyModState();
extern JULIET_API bool IsKeyPressed(ScanCode scanCode); extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState);
extern JULIET_API KeyMod GetKeyModState();
extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState);
} // namespace Juliet
+162 -165
View File
@@ -1,186 +1,183 @@
#pragma once #pragma once
namespace Juliet // Follow the HID Usage page for USB
// https://usb.org/sites/default/files/hut1_5.pdf
// 0 to 256 Is dedicated to Keyboard Usage Page (0x07)
// 257 to 286 Is dedicated to Consumer Usage Page (0xC)
// 287 to 511 Is not implemented. Could be used for Mobile or Consoles
// ScanCode reprensent Physical Keys and Buttons
enum class ScanCode : uint16
{ {
// Follow the HID Usage page for USB Unknown = 0,
// https://usb.org/sites/default/files/hut1_5.pdf Unsupported = 0,
// 0 to 256 Is dedicated to Keyboard Usage Page (0x07)
// 257 to 286 Is dedicated to Consumer Usage Page (0xC)
// 287 to 511 Is not implemented. Could be used for Mobile or Consoles
// ScanCode reprensent Physical Keys and Buttons
enum class ScanCode : uint16
{
Unknown = 0,
Unsupported = 0,
A = 4, A = 4,
B = 5, B = 5,
C = 6, C = 6,
D = 7, D = 7,
E = 8, E = 8,
F = 9, F = 9,
G = 10, G = 10,
H = 11, H = 11,
I = 12, I = 12,
J = 13, J = 13,
K = 14, K = 14,
L = 15, L = 15,
M = 16, M = 16,
N = 17, N = 17,
O = 18, O = 18,
P = 19, P = 19,
Q = 20, Q = 20,
R = 21, R = 21,
S = 22, S = 22,
T = 23, T = 23,
U = 24, U = 24,
V = 25, V = 25,
W = 26, W = 26,
X = 27, X = 27,
Y = 28, Y = 28,
Z = 29, Z = 29,
Num1 = 30, Num1 = 30,
Num2 = 31, Num2 = 31,
Num3 = 32, Num3 = 32,
Num4 = 33, Num4 = 33,
Num5 = 34, Num5 = 34,
Num6 = 35, Num6 = 35,
Num7 = 36, Num7 = 36,
Num8 = 37, Num8 = 37,
Num9 = 38, Num9 = 38,
Num0 = 39, Num0 = 39,
Return = 40, Return = 40,
Escape = 41, Escape = 41,
Backspace = 42, Backspace = 42,
Tab = 43, Tab = 43,
Space = 44, Space = 44,
Minus = 45, Minus = 45,
Equals = 46, Equals = 46,
LeftBracket = 47, LeftBracket = 47,
RightBracket = 48, RightBracket = 48,
Backslash = 49, Backslash = 49,
NonUSHash = 50, // Same as 49 but for ISO keyboards NonUSHash = 50, // Same as 49 but for ISO keyboards
Semicolon = 51, Semicolon = 51,
Apostrophe = 52, Apostrophe = 52,
GraveAccent = 53, GraveAccent = 53,
Comma = 54, Comma = 54,
Period = 55, Period = 55,
Slash = 56, Slash = 56,
CapsLock = 57, CapsLock = 57,
F1 = 58, F1 = 58,
F2 = 59, F2 = 59,
F3 = 60, F3 = 60,
F4 = 61, F4 = 61,
F5 = 62, F5 = 62,
F6 = 63, F6 = 63,
F7 = 64, F7 = 64,
F8 = 65, F8 = 65,
F9 = 66, F9 = 66,
F10 = 67, F10 = 67,
F11 = 68, F11 = 68,
F12 = 69, F12 = 69,
PrintScreen = 70, PrintScreen = 70,
ScrollLock = 71, ScrollLock = 71,
Pause = 72, Pause = 72,
Insert = 73, Insert = 73,
Home = 74, Home = 74,
PageUp = 75, PageUp = 75,
Delete = 76, Delete = 76,
End = 77, End = 77,
PageDown = 78, PageDown = 78,
RightArrow = 79, RightArrow = 79,
LeftArrow = 80, LeftArrow = 80,
DownArrow = 81, DownArrow = 81,
UpArrow = 82, UpArrow = 82,
NumlockClear = 83, // Pc = Numlock / Mac = Clear NumlockClear = 83, // Pc = Numlock / Mac = Clear
KeyPad_Divide = 84, KeyPad_Divide = 84,
KeyPad_Multiply = 85, KeyPad_Multiply = 85,
KeyPad_Minus = 86, KeyPad_Minus = 86,
KeyPad_Plus = 87, KeyPad_Plus = 87,
KeyPad_Enter = 88, KeyPad_Enter = 88,
KeyPad_Num1 = 89, KeyPad_Num1 = 89,
KeyPad_Num2 = 90, KeyPad_Num2 = 90,
KeyPad_Num3 = 91, KeyPad_Num3 = 91,
KeyPad_Num4 = 92, KeyPad_Num4 = 92,
KeyPad_Num5 = 93, KeyPad_Num5 = 93,
KeyPad_Num6 = 94, KeyPad_Num6 = 94,
KeyPad_Num7 = 95, KeyPad_Num7 = 95,
KeyPad_Num8 = 96, KeyPad_Num8 = 96,
KeyPad_Num9 = 97, KeyPad_Num9 = 97,
KeyPad_Num0 = 98, KeyPad_Num0 = 98,
KeyPad_Period = 99, KeyPad_Period = 99,
NonUSBackslash = 100, // ISO keyboards only NonUSBackslash = 100, // ISO keyboards only
Power = 102, // Some mac have a Power key Power = 102, // Some mac have a Power key
KeyPad_Equals = 103, KeyPad_Equals = 103,
F13 = 104, F13 = 104,
F14 = 105, F14 = 105,
F15 = 106, F15 = 106,
F16 = 107, F16 = 107,
F17 = 108, F17 = 108,
F18 = 109, F18 = 109,
F19 = 110, F19 = 110,
F20 = 111, F20 = 111,
F21 = 112, F21 = 112,
F22 = 113, F22 = 113,
F23 = 114, F23 = 114,
F24 = 115, F24 = 115,
Mute = 127, Mute = 127,
VolumeUp = 128, VolumeUp = 128,
VolumeDown = 129, VolumeDown = 129,
KeyPad_Comma = 133, KeyPad_Comma = 133,
International1 = 135, // Mostly used on Asian keyboards International1 = 135, // Mostly used on Asian keyboards
International2 = 136, International2 = 136,
International3 = 137, // Yen Symbol International3 = 137, // Yen Symbol
International4 = 138, International4 = 138,
International5 = 139, International5 = 139,
International6 = 140, International6 = 140,
International7 = 141, International7 = 141,
International8 = 142, International8 = 142,
International9 = 143, International9 = 143,
Lang1 = 144, // Hangul (Korean) Lang1 = 144, // Hangul (Korean)
Lang2 = 145, // Hanja (Korean) Lang2 = 145, // Hanja (Korean)
Lang3 = 146, // Katakana (Japanese) Lang3 = 146, // Katakana (Japanese)
Lang4 = 147, // Hiragana (Japanese) Lang4 = 147, // Hiragana (Japanese)
Lang5 = 148, // Zenkaku/Hankaku (Japanese) Lang5 = 148, // Zenkaku/Hankaku (Japanese)
Lang6 = 149, // Unused Lang6 = 149, // Unused
Lang7 = 150, // Unused Lang7 = 150, // Unused
Lang8 = 151, // Unused Lang8 = 151, // Unused
Lang9 = 152, // Unused Lang9 = 152, // Unused
LeftControl = 224, LeftControl = 224,
LeftShift = 225, LeftShift = 225,
LeftAlt = 226, // Alt for PC, Option for Mac LeftAlt = 226, // Alt for PC, Option for Mac
LeftOSCommand = 227, // Window key for PC, Command for Mac LeftOSCommand = 227, // Window key for PC, Command for Mac
RightControl = 228, RightControl = 228,
RightShift = 229, RightShift = 229,
RightAlt = 230, // Alt Gr for PC, Option for Mac RightAlt = 230, // Alt Gr for PC, Option for Mac
RightOSCommand = 231, // Window key for PC, Command for Mac RightOSCommand = 231, // Window key for PC, Command for Mac
Sleep = 258, Sleep = 258,
WakeUp = 259, WakeUp = 259,
Media_NextTrack = 267, Media_NextTrack = 267,
Media_PreviousTrack = 268, Media_PreviousTrack = 268,
Media_Stop = 269, Media_Stop = 269,
Media_Eject = 270, Media_Eject = 270,
Media_PlayPause = 271, Media_PlayPause = 271,
Media_Select = 272, Media_Select = 272,
Reserved = 287, Reserved = 287,
Count = 512 Count = 512
}; };
} // namespace Juliet
+21 -24
View File
@@ -1,28 +1,25 @@
#pragma once #pragma once
namespace Juliet using MouseID = uint8;
enum class MouseButton : uint8
{ {
using MouseID = uint8; None = 0,
Left = 1 << 0,
Right = 1 << 1,
Middle = 1 << 2,
Button1 = 1 << 3,
Button2 = 1 << 4,
};
enum class MouseButton : uint8 // TODO : Replace by Vector2f
{ struct MousePosition
None = 0, {
Left = 1 << 0, float X;
Right = 1 << 1, float Y;
Middle = 1 << 2, };
Button1 = 1 << 3,
Button2 = 1 << 4,
};
// TODO : Replace by Vector2f JULIET_API extern bool IsMouseButtonDown(MouseButton button);
struct MousePosition JULIET_API extern MousePosition GetMousePosition();
{ JULIET_API extern MousePosition GetMouseDelta();
float X; JULIET_API extern MouseButton GetMouseButtonState();
float Y;
};
JULIET_API extern bool IsMouseButtonDown(MouseButton button);
JULIET_API extern MousePosition GetMousePosition();
JULIET_API extern MousePosition GetMouseDelta();
JULIET_API extern MouseButton GetMouseButtonState();
} // namespace Juliet
+35 -38
View File
@@ -1,49 +1,46 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet namespace Memory
{ {
namespace Memory Byte* OS_Reserve(size_t size);
bool OS_Commit(Byte* ptr, size_t size);
void OS_Release(Byte* ptr, size_t size);
template <typename Type>
Type* OS_Reserve(size_t size)
{ {
Byte* OS_Reserve(size_t size); return reinterpret_cast<Type*>(OS_Reserve(size));
bool OS_Commit(Byte* ptr, size_t size); }
void OS_Release(Byte* ptr, size_t size);
template <typename Type> template <typename Type>
Type* OS_Reserve(size_t size) bool OS_Commit(Type* ptr, size_t size)
{
return reinterpret_cast<Type*>(OS_Reserve(size));
}
template <typename Type>
bool OS_Commit(Type* ptr, size_t size)
{
return OS_Commit(reinterpret_cast<Byte*>(ptr), size);
}
template <typename Type>
void OS_Release(Type* ptr, size_t size)
{
OS_Release(reinterpret_cast<Byte*>(ptr), size);
}
} // namespace Memory
namespace Time
{ {
uint64 Timestamp(); return OS_Commit(reinterpret_cast<Byte*>(ptr), size);
void ComputeDeltaTime(); }
float GetDeltaTime();
uint64 GetFrameNumber();
} // namespace Time
namespace Debug template <typename Type>
void OS_Release(Type* ptr, size_t size)
{ {
JULIET_API bool IsDebuggerPresent(); OS_Release(reinterpret_cast<Byte*>(ptr), size);
} // namespace Debug }
using EntryPointFunc = int (*)(int, wchar_t**); } // namespace Memory
JULIET_API int Bootstrap(EntryPointFunc entryPointFunc, int argc, wchar_t** argv);
} // namespace Juliet namespace Time
{
uint64 Timestamp();
void ComputeDeltaTime();
float GetDeltaTime();
uint64 GetFrameNumber();
} // namespace Time
namespace Debug
{
JULIET_API bool IsDebuggerPresent();
} // namespace Debug
using EntryPointFunc = int (*)(int, wchar_t**);
JULIET_API int Bootstrap(EntryPointFunc entryPointFunc, int argc, wchar_t** argv);
+23 -26
View File
@@ -1,38 +1,35 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
namespace Juliet // Fwd Declare
struct DynamicLibrary;
struct HotReloadCode
{ {
// Fwd Declare String DLLFullPath;
struct DynamicLibrary; String LockFullPath;
String TransientDLLName;
struct HotReloadCode uint64 LastWriteTime;
{
String DLLFullPath;
String LockFullPath;
String TransientDLLName;
uint64 LastWriteTime; DynamicLibrary* Dll;
DynamicLibrary* Dll; void** Functions;
const char** FunctionNames;
uint32 FunctionCount;
void** Functions; uint32 UniqueID;
const char** FunctionNames;
uint32 FunctionCount;
uint32 UniqueID; bool IsValid : 1;
};
bool IsValid : 1; 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 InitHotReloadCode(NonNullPtr<Arena> arena, HotReloadCode& code, String dllName, extern JULIET_API void LoadCode(HotReloadCode& code);
String transientDllName, String lockFilename); extern JULIET_API void UnloadCode(HotReloadCode& code);
extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code);
extern JULIET_API void LoadCode(HotReloadCode& code); extern JULIET_API void ReloadCode(HotReloadCode& code);
extern JULIET_API void UnloadCode(HotReloadCode& code); extern JULIET_API bool ShouldReloadCode(const HotReloadCode& code);
extern JULIET_API void ReloadCode(HotReloadCode& code);
extern JULIET_API bool ShouldReloadCode(const HotReloadCode& code);
} // namespace Juliet
+14 -17
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
@@ -7,25 +7,22 @@
struct ImGuiContext; struct ImGuiContext;
namespace Juliet struct Window;
struct GraphicsDevice;
namespace ImGuiService
{ {
struct Window; JULIET_API void Initialize(NonNullPtr<Window> window);
struct GraphicsDevice; JULIET_API void Shutdown();
namespace ImGuiService JULIET_API void NewFrame();
{ JULIET_API void Render();
JULIET_API void Initialize(NonNullPtr<Window> window);
JULIET_API void Shutdown();
JULIET_API void NewFrame(); JULIET_API bool IsInitialized();
JULIET_API void Render(); JULIET_API ImGuiContext* GetContext();
JULIET_API bool IsInitialized(); // Run internal unit tests
JULIET_API ImGuiContext* GetContext(); JULIET_API void RunTests();
} // namespace ImGuiService
// Run internal unit tests
JULIET_API void RunTests();
} // namespace ImGuiService
} // namespace Juliet
#endif // JULIET_ENABLE_IMGUI #endif // JULIET_ENABLE_IMGUI
+2 -2
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/HAL/Display/Window.h> #include <Core/HAL/Display/Window.h>
@@ -6,7 +6,7 @@
#include <Juliet.h> #include <Juliet.h>
namespace Juliet::UnitTest namespace UnitTest
{ {
void TestImGui(); void TestImGui();
} }
+16 -19
View File
@@ -1,26 +1,23 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
namespace Juliet enum class JulietInit_Flags : uint8
{ {
enum class JulietInit_Flags : uint8 None = 0,
{ Display = 1 << 0,
None = 0, Audio = 1 << 1,
Display = 1 << 0, Count = Audio,
Audio = 1 << 1, All = 0xFb
Count = Audio, };
All = 0xFb
};
struct Arena; struct Arena;
struct GameData struct GameData
{ {
struct GameState* GameState; struct GameState* GameState;
Arena* ScratchArena; Arena* ScratchArena;
}; };
void JulietInit(JulietInit_Flags flags); void JulietInit(JulietInit_Flags flags);
void JulietShutdown(); void JulietShutdown();
} // namespace Juliet
+13 -16
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
@@ -9,21 +9,18 @@
// TODO Juliet Containers + Allocators... // TODO Juliet Containers + Allocators...
// TODO: Juliet chrono, because it prevents me from doing #define global static // TODO: Juliet chrono, because it prevents me from doing #define global static
namespace Juliet enum class LogLevel : uint8;
{ enum class LogCategory : uint8;
enum class LogLevel : uint8;
enum class LogCategory : uint8;
extern void JULIET_API InitializeLogManager(); extern void JULIET_API InitializeLogManager();
extern void JULIET_API ShutdownLogManager(); extern void JULIET_API ShutdownLogManager();
extern void JULIET_API LogScopeBegin(); extern void JULIET_API LogScopeBegin();
// TODO everything that happened in there to export them to file or something // TODO everything that happened in there to export them to file or something
extern void JULIET_API LogScopeEnd(); extern void JULIET_API LogScopeEnd();
extern void JULIET_API Log(LogLevel level, LogCategory category, const char* fmt, ...); extern void JULIET_API Log(LogLevel level, LogCategory category, const char* fmt, ...);
extern void JULIET_API LogDebug(LogCategory category, const char* fmt, ...); extern void JULIET_API LogDebug(LogCategory category, const char* fmt, ...);
extern void JULIET_API LogMessage(LogCategory category, const char* fmt, ...); extern void JULIET_API LogMessage(LogCategory category, const char* fmt, ...);
extern void JULIET_API LogWarning(LogCategory category, const char* fmt, ...); extern void JULIET_API LogWarning(LogCategory category, const char* fmt, ...);
extern void JULIET_API LogError(LogCategory category, const char* fmt, ...); extern void JULIET_API LogError(LogCategory category, const char* fmt, ...);
} // namespace Juliet
+16 -19
View File
@@ -1,22 +1,19 @@
#pragma once #pragma once
namespace Juliet enum class LogLevel : uint8
{ {
enum class LogLevel : uint8 Debug = 0,
{ Message = 1,
Debug = 0, Warning = 2,
Message = 1, Error = 3,
Warning = 2, };
Error = 3,
};
enum class LogCategory : uint8 enum class LogCategory : uint8
{ {
Core = 0, Core = 0,
Graphics = 1, Graphics = 1,
Networking = 2, Networking = 2,
Engine = 3, Engine = 3,
Tool = 4, Tool = 4,
Game = 5, Game = 5,
}; };
} // namespace Juliet
+4 -4
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/HAL/OS/OS.h> #include <Core/HAL/OS/OS.h>
@@ -12,12 +12,12 @@ extern int JulietMain(int, wchar_t**);
#if UNICODE #if UNICODE
int wmain(int argc, wchar_t** argv) int wmain(int argc, wchar_t** argv)
{ {
return Juliet::Bootstrap(JulietMain, argc, argv); return Bootstrap(JulietMain, argc, argv);
} }
#else #else
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
return Juliet::Bootstrap(JulietMain, argc, argv); return Bootstrap(JulietMain, argc, argv);
} }
#endif #endif
@@ -38,7 +38,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
(void)szCmdLine; (void)szCmdLine;
(void)sw; (void)sw;
return Juliet::Bootstrap(JulietMain, __argc, __wargv); return Bootstrap(JulietMain, __argc, __wargv);
} }
} }
#else #else
+35 -38
View File
@@ -1,52 +1,49 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet extern JULIET_API float RoundF(float value);
inline int32 LRoundF(float value)
{ {
extern JULIET_API float RoundF(float value); return static_cast<int32>(RoundF(value));
}
inline int32 LRoundF(float value) template <typename Type>
{ constexpr Type Min(Type lhs, Type rhs)
return static_cast<int32>(RoundF(value)); {
} return rhs < lhs ? rhs : lhs;
}
template <typename Type> template <typename Type>
constexpr Type Min(Type lhs, Type rhs) constexpr Type Max(Type lhs, Type rhs)
{ {
return rhs < lhs ? rhs : lhs; return lhs < rhs ? rhs : lhs;
} }
template <typename Type> template <typename Type>
constexpr Type Max(Type lhs, Type rhs) constexpr Type ClampTop(Type value, Type X)
{ {
return lhs < rhs ? rhs : lhs; return Min(value, X);
} }
template <typename Type> template <typename Type>
constexpr Type ClampTop(Type value, Type X) constexpr Type ClampBottom(Type value, Type X)
{ {
return Min(value, X); return Max(value, X);
} }
template <typename Type> template <typename Type>
constexpr Type ClampBottom(Type value, Type X) constexpr Type Clamp(Type val, Type min, Type max)
{
if (val < min)
{ {
return Max(value, X); return min;
} }
if (val > max)
template <typename Type>
constexpr Type Clamp(Type val, Type min, Type max)
{ {
if (val < min) return max;
{
return min;
}
if (val > max)
{
return max;
}
return val;
} }
} // namespace Juliet return val;
}
+174 -177
View File
@@ -1,194 +1,191 @@
#pragma once #pragma once
#include <Core/Math/Vector.h> #include <Core/Math/Vector.h>
#include <math.h> #include <math.h>
namespace Juliet struct Matrix
{ {
struct Matrix float m[4][4];
{ };
float m[4][4];
};
[[nodiscard]] inline Matrix MatrixIdentity() [[nodiscard]] inline Matrix MatrixIdentity()
{ {
Matrix result = {}; Matrix result = {};
result.m[0][0] = 1.0f; result.m[0][0] = 1.0f;
result.m[1][1] = 1.0f; result.m[1][1] = 1.0f;
result.m[2][2] = 1.0f; result.m[2][2] = 1.0f;
result.m[3][3] = 1.0f; result.m[3][3] = 1.0f;
return result; return result;
} }
[[nodiscard]] inline Matrix operator*(const Matrix& lhs, const Matrix& rhs) [[nodiscard]] inline Matrix operator*(const Matrix& lhs, const Matrix& rhs)
{
Matrix result = {};
for (int i = 0; i < 4; ++i)
{ {
Matrix result = {}; for (int j = 0; j < 4; ++j)
for (int i = 0; i < 4; ++i)
{ {
for (int j = 0; j < 4; ++j) for (int k = 0; k < 4; ++k)
{ {
for (int k = 0; k < 4; ++k) result.m[i][j] += lhs.m[i][k] * rhs.m[k][j];
{
result.m[i][j] += lhs.m[i][k] * rhs.m[k][j];
}
} }
} }
return result;
} }
return result;
}
[[nodiscard]] inline Matrix MatrixTranslation(float x, float y, float z) [[nodiscard]] inline Matrix MatrixTranslation(float x, float y, float z)
{
Matrix result = MatrixIdentity();
result.m[0][3] = x;
result.m[1][3] = y;
result.m[2][3] = z;
return result;
}
[[nodiscard]] inline Matrix MatrixScale(float x, float y, float z)
{
Matrix result = MatrixIdentity();
result.m[0][0] = x;
result.m[1][1] = y;
result.m[2][2] = z;
return result;
}
[[nodiscard]] inline Matrix MatrixRotationX(float radians)
{
float c = cosf(radians);
float s = sinf(radians);
Matrix result = MatrixIdentity();
result.m[1][1] = c;
result.m[1][2] = -s;
result.m[2][1] = s;
result.m[2][2] = c;
return result;
}
[[nodiscard]] inline Matrix MatrixRotationY(float radians)
{
float c = cosf(radians);
float s = sinf(radians);
Matrix result = MatrixIdentity();
result.m[0][0] = c;
result.m[0][2] = s;
result.m[2][0] = -s;
result.m[2][2] = c;
return result;
}
[[nodiscard]] inline Matrix MatrixRotationZ(float radians)
{
float c = cosf(radians);
float s = sinf(radians);
Matrix result = MatrixIdentity();
result.m[0][0] = c;
result.m[0][1] = -s;
result.m[1][0] = s;
result.m[1][1] = c;
return result;
}
inline void MatrixTranslate(Matrix& m, const Vector3& v)
{
m.m[0][3] += v.x;
m.m[1][3] += v.y;
m.m[2][3] += v.z;
}
[[nodiscard]] inline Matrix MatrixRotation(float x, float y, float z)
{
return MatrixRotationX(x) * MatrixRotationY(y) * MatrixRotationZ(z);
}
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
{
// Left-Handed convention
Vector3 zaxis = Normalize(target - eye); // Forward is +z
Vector3 xaxis = Normalize(Cross(up, zaxis));
Vector3 yaxis = Cross(zaxis, xaxis);
Matrix result = {};
// Row 0
result.m[0][0] = xaxis.x;
result.m[0][1] = xaxis.y;
result.m[0][2] = xaxis.z;
result.m[0][3] = -Dot(xaxis, eye);
// Row 1
result.m[1][0] = yaxis.x;
result.m[1][1] = yaxis.y;
result.m[1][2] = yaxis.z;
result.m[1][3] = -Dot(yaxis, eye);
// Row 2
result.m[2][0] = zaxis.x;
result.m[2][1] = zaxis.y;
result.m[2][2] = zaxis.z;
result.m[2][3] = -Dot(zaxis, eye);
// Row 3
result.m[3][3] = 1.0f;
return result;
}
inline Matrix PerspectiveFov(float fovY, float aspectRatio, float nearZ, float farZ)
{
// Left-Handed Perspective
float yScale = 1.0f / tanf(fovY * 0.5f);
float xScale = yScale / aspectRatio;
Matrix result = {};
result.m[0][0] = xScale;
result.m[1][1] = yScale;
result.m[2][2] = farZ / (farZ - nearZ);
result.m[2][3] = (-nearZ * farZ) / (farZ - nearZ);
result.m[3][2] = 1.0f;
result.m[3][3] = 0.0f;
return result;
}
[[nodiscard]] inline Matrix MatrixInverse(const Matrix& m)
{
Matrix out = {};
float m00 = m.m[0][0], m01 = m.m[0][1], m02 = m.m[0][2], m03 = m.m[0][3];
float m10 = m.m[1][0], m11 = m.m[1][1], m12 = m.m[1][2], m13 = m.m[1][3];
float m20 = m.m[2][0], m21 = m.m[2][1], m22 = m.m[2][2], m23 = m.m[2][3];
float m30 = m.m[3][0], m31 = m.m[3][1], m32 = m.m[3][2], m33 = m.m[3][3];
out.m[0][0] = m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22;
out.m[1][0] = -m10 * m22 * m33 + m10 * m23 * m32 + m20 * m12 * m33 - m20 * m13 * m32 - m30 * m12 * m23 + m30 * m13 * m22;
out.m[2][0] = m10 * m21 * m33 - m10 * m23 * m31 - m20 * m11 * m33 + m20 * m13 * m31 + m30 * m11 * m23 - m30 * m13 * m21;
out.m[3][0] = -m10 * m21 * m32 + m10 * m22 * m31 + m20 * m11 * m32 - m20 * m12 * m31 - m30 * m11 * m22 + m30 * m12 * m21;
out.m[0][1] = -m01 * m22 * m33 + m01 * m23 * m32 + m21 * m02 * m33 - m21 * m03 * m32 - m31 * m02 * m23 + m31 * m03 * m22;
out.m[1][1] = m00 * m22 * m33 - m00 * m23 * m32 - m20 * m02 * m33 + m20 * m03 * m32 + m30 * m02 * m23 - m30 * m03 * m22;
out.m[2][1] = -m00 * m21 * m33 + m00 * m23 * m31 + m20 * m01 * m33 - m20 * m03 * m31 - m30 * m01 * m23 + m30 * m03 * m21;
out.m[3][1] = m00 * m21 * m32 - m00 * m22 * m31 - m20 * m01 * m32 + m20 * m02 * m31 + m30 * m01 * m22 - m30 * m02 * m21;
out.m[0][2] = m01 * m12 * m33 - m01 * m13 * m32 - m11 * m02 * m33 + m11 * m03 * m32 + m31 * m02 * m13 - m31 * m03 * m12;
out.m[1][2] = -m00 * m12 * m33 + m00 * m13 * m32 + m10 * m02 * m33 - m10 * m03 * m32 - m30 * m02 * m13 + m30 * m03 * m12;
out.m[2][2] = m00 * m11 * m33 - m00 * m13 * m31 - m10 * m01 * m33 + m10 * m03 * m31 + m30 * m01 * m13 - m30 * m03 * m11;
out.m[3][2] = -m00 * m11 * m32 + m00 * m12 * m31 + m10 * m01 * m32 - m10 * m02 * m31 - m30 * m01 * m12 + m30 * m02 * m11;
out.m[0][3] = -m01 * m12 * m23 + m01 * m13 * m22 + m11 * m02 * m23 - m11 * m03 * m22 - m21 * m02 * m13 + m21 * m03 * m12;
out.m[1][3] = m00 * m12 * m23 - m00 * m13 * m22 - m10 * m02 * m23 + m10 * m03 * m22 + m20 * m02 * m13 - m20 * m03 * m12;
out.m[2][3] = -m00 * m11 * m23 + m00 * m13 * m21 + m10 * m01 * m23 - m10 * m03 * m21 - m20 * m01 * m13 + m20 * m03 * m11;
out.m[3][3] = m00 * m11 * m22 - m00 * m12 * m21 - m10 * m01 * m22 + m10 * m02 * m21 + m20 * m01 * m12 - m20 * m02 * m11;
float det = m00 * out.m[0][0] + m01 * out.m[1][0] + m02 * out.m[2][0] + m03 * out.m[3][0];
if (det != 0.0f)
{ {
Matrix result = MatrixIdentity(); float invDet = 1.0f / det;
result.m[0][3] = x; for (int r = 0; r < 4; ++r)
result.m[1][3] = y; for (int c = 0; c < 4; ++c)
result.m[2][3] = z; out.m[r][c] *= invDet;
return result;
} }
[[nodiscard]] inline Matrix MatrixScale(float x, float y, float z) return out;
{ }
Matrix result = MatrixIdentity();
result.m[0][0] = x;
result.m[1][1] = y;
result.m[2][2] = z;
return result;
}
[[nodiscard]] inline Matrix MatrixRotationX(float radians)
{
float c = cosf(radians);
float s = sinf(radians);
Matrix result = MatrixIdentity();
result.m[1][1] = c;
result.m[1][2] = -s;
result.m[2][1] = s;
result.m[2][2] = c;
return result;
}
[[nodiscard]] inline Matrix MatrixRotationY(float radians)
{
float c = cosf(radians);
float s = sinf(radians);
Matrix result = MatrixIdentity();
result.m[0][0] = c;
result.m[0][2] = s;
result.m[2][0] = -s;
result.m[2][2] = c;
return result;
}
[[nodiscard]] inline Matrix MatrixRotationZ(float radians)
{
float c = cosf(radians);
float s = sinf(radians);
Matrix result = MatrixIdentity();
result.m[0][0] = c;
result.m[0][1] = -s;
result.m[1][0] = s;
result.m[1][1] = c;
return result;
}
inline void MatrixTranslate(Matrix& m, const Vector3& v)
{
m.m[0][3] += v.x;
m.m[1][3] += v.y;
m.m[2][3] += v.z;
}
[[nodiscard]] inline Matrix MatrixRotation(float x, float y, float z)
{
return MatrixRotationX(x) * MatrixRotationY(y) * MatrixRotationZ(z);
}
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
{
// Left-Handed convention
Vector3 zaxis = Normalize(target - eye); // Forward is +z
Vector3 xaxis = Normalize(Cross(up, zaxis));
Vector3 yaxis = Cross(zaxis, xaxis);
Matrix result = {};
// Row 0
result.m[0][0] = xaxis.x;
result.m[0][1] = xaxis.y;
result.m[0][2] = xaxis.z;
result.m[0][3] = -Dot(xaxis, eye);
// Row 1
result.m[1][0] = yaxis.x;
result.m[1][1] = yaxis.y;
result.m[1][2] = yaxis.z;
result.m[1][3] = -Dot(yaxis, eye);
// Row 2
result.m[2][0] = zaxis.x;
result.m[2][1] = zaxis.y;
result.m[2][2] = zaxis.z;
result.m[2][3] = -Dot(zaxis, eye);
// Row 3
result.m[3][3] = 1.0f;
return result;
}
inline Matrix PerspectiveFov(float fovY, float aspectRatio, float nearZ, float farZ)
{
// Left-Handed Perspective
float yScale = 1.0f / tanf(fovY * 0.5f);
float xScale = yScale / aspectRatio;
Matrix result = {};
result.m[0][0] = xScale;
result.m[1][1] = yScale;
result.m[2][2] = farZ / (farZ - nearZ);
result.m[2][3] = (-nearZ * farZ) / (farZ - nearZ);
result.m[3][2] = 1.0f;
result.m[3][3] = 0.0f;
return result;
}
[[nodiscard]] inline Matrix MatrixInverse(const Matrix& m)
{
Matrix out = {};
float m00 = m.m[0][0], m01 = m.m[0][1], m02 = m.m[0][2], m03 = m.m[0][3];
float m10 = m.m[1][0], m11 = m.m[1][1], m12 = m.m[1][2], m13 = m.m[1][3];
float m20 = m.m[2][0], m21 = m.m[2][1], m22 = m.m[2][2], m23 = m.m[2][3];
float m30 = m.m[3][0], m31 = m.m[3][1], m32 = m.m[3][2], m33 = m.m[3][3];
out.m[0][0] = m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22;
out.m[1][0] = -m10 * m22 * m33 + m10 * m23 * m32 + m20 * m12 * m33 - m20 * m13 * m32 - m30 * m12 * m23 + m30 * m13 * m22;
out.m[2][0] = m10 * m21 * m33 - m10 * m23 * m31 - m20 * m11 * m33 + m20 * m13 * m31 + m30 * m11 * m23 - m30 * m13 * m21;
out.m[3][0] = -m10 * m21 * m32 + m10 * m22 * m31 + m20 * m11 * m32 - m20 * m12 * m31 - m30 * m11 * m22 + m30 * m12 * m21;
out.m[0][1] = -m01 * m22 * m33 + m01 * m23 * m32 + m21 * m02 * m33 - m21 * m03 * m32 - m31 * m02 * m23 + m31 * m03 * m22;
out.m[1][1] = m00 * m22 * m33 - m00 * m23 * m32 - m20 * m02 * m33 + m20 * m03 * m32 + m30 * m02 * m23 - m30 * m03 * m22;
out.m[2][1] = -m00 * m21 * m33 + m00 * m23 * m31 + m20 * m01 * m33 - m20 * m03 * m31 - m30 * m01 * m23 + m30 * m03 * m21;
out.m[3][1] = m00 * m21 * m32 - m00 * m22 * m31 - m20 * m01 * m32 + m20 * m02 * m31 + m30 * m01 * m22 - m30 * m02 * m21;
out.m[0][2] = m01 * m12 * m33 - m01 * m13 * m32 - m11 * m02 * m33 + m11 * m03 * m32 + m31 * m02 * m13 - m31 * m03 * m12;
out.m[1][2] = -m00 * m12 * m33 + m00 * m13 * m32 + m10 * m02 * m33 - m10 * m03 * m32 - m30 * m02 * m13 + m30 * m03 * m12;
out.m[2][2] = m00 * m11 * m33 - m00 * m13 * m31 - m10 * m01 * m33 + m10 * m03 * m31 + m30 * m01 * m13 - m30 * m03 * m11;
out.m[3][2] = -m00 * m11 * m32 + m00 * m12 * m31 + m10 * m01 * m32 - m10 * m02 * m31 - m30 * m01 * m12 + m30 * m02 * m11;
out.m[0][3] = -m01 * m12 * m23 + m01 * m13 * m22 + m11 * m02 * m23 - m11 * m03 * m22 - m21 * m02 * m13 + m21 * m03 * m12;
out.m[1][3] = m00 * m12 * m23 - m00 * m13 * m22 - m10 * m02 * m23 + m10 * m03 * m22 + m20 * m02 * m13 - m20 * m03 * m12;
out.m[2][3] = -m00 * m11 * m23 + m00 * m13 * m21 + m10 * m01 * m23 - m10 * m03 * m21 - m20 * m01 * m13 + m20 * m03 * m11;
out.m[3][3] = m00 * m11 * m22 - m00 * m12 * m21 - m10 * m01 * m22 + m10 * m02 * m21 + m20 * m01 * m12 - m20 * m02 * m11;
float det = m00 * out.m[0][0] + m01 * out.m[1][0] + m02 * out.m[2][0] + m03 * out.m[3][0];
if (det != 0.0f)
{
float invDet = 1.0f / det;
for (int r = 0; r < 4; ++r)
for (int c = 0; c < 4; ++c)
out.m[r][c] *= invDet;
}
return out;
}
} // namespace Juliet
+7 -10
View File
@@ -1,12 +1,9 @@
#pragma once #pragma once
namespace Juliet struct Rectangle
{ {
struct Rectangle int32 X;
{ int32 Y;
int32 X; int32 Width;
int32 Y; int32 Height;
int32 Width; };
int32 Height;
};
} // namespace Juliet
+23 -26
View File
@@ -1,39 +1,36 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Juliet.h> #include <Juliet.h>
#include <math.h> #include <math.h>
namespace Juliet struct Vector3
{ {
struct Vector3 float x, y, z;
{
float x, y, z;
Vector3 operator+(const Vector3& rhs) const { return { x + rhs.x, y + rhs.y, z + rhs.z }; } Vector3 operator+(const Vector3& rhs) const { return { x + rhs.x, y + rhs.y, z + rhs.z }; }
Vector3 operator-(const Vector3& rhs) const { return { x - rhs.x, y - rhs.y, z - rhs.z }; } Vector3 operator-(const Vector3& rhs) const { return { x - rhs.x, y - rhs.y, z - rhs.z }; }
Vector3 operator*(float s) const { return { x * s, y * s, z * s }; } Vector3 operator*(float s) const { return { x * s, y * s, z * s }; }
}; };
struct Vector4 struct Vector4
{ {
float x, y, z, w; float x, y, z, w;
}; };
inline Vector3 Normalize(const Vector3& v) inline Vector3 Normalize(const Vector3& v)
{
float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
if (len > 0.0001f)
{ {
float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); return { v.x / len, v.y / len, v.z / len };
if (len > 0.0001f)
{
return { v.x / len, v.y / len, v.z / len };
}
return v;
} }
return v;
}
inline Vector3 Cross(const Vector3& a, const Vector3& b) inline Vector3 Cross(const Vector3& a, const Vector3& b)
{ {
return { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x }; return { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x };
} }
inline float Dot(const Vector3& a, const Vector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } inline float Dot(const Vector3& a, const Vector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
} // namespace Juliet
+20 -23
View File
@@ -1,31 +1,28 @@
#pragma once #pragma once
#include <Juliet.h> #include <Juliet.h>
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
namespace Juliet // Uninitialized allocation
{ JULIET_API void* Malloc(size_t elem_size);
// Uninitialized allocation // Initialized to 0 allocation
JULIET_API void* Malloc(size_t elem_size); JULIET_API void* Calloc(size_t nb_elem, size_t elem_size);
// Initialized to 0 allocation JULIET_API void* Realloc(void* memory, size_t newSize);
JULIET_API void* Calloc(size_t nb_elem, size_t elem_size);
JULIET_API void* Realloc(void* memory, size_t newSize);
// Free // Free
template <typename Type> template <typename Type>
void Free(Type* memory) void Free(Type* memory)
{
Assert(memory);
::free(memory);
}
// Free and Set the ptr to nullptr
template <typename Type>
void SafeFree(Type*& memory)
{
if (memory)
{ {
Assert(memory);
::free(memory); ::free(memory);
memory = nullptr;
} }
// Free and Set the ptr to nullptr }
template <typename Type>
void SafeFree(Type*& memory)
{
if (memory)
{
::free(memory);
memory = nullptr;
}
}
} // namespace Juliet
+108 -111
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
@@ -10,122 +10,119 @@
#include <Core/Memory/MemoryArenaDebug.h> #include <Core/Memory/MemoryArenaDebug.h>
#endif #endif
namespace Juliet constexpr global uint64 g_Arena_Default_Reserve_Size = Megabytes(64);
constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64);
constexpr global uint64 k_ArenaHeaderSize = 128;
#if JULIET_DEBUG
struct ArenaDebugInfo;
JULIET_API String FormatDebugTagV(const char* formatStr, std::format_args args);
#endif
struct Arena
{ {
constexpr global uint64 g_Arena_Default_Reserve_Size = Megabytes(64); Arena* Previous;
constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64); Arena* Current;
constexpr global uint64 k_ArenaHeaderSize = 128;
uint64 BasePosition;
uint64 Position;
uint64 Alignment;
uint64 CommitSize;
uint64 ReserveSize;
uint64 Committed;
uint64 Reserved;
Arena* FreeBlockLast;
JULIET_DEBUG_ONLY(uint16 LostNodeCount;)
JULIET_DEBUG_ONLY(bool CanReserveMore : 1;)
JULIET_DEBUG_ONLY(Arena* GlobalNext;)
JULIET_DEBUG_ONLY(Arena* GlobalPrev;)
JULIET_DEBUG_ONLY(ArenaDebugInfo* FirstDebugInfo;)
const char* Name;
};
static_assert(sizeof(Arena) <= k_ArenaHeaderSize);
struct TempArena
{
Arena* Arena;
index_t Position;
};
struct ArenaParams
{
uint64 ReserveSize = g_Arena_Default_Reserve_Size;
uint64 CommitSize = g_Arena_Default_Commit_Size;
const char* Name;
// When false, will assert if a new block is reserved.
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
};
[[nodiscard]] JULIET_API Arena* ArenaAllocate(const ArenaParams& params,
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
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_PARAM(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);
[[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena);
#if JULIET_DEBUG #if JULIET_DEBUG
struct ArenaDebugInfo; template <typename FirstDebugArg, typename... DebugArgs>
JULIET_API String FormatDebugTagV(const char* formatStr, std::format_args args);
#endif #endif
[[nodiscard]] inline void* ArenaPushSize(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_PARAM(FirstDebugArg&& firstDebugArg,
DebugArgs&&... debugArgs))
{
return ArenaPush(arena, size, align,
shouldBeZeroed JULIET_DEBUG_PARAM(
[&]() -> const char*
{
return Format(GetDebugInfoArena(), std::forward<FirstDebugArg>(firstDebugArg),
std::forward<DebugArgs>(debugArgs)...)
.Str;
}()));
}
struct Arena template <typename Type JULIET_DEBUG_ONLY(, typename... DebugArgs)>
{ [[nodiscard]] Type* ArenaPushStruct(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
Arena* Previous; {
Arena* Current; return static_cast<Type*>(
ArenaPush(arena, sizeof(Type) * 1, AlignOf(Type),
uint64 BasePosition; true JULIET_DEBUG_PARAM(
uint64 Position; [&]() -> const char*
uint64 Alignment; {
if constexpr (sizeof...(DebugArgs) > 0)
uint64 CommitSize;
uint64 ReserveSize;
uint64 Committed;
uint64 Reserved;
Arena* FreeBlockLast;
JULIET_DEBUG_ONLY(uint16 LostNodeCount;)
JULIET_DEBUG_ONLY(bool CanReserveMore : 1;)
JULIET_DEBUG_ONLY(Arena* GlobalNext;)
JULIET_DEBUG_ONLY(Arena* GlobalPrev;)
JULIET_DEBUG_ONLY(ArenaDebugInfo* FirstDebugInfo;)
const char* Name;
};
static_assert(sizeof(Arena) <= k_ArenaHeaderSize);
struct TempArena
{
Arena* Arena;
index_t Position;
};
struct ArenaParams
{
uint64 ReserveSize = g_Arena_Default_Reserve_Size;
uint64 CommitSize = g_Arena_Default_Commit_Size;
const char* Name;
// When false, will assert if a new block is reserved.
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
};
[[nodiscard]] JULIET_API Arena* ArenaAllocate(const ArenaParams& params,
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
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_PARAM(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);
[[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena);
#if JULIET_DEBUG
template <typename FirstDebugArg, typename... DebugArgs>
#endif
[[nodiscard]] inline void* ArenaPushSize(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_PARAM(FirstDebugArg&& firstDebugArg,
DebugArgs&&... debugArgs))
{
return ArenaPush(arena, size, align,
shouldBeZeroed JULIET_DEBUG_PARAM(
[&]() -> const char*
{
return Format(GetDebugInfoArena(), std::forward<FirstDebugArg>(firstDebugArg),
std::forward<DebugArgs>(debugArgs)...)
.Str;
}()));
}
template <typename Type JULIET_DEBUG_ONLY(, typename... DebugArgs)>
[[nodiscard]] Type* ArenaPushStruct(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
{
return static_cast<Type*>(
ArenaPush(arena, sizeof(Type) * 1, AlignOf(Type),
true JULIET_DEBUG_PARAM(
[&]() -> const char*
{ {
if constexpr (sizeof...(DebugArgs) > 0) return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
{ }
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str; return GetTypeName<Type>();
} }())));
return GetTypeName<Type>(); }
}())));
}
template <typename Type, bool shouldZero = true JULIET_DEBUG_ONLY(, typename... DebugArgs)> template <typename Type, bool shouldZero = true JULIET_DEBUG_ONLY(, typename... DebugArgs)>
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs)) [[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
{ {
return static_cast<Type*>( return static_cast<Type*>(
ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)), ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)),
shouldZero JULIET_DEBUG_PARAM( shouldZero JULIET_DEBUG_PARAM(
[&]() -> const char* [&]() -> const char*
{
if constexpr (sizeof...(DebugArgs) > 0)
{ {
if constexpr (sizeof...(DebugArgs) > 0) return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str;
{ }
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Str; return GetTypeName<Type>();
} }())));
return GetTypeName<Type>(); }
}())));
}
TempArena ArenaTempBegin(NonNullPtr<Arena> arena); TempArena ArenaTempBegin(NonNullPtr<Arena> arena);
void ArenaTempEnd(TempArena temp); void ArenaTempEnd(TempArena temp);
} // namespace Juliet
+33 -36
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
@@ -7,46 +7,43 @@
#if JULIET_DEBUG #if JULIET_DEBUG
namespace Juliet struct Arena;
struct MemoryBlock;
// Arena (Struct)
struct ArenaDebugInfo
{ {
struct Arena; const char* Tag;
struct MemoryBlock; size_t Offset;
size_t Size;
ArenaDebugInfo* Next;
};
// Arena (Struct) // MemoryArena (Pool-based)
struct ArenaDebugInfo struct ArenaAllocation
{ {
const char* Tag; size_t Offset;
size_t Offset; size_t Size;
size_t Size; String Tag;
ArenaDebugInfo* Next; ArenaAllocation* Next;
}; };
// MemoryArena (Pool-based) // Arena (Struct)
struct ArenaAllocation void DebugRegisterArena(NonNullPtr<Arena> arena);
{ void DebugUnregisterArena(NonNullPtr<Arena> arena);
size_t Offset; void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name);
size_t Size; bool IsDebugInfoArena(const Arena* arena); // To prevent recursion
String Tag; void DebugArenaFreeBlock(Arena* block); // To clear all debug infos in a block
ArenaAllocation* Next; void DebugArenaRemoveAllocation(Arena* block, size_t oldOffset);
}; void DebugArenaPopTo(Arena* block, size_t newPosition);
void DebugArenaAddDebugInfo(Arena* block, size_t size, size_t offset, const char* tag);
// Arena (Struct) // MemoryArena (Pool-based)
void DebugRegisterArena(NonNullPtr<Arena> arena); void DebugFreeArenaAllocations(MemoryBlock* blk);
void DebugUnregisterArena(NonNullPtr<Arena> arena); void DebugArenaAddAllocation(MemoryBlock* blk, size_t size, size_t offset, String tag);
void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name); void DebugArenaRemoveLastAllocation(MemoryBlock* blk);
bool IsDebugInfoArena(const Arena* arena); // To prevent recursion
void DebugArenaFreeBlock(Arena* block); // To clear all debug infos in a block
void DebugArenaRemoveAllocation(Arena* block, size_t oldOffset);
void DebugArenaPopTo(Arena* block, size_t newPosition);
void DebugArenaAddDebugInfo(Arena* block, size_t size, size_t offset, const char* tag);
// MemoryArena (Pool-based) JULIET_API Arena* GetDebugInfoArena();
void DebugFreeArenaAllocations(MemoryBlock* blk);
void DebugArenaAddAllocation(MemoryBlock* blk, size_t size, size_t offset, String tag);
void DebugArenaRemoveLastAllocation(MemoryBlock* blk);
JULIET_API Arena* GetDebugInfoArena();
} // namespace Juliet
#endif #endif
+57 -60
View File
@@ -1,78 +1,75 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#define ArraySize(array) (sizeof(array) / sizeof(array[0])) #define ArraySize(array) (sizeof(array) / sizeof(array[0]))
namespace Juliet inline int32 MemCompare(const void* leftValue, const void* rightValue, size_t size)
{ {
inline int32 MemCompare(const void* leftValue, const void* rightValue, size_t size) auto left = static_cast<const unsigned char*>(leftValue);
auto right = static_cast<const unsigned char*>(rightValue);
while (size && *left == *right)
{ {
auto left = static_cast<const unsigned char*>(leftValue); ++left;
auto right = static_cast<const unsigned char*>(rightValue); ++right;
while (size && *left == *right) --size;
{ }
++left; return size ? *left - *right : 0;
++right; }
--size;
} // Single linked list
return size ? *left - *right : 0; void SingleLinkedListPushNext(auto*& stackTop, auto* node)
{
node->Next = stackTop;
stackTop = node;
}
void SingleLinkedListPushPrevious(auto*& stackTop, auto* node)
{
node->Previous = stackTop;
stackTop = node;
}
void SingleLinkedListPopNext(auto*& stackTop)
{
stackTop = stackTop->Next;
}
// Double linked list
template <typename QueueType, typename QueueTypeNode>
void Enqueue(QueueType& queue, QueueTypeNode* node)
{
if (queue.First == nullptr)
{
queue.First = queue.Last = node;
node->Next = nullptr;
}
else
{
queue.Last->Next = node, queue.Last = node;
node->Next = nullptr;
} }
// Single linked list queue.Nodecount += 1;
void SingleLinkedListPushNext(auto*& stackTop, auto* node) }
{
node->Next = stackTop;
stackTop = node;
}
void SingleLinkedListPushPrevious(auto*& stackTop, auto* node) template <typename QueueType>
{ struct QueueNode
node->Previous = stackTop; {
stackTop = node; QueueType* Next;
} };
void SingleLinkedListPopNext(auto*& stackTop)
{
stackTop = stackTop->Next;
}
// Double linked list
template <typename QueueType, typename QueueTypeNode>
void Enqueue(QueueType& queue, QueueTypeNode* node)
{
if (queue.First == nullptr)
{
queue.First = queue.Last = node;
node->Next = nullptr;
}
else
{
queue.Last->Next = node, queue.Last = node;
node->Next = nullptr;
}
queue.Nodecount += 1;
}
template <typename QueueType>
struct QueueNode
{
QueueType* Next;
};
#define DECLARE_QUEUE(type) \ #define DECLARE_QUEUE(type) \
struct type##Queue \ struct type##Queue \
{ \ { \
type* First; \ type* First; \
type* Last; \ type* Last; \
size_t Nodecount; \ size_t Nodecount; \
size_t Size; \ size_t Size; \
}; };
// TODO: homemade versions // TODO: homemade versions
#define MemSet memset #define MemSet memset
#define MemCopy memcpy #define MemCopy memcpy
#define MemoryZero(dst, size) MemSet(dst, 0, size) #define MemoryZero(dst, size) MemSet(dst, 0, size)
} // namespace Juliet
+5 -8
View File
@@ -1,11 +1,8 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
namespace Juliet // TODO : Do something better.
{ constexpr uint32 kLocalhost = (127 << 3) | (0 << 2) | (0 << 1) | 1;
// TODO : Do something better. constexpr uint32 kAnyIp = 0;
constexpr uint32 kLocalhost = (127 << 3) | (0 << 2) | (0 << 1) | 1; constexpr uint32 kBroadcastIp = (255 << 3) | (255 << 2) | (255 << 1) | 255;
constexpr uint32 kAnyIp = 0;
constexpr uint32 kBroadcastIp = (255 << 3) | (255 << 2) | (255 << 1) | 255;
} // namespace Juliet
+22 -25
View File
@@ -1,36 +1,33 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
namespace Juliet class NetworkPacket
{ {
class NetworkPacket public:
{ NetworkPacket();
public: NetworkPacket(Arena& arena);
NetworkPacket(); virtual ~NetworkPacket();
NetworkPacket(Arena& arena); NetworkPacket(NetworkPacket&);
virtual ~NetworkPacket(); NetworkPacket& operator=(const NetworkPacket&);
NetworkPacket(NetworkPacket&); NetworkPacket(NetworkPacket&&) noexcept;
NetworkPacket& operator=(const NetworkPacket&); NetworkPacket& operator=(NetworkPacket&&) noexcept;
NetworkPacket(NetworkPacket&&) noexcept;
NetworkPacket& operator=(NetworkPacket&&) noexcept;
void Create(Arena& arena); void Create(Arena& arena);
[[nodiscard]] ByteBuffer GetRawData(); [[nodiscard]] ByteBuffer GetRawData();
// Pack // Pack
NetworkPacket& operator<<(uint32 value); NetworkPacket& operator<<(uint32 value);
NetworkPacket& operator<<(char* data); NetworkPacket& operator<<(char* data);
protected: protected:
void Append(ByteBuffer buffer); void Append(ByteBuffer buffer);
friend class TcpSocket; friend class TcpSocket;
private: private:
VectorArena<Byte, 4096> Data; VectorArena<Byte, 4096> Data;
size_t PartialSendIndex = 0; size_t PartialSendIndex = 0;
}; };
} // namespace Juliet
+47 -50
View File
@@ -1,56 +1,53 @@
#pragma once #pragma once
#include <Core/Networking/SocketHandle.h> #include <Core/Networking/SocketHandle.h>
namespace Juliet class Socket
{ {
class Socket public:
virtual ~Socket();
Socket(Socket&& other) noexcept;
Socket& operator=(Socket&& socket) noexcept;
Socket(const Socket&) = delete;
Socket& operator=(const Socket&) = delete;
bool IsValid() const;
enum class Status : uint8
{ {
public: Done,
virtual ~Socket(); Partial,
Ready,
Socket(Socket&& other) noexcept; NotReady,
Socket& operator=(Socket&& socket) noexcept; Disconnected,
Error
Socket(const Socket&) = delete;
Socket& operator=(const Socket&) = delete;
bool IsValid() const;
enum class Status : uint8
{
Done,
Partial,
Ready,
NotReady,
Disconnected,
Error
};
protected:
enum class Protocol : uint8
{
TCP,
UDP
};
// To store the result of a send/receive on the socket
struct RequestStatus
{
Status Status = Status::Done;
size_t Length = 0;
};
explicit Socket(Protocol protocol);
SocketHandle GetHandle() const { return Handle; }
void Create();
void CreateFromHandle(SocketHandle handle);
void Close();
private:
SocketHandle Handle;
Protocol ProtocolType;
}; };
} // namespace Juliet
protected:
enum class Protocol : uint8
{
TCP,
UDP
};
// To store the result of a send/receive on the socket
struct RequestStatus
{
Status Status = Status::Done;
size_t Length = 0;
};
explicit Socket(Protocol protocol);
SocketHandle GetHandle() const { return Handle; }
void Create();
void CreateFromHandle(SocketHandle handle);
void Close();
private:
SocketHandle Handle;
Protocol ProtocolType;
};
@@ -1,14 +1,11 @@
#pragma once #pragma once
#if JULIET_WIN32 #if JULIET_WIN32
#include <basetsd.h> #include <basetsd.h>
#endif #endif
namespace Juliet
{
#if JULIET_WIN32 #if JULIET_WIN32
using SocketHandle = UINT_PTR; using SocketHandle = UINT_PTR;
#else #else
using SocketHandle = int; using SocketHandle = int;
#endif #endif
} // namespace Juliet
+10 -13
View File
@@ -1,21 +1,18 @@
#pragma once #pragma once
#include <Core/Networking/IPAddress.h> #include <Core/Networking/IPAddress.h>
#include <Core/Networking/Socket.h> #include <Core/Networking/Socket.h>
#include <Core/Networking/TcpSocket.h> #include <Core/Networking/TcpSocket.h>
namespace Juliet class TcpListener : public Socket
{ {
class TcpListener : public Socket public:
{ TcpListener();
public:
TcpListener();
TcpListener(const TcpListener&) = delete; TcpListener(const TcpListener&) = delete;
TcpListener& operator=(const TcpListener&) = delete; TcpListener& operator=(const TcpListener&) = delete;
Status Listen(uint16 port, uint32 address = kAnyIp); Status Listen(uint16 port, uint32 address = kAnyIp);
Status Accept(TcpSocket& socket); Status Accept(TcpSocket& socket);
void Close(); void Close();
}; };
} // namespace Juliet
+14 -17
View File
@@ -1,24 +1,21 @@
#pragma once #pragma once
#include <Core/Networking/Socket.h> #include <Core/Networking/Socket.h>
namespace Juliet class NetworkPacket;
class TcpSocket : public Socket
{ {
class NetworkPacket; public:
TcpSocket();
class TcpSocket : public Socket TcpSocket(const TcpSocket&) = delete;
{ TcpSocket& operator=(const TcpSocket&) = delete;
public:
TcpSocket();
TcpSocket(const TcpSocket&) = delete; RequestStatus Send(NetworkPacket& packet);
TcpSocket& operator=(const TcpSocket&) = delete; RequestStatus Send(ByteBuffer buffer);
Status Receive(NetworkPacket& outPacket);
RequestStatus Send(NetworkPacket& packet); private:
RequestStatus Send(ByteBuffer buffer); friend class TcpListener;
Status Receive(NetworkPacket& outPacket); };
private:
friend class TcpListener;
};
} // namespace Juliet
+1 -1
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <bit> #include <bit>
+3 -6
View File
@@ -1,7 +1,4 @@
#pragma once #pragma once
namespace Juliet using Mutex = std::mutex;
{ using LockGuard = std::lock_guard<Mutex>;
using Mutex = std::mutex;
using LockGuard = std::lock_guard<Mutex>;
} // namespace Juliet
+10 -13
View File
@@ -1,19 +1,16 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
namespace Juliet uint32 thread_id();
void set_thread_name(String name);
// TODO : Proper wait
inline void wait_ms(int milliseconds)
{ {
uint32 thread_id(); clock_t start_time = clock();
while (clock() < start_time + milliseconds)
void set_thread_name(String name);
// TODO : Proper wait
inline void wait_ms(int milliseconds)
{ {
clock_t start_time = clock();
while (clock() < start_time + milliseconds)
{
}
} }
} // namespace Juliet }
+13 -16
View File
@@ -1,24 +1,21 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
namespace Juliet struct thread_context
{ {
struct thread_context Arena* ScratchArenas[2];
{
Arena* ScratchArenas[2];
char ThreadName[64]; char ThreadName[64];
uint8 ThreadNameSize; uint8 ThreadNameSize;
}; };
thread_context* thread_context_alloc(); thread_context* thread_context_alloc();
void thread_context_release(NonNullPtr<thread_context> ctx); void thread_context_release(NonNullPtr<thread_context> ctx);
void thread_context_select(NonNullPtr<thread_context> ctx); void thread_context_select(NonNullPtr<thread_context> ctx);
thread_context* thread_context_current(); thread_context* thread_context_current();
Arena* thread_context_get_scratch(Arena** conflicts, size_t count); Arena* thread_context_get_scratch(Arena** conflicts, size_t count);
TempArena scratch_begin(Arena** conflicts, size_t count); TempArena scratch_begin(Arena** conflicts, size_t count);
void scratch_end(TempArena scratch); void scratch_end(TempArena scratch);
} // namespace Juliet
+2 -5
View File
@@ -1,9 +1,6 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Graphics/MeshRenderer.h> #include <Graphics/MeshRenderer.h>
namespace Juliet JULIET_API extern MeshAssetID LoadMesh(String filename);
{
JULIET_API extern MeshAssetID LoadMesh(String filename);
}
+20 -23
View File
@@ -1,33 +1,30 @@
#pragma once #pragma once
#include <Core/Common/CRC32.h> #include <Core/Common/CRC32.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet struct Class
{ {
struct Class uint32 CRC;
#if JULIET_DEBUG
// TODO: string struct may be
const char* Name;
size_t Name_Length;
#endif
consteval Class(const char* className, size_t name_length)
{ {
uint32 CRC; CRC = crc32(className, name_length);
#if JULIET_DEBUG #if JULIET_DEBUG
// TODO: string struct may be // TODO: string struct may be
const char* Name; Name = className;
size_t Name_Length; Name_Length = name_length;
#endif #endif
consteval Class(const char* className, size_t name_length)
{
CRC = crc32(className, name_length);
#if JULIET_DEBUG
// TODO: string struct may be
Name = className;
Name_Length = name_length;
#endif
}
};
template <typename type>
bool IsA(Class& cls)
{
return cls.CRC == type::StaticClass->CRC;
} }
} // namespace Juliet };
template <typename type>
bool IsA(Class& cls)
{
return cls.CRC == type::StaticClass->CRC;
}
+3 -3
View File
@@ -1,12 +1,12 @@
#pragma once #pragma once
#include <Juliet.h> #include <Juliet.h>
#if JULIET_DEBUG #if JULIET_DEBUG
namespace Juliet::Debug namespace Debug
{ {
JULIET_API void DebugDrawMemoryArena(); JULIET_API void DebugDrawMemoryArena();
} // namespace Juliet::Debug } // namespace Debug
#endif #endif
+14 -17
View File
@@ -1,25 +1,22 @@
#pragma once #pragma once
#include <Core/Application/IApplication.h> #include <Core/Application/IApplication.h>
namespace Juliet enum class JulietInit_Flags : uint8;
struct Engine
{ {
enum class JulietInit_Flags : uint8; IApplication* Application = nullptr;
Arena* PlatformArena = nullptr;
Arena* AssetArena = nullptr;
};
struct Engine void InitializeEngine(JulietInit_Flags flags);
{ void ShutdownEngine();
IApplication* Application = nullptr;
Arena* PlatformArena = nullptr;
Arena* AssetArena = nullptr;
};
void InitializeEngine(JulietInit_Flags flags); void LoadApplication(IApplication& app);
void ShutdownEngine(); void UnloadApplication();
void LoadApplication(IApplication& app); void RunEngine();
void UnloadApplication();
void RunEngine(); extern Arena* GetPlatformArena();
extern Arena* GetPlatformArena();
} // namespace Juliet
+26 -29
View File
@@ -1,38 +1,35 @@
#pragma once #pragma once
#include <Core/Math/Matrix.h> #include <Core/Math/Matrix.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet struct Camera
{ {
struct Camera index_t Index;
{ Vector3 Position;
index_t Index; Vector3 Target;
Vector3 Position; Vector3 Up;
Vector3 Target; float FOV; // In radians
Vector3 Up; float AspectRatio;
float FOV; // In radians float NearPlane;
float AspectRatio; float FarPlane;
float NearPlane; };
float FarPlane;
};
inline Matrix Camera_GetViewMatrix(const Camera& cam) inline Matrix Camera_GetViewMatrix(const Camera& cam)
{ {
return LookAt(cam.Position, cam.Target, cam.Up); return LookAt(cam.Position, cam.Target, cam.Up);
} }
inline Matrix Camera_GetProjectionMatrix(const Camera& cam) inline Matrix Camera_GetProjectionMatrix(const Camera& cam)
{ {
return PerspectiveFov(cam.FOV, cam.AspectRatio, cam.NearPlane, cam.FarPlane); return PerspectiveFov(cam.FOV, cam.AspectRatio, cam.NearPlane, cam.FarPlane);
} }
inline Matrix Camera_GetViewProjectionMatrix(const Camera& cam) inline Matrix Camera_GetViewProjectionMatrix(const Camera& cam)
{ {
return Camera_GetProjectionMatrix(cam) * Camera_GetViewMatrix(cam); return Camera_GetProjectionMatrix(cam) * Camera_GetViewMatrix(cam);
} }
JULIET_API extern void ReserveCamera(size_t amount); JULIET_API extern void ReserveCamera(size_t amount);
JULIET_API extern Camera* GetCurrentCamera(); JULIET_API extern Camera* GetCurrentCamera();
JULIET_API extern void SetCurrentCamera(index_t index); JULIET_API extern void SetCurrentCamera(index_t index);
} // namespace Juliet
+10 -13
View File
@@ -1,16 +1,13 @@
#pragma once #pragma once
namespace Juliet template <typename Type>
struct ColorType
{ {
template <typename Type> Type R;
struct ColorType Type G;
{ Type B;
Type R; Type A;
Type G; };
Type B;
Type A;
};
using FColor = ColorType<float>; using FColor = ColorType<float>;
using Color = ColorType<uint8>; using Color = ColorType<uint8>;
} // namespace Juliet
+7 -10
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Math/Vector.h> #include <Core/Math/Vector.h>
#include <Graphics/Camera.h> #include <Graphics/Camera.h>
@@ -6,12 +6,9 @@
#include <Graphics/Graphics.h> #include <Graphics/Graphics.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet extern JULIET_API void DebugDisplay_Initialize(NonNullPtr<Arena> arena, GraphicsDevice* device);
{ extern JULIET_API void DebugDisplay_Shutdown(GraphicsDevice* device);
extern JULIET_API void DebugDisplay_Initialize(NonNullPtr<Arena> arena, GraphicsDevice* device); extern JULIET_API void DebugDisplay_DrawLine(const Vector3& start, const Vector3& end, const FColor& color, bool overlay);
extern JULIET_API void DebugDisplay_Shutdown(GraphicsDevice* device); extern JULIET_API void DebugDisplay_DrawSphere(const Vector3& center, float radius, const FColor& color, bool overlay);
extern JULIET_API void DebugDisplay_DrawLine(const Vector3& start, const Vector3& end, const FColor& color, bool overlay); extern JULIET_API void DebugDisplay_Prepare(CommandList* cmdList);
extern JULIET_API void DebugDisplay_DrawSphere(const Vector3& center, float radius, const FColor& color, bool overlay); extern JULIET_API void DebugDisplay_Flush(CommandList* cmdList, RenderPass* renderPass, const Camera& camera);
extern JULIET_API void DebugDisplay_Prepare(CommandList* cmdList);
extern JULIET_API void DebugDisplay_Flush(CommandList* cmdList, RenderPass* renderPass, const Camera& camera);
} // namespace Juliet
+134 -137
View File
@@ -12,166 +12,163 @@
#include <Juliet.h> #include <Juliet.h>
// Graphics Interface // Graphics Interface
namespace Juliet // Opaque types
struct CommandList;
struct GraphicsDevice;
struct Fence;
// Parameters of an indirect draw command
struct IndirectDrawCommand
{ {
// Opaque types uint32 VertexCount; // Number of vertices to draw
struct CommandList; uint32 InstanceCount; // Number of instanced to draw
struct GraphicsDevice; uint32 FirstVertex; // Index of the first vertex to draw
struct Fence; uint32 FirstInstance; // ID of the first instance to draw
};
// Parameters of an indirect draw command // Parameters of an INDEXED indirect draw command
struct IndirectDrawCommand struct IndexedIndirectDrawCommand
{ {
uint32 VertexCount; // Number of vertices to draw uint32 VertexCount; // Number of vertices to draw
uint32 InstanceCount; // Number of instanced to draw uint32 InstanceCount; // Number of instanced to draw
uint32 FirstVertex; // Index of the first vertex to draw uint32 FirstIndex; // Base Index within the index buffer
uint32 FirstInstance; // ID of the first instance to draw int32 VertexOffset; // Offset the vertex index into the buffer
}; uint32 FirstInstance; // ID of the first instance to draw
};
// Parameters of an INDEXED indirect draw command // Parameters of an INDEXED Indirect Dispatch Command
struct IndexedIndirectDrawCommand struct IndirectDispatchCommand
{ {
uint32 VertexCount; // Number of vertices to draw uint32 X_WorkGroupCount; // Number of Workgroup to dispatch on dimension X
uint32 InstanceCount; // Number of instanced to draw uint32 Y_WorkGroupCount; // Number of Workgroup to dispatch on dimension Y
uint32 FirstIndex; // Base Index within the index buffer uint32 Z_WorkGroupCount; // Number of Workgroup to dispatch on dimension Z
int32 VertexOffset; // Offset the vertex index into the buffer };
uint32 FirstInstance; // ID of the first instance to draw
};
// Parameters of an INDEXED Indirect Dispatch Command enum class QueueType : uint8
struct IndirectDispatchCommand {
{ Graphics = 0,
uint32 X_WorkGroupCount; // Number of Workgroup to dispatch on dimension X Compute,
uint32 Y_WorkGroupCount; // Number of Workgroup to dispatch on dimension Y Copy,
uint32 Z_WorkGroupCount; // Number of Workgroup to dispatch on dimension Z Count
}; };
enum class QueueType : uint8 enum class IndexFormat : uint8
{ {
Graphics = 0, UInt16,
Compute, UInt32
Copy, };
Count
};
enum class IndexFormat : uint8 enum struct SwapChainComposition : uint8
{ {
UInt16, SDR,
UInt32 SDR_LINEAR,
}; HDR_EXTENDED_LINEAR,
HDR10_ST2084
};
enum struct SwapChainComposition : uint8 // PresentMode from highest to lowest latency
{ // Vsync prevents tearing. Enqueue ready images.
SDR, // Mailbox prevents tearing. When image is ready, replace any pending image
SDR_LINEAR, // Immediate replace current image as soon as possible. Can cause tearing
HDR_EXTENDED_LINEAR, enum struct PresentMode : uint8
HDR10_ST2084 {
}; VSync,
Mailbox,
Immediate
};
// PresentMode from highest to lowest latency struct GraphicsViewPort
// Vsync prevents tearing. Enqueue ready images. {
// Mailbox prevents tearing. When image is ready, replace any pending image float X;
// Immediate replace current image as soon as possible. Can cause tearing float Y;
enum struct PresentMode : uint8 float Width;
{ float Height;
VSync, float MinDepth;
Mailbox, float MaxDepth;
Immediate };
};
struct GraphicsViewPort extern JULIET_API GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config);
{ extern JULIET_API void DestroyGraphicsDevice(NonNullPtr<GraphicsDevice> device);
float X;
float Y;
float Width;
float Height;
float MinDepth;
float MaxDepth;
};
extern JULIET_API GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config); // Attach To Window
extern JULIET_API void DestroyGraphicsDevice(NonNullPtr<GraphicsDevice> device); extern JULIET_API bool AttachToWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
extern JULIET_API void DetachFromWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
// Attach To Window // SwapChain
extern JULIET_API bool AttachToWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window); extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window,
extern JULIET_API void DetachFromWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window); Texture** swapChainTexture);
extern JULIET_API bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList,
NonNullPtr<Window> window, Texture** swapChainTexture);
extern JULIET_API bool WaitForSwapchain(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
extern JULIET_API TextureFormat GetSwapChainTextureFormat(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
// SwapChain // Textures
extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, extern JULIET_API Texture* CreateTexture(NonNullPtr<GraphicsDevice> device, const TextureCreateInfo& createInfo);
Texture** swapChainTexture); extern JULIET_API void DestroyTexture(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture);
extern JULIET_API bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList,
NonNullPtr<Window> window, Texture** swapChainTexture);
extern JULIET_API bool WaitForSwapchain(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
extern JULIET_API TextureFormat GetSwapChainTextureFormat(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
// Textures // Command List
extern JULIET_API Texture* CreateTexture(NonNullPtr<GraphicsDevice> device, const TextureCreateInfo& createInfo); extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics);
extern JULIET_API void DestroyTexture(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture); extern JULIET_API void SubmitCommandLists(NonNullPtr<CommandList> commandList);
// Command List // RenderPass
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics); extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, ColorTargetInfo& colorTargetInfo,
extern JULIET_API void SubmitCommandLists(NonNullPtr<CommandList> commandList); DepthStencilTargetInfo* depthStencilTargetInfo = nullptr);
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList,
NonNullPtr<const ColorTargetInfo> colorTargetInfos, uint32 colorTargetInfoCount,
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr);
extern JULIET_API void EndRenderPass(NonNullPtr<RenderPass> renderPass);
// RenderPass extern JULIET_API void SetGraphicsViewPort(NonNullPtr<RenderPass> renderPass, const GraphicsViewPort& viewPort);
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, ColorTargetInfo& colorTargetInfo, extern JULIET_API void SetScissorRect(NonNullPtr<RenderPass> renderPass, const struct Rectangle& rectangle);
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr); extern JULIET_API void SetBlendConstants(NonNullPtr<RenderPass> renderPass, FColor blendConstants);
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, extern JULIET_API void SetStencilReference(NonNullPtr<RenderPass> renderPass, uint8 reference);
NonNullPtr<const ColorTargetInfo> colorTargetInfos, uint32 colorTargetInfoCount,
DepthStencilTargetInfo* depthStencilTargetInfo = nullptr);
extern JULIET_API void EndRenderPass(NonNullPtr<RenderPass> renderPass);
extern JULIET_API void SetGraphicsViewPort(NonNullPtr<RenderPass> renderPass, const GraphicsViewPort& viewPort); extern JULIET_API void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline);
extern JULIET_API void SetScissorRect(NonNullPtr<RenderPass> renderPass, const Rectangle& rectangle); extern JULIET_API void DrawPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numVertices, uint32 numInstances,
extern JULIET_API void SetBlendConstants(NonNullPtr<RenderPass> renderPass, FColor blendConstants); uint32 firstVertex, uint32 firstInstance);
extern JULIET_API void SetStencilReference(NonNullPtr<RenderPass> renderPass, uint8 reference); extern JULIET_API void DrawIndexedPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numIndices, uint32 numInstances,
uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance);
extern JULIET_API void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline); extern JULIET_API void SetIndexBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer,
extern JULIET_API void DrawPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numVertices, uint32 numInstances, IndexFormat format, size_t indexCount, index_t offset);
uint32 firstVertex, uint32 firstInstance);
extern JULIET_API void DrawIndexedPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numIndices, uint32 numInstances,
uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance);
extern JULIET_API void SetIndexBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer, extern JULIET_API void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage,
IndexFormat format, size_t indexCount, index_t offset); uint32 rootParameterIndex, uint32 numConstants, const void* constants);
extern JULIET_API void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage, // Fences
uint32 rootParameterIndex, uint32 numConstants, const void* constants); extern JULIET_API bool WaitUntilGPUIsIdle(NonNullPtr<GraphicsDevice> device);
// Fences // Shaders
extern JULIET_API bool WaitUntilGPUIsIdle(NonNullPtr<GraphicsDevice> device); extern JULIET_API Shader* CreateShader(NonNullPtr<GraphicsDevice> device, String filename, ShaderCreateInfo& shaderCreateInfo);
extern JULIET_API void DestroyShader(NonNullPtr<GraphicsDevice> device, NonNullPtr<Shader> shader);
// Shaders // Pipelines
extern JULIET_API Shader* CreateShader(NonNullPtr<GraphicsDevice> device, String filename, ShaderCreateInfo& shaderCreateInfo); extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device,
extern JULIET_API void DestroyShader(NonNullPtr<GraphicsDevice> device, NonNullPtr<Shader> shader); const GraphicsPipelineCreateInfo& createInfo);
extern JULIET_API void DestroyGraphicsPipeline(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline);
// Pipelines
extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device,
const GraphicsPipelineCreateInfo& createInfo);
extern JULIET_API void DestroyGraphicsPipeline(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline);
#if ALLOW_SHADER_HOT_RELOAD #if ALLOW_SHADER_HOT_RELOAD
// Allows updating the graphics pipeline shaders. Can update either one or both shaders. // Allows updating the graphics pipeline shaders. Can update either one or both shaders.
extern JULIET_API bool UpdateGraphicsPipelineShaders(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline, extern JULIET_API bool UpdateGraphicsPipelineShaders(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline,
Shader* optional_vertexShader, Shader* optional_fragmentShader); Shader* optional_vertexShader, Shader* optional_fragmentShader);
#endif #endif
// Buffers // Buffers
extern JULIET_API GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GraphicsDevice> device, const BufferCreateInfo& createInfo); extern JULIET_API GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GraphicsDevice> device, const BufferCreateInfo& createInfo);
extern JULIET_API GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, extern JULIET_API GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device,
const TransferBufferCreateInfo& createInfo); const TransferBufferCreateInfo& createInfo);
extern JULIET_API void* MapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API void* MapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
extern JULIET_API void UnmapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API void UnmapGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
extern JULIET_API void* MapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer); extern JULIET_API void* MapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
extern JULIET_API void UnmapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer); extern JULIET_API void UnmapGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
extern JULIET_API void CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst, extern JULIET_API void CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset = 0, NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset = 0,
size_t srcOffset = 0); size_t srcOffset = 0);
extern JULIET_API void CopyBufferToTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Texture> dst, extern JULIET_API void CopyBufferToTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Texture> dst,
NonNullPtr<GraphicsTransferBuffer> src); NonNullPtr<GraphicsTransferBuffer> src);
extern JULIET_API void TransitionBufferToReadable(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API void TransitionBufferToReadable(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer);
extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture); extern JULIET_API uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture);
extern JULIET_API void DestroyGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer); extern JULIET_API void DestroyGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
extern JULIET_API void DestroyGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer); extern JULIET_API void DestroyGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsTransferBuffer> buffer);
} // namespace Juliet
+27 -30
View File
@@ -1,36 +1,33 @@
#pragma once #pragma once
namespace Juliet enum class BufferUsage : uint8
{ {
enum class BufferUsage : uint8 None = 0,
{ IndexBuffer = 1 << 0,
None = 0, ConstantBuffer = 1 << 1,
IndexBuffer = 1 << 0, StructuredBuffer = 1 << 2,
ConstantBuffer = 1 << 1, };
StructuredBuffer = 1 << 2,
};
enum class TransferBufferUsage : uint8 enum class TransferBufferUsage : uint8
{ {
Download, Download,
Upload Upload
}; };
struct BufferCreateInfo struct BufferCreateInfo
{ {
size_t Size; size_t Size;
size_t Stride; size_t Stride;
BufferUsage Usage; BufferUsage Usage;
bool IsDynamic; bool IsDynamic;
}; };
struct TransferBufferCreateInfo struct TransferBufferCreateInfo
{ {
size_t Size; size_t Size;
TransferBufferUsage Usage; TransferBufferUsage Usage;
}; };
// Opaque // Opaque
struct GraphicsBuffer; struct GraphicsBuffer;
struct GraphicsTransferBuffer; struct GraphicsTransferBuffer;
} // namespace Juliet
+9 -12
View File
@@ -10,17 +10,14 @@
#define ALLOW_SHADER_HOT_RELOAD 0 #define ALLOW_SHADER_HOT_RELOAD 0
#endif #endif
namespace Juliet enum class GraphicsDriverType : uint8
{ {
enum class DriverType : uint8 Any = 0,
{ DX12 = 1,
Any = 0, };
DX12 = 1,
};
struct GraphicsConfig struct GraphicsConfig
{ {
DriverType PreferredDriver = DriverType::DX12; GraphicsDriverType PreferredDriver = GraphicsDriverType::DX12;
bool EnableDebug; bool EnableDebug;
}; };
} // namespace Juliet
+187 -190
View File
@@ -1,225 +1,222 @@
#pragma once #pragma once
#include <Graphics/Shader.h> #include <Graphics/Shader.h>
#include <Graphics/Texture.h> #include <Graphics/Texture.h>
namespace Juliet // Forward Declare
struct ColorTargetDescription;
enum class FillMode : uint8
{ {
// Forward Declare Solid,
struct ColorTargetDescription; Wireframe,
Count
};
enum class FillMode : uint8 enum class CullMode : uint8
{ {
Solid, None,
Wireframe, Front,
Count Back,
}; Count
};
enum class CullMode : uint8 enum class FrontFace : uint8
{ {
None, CounterClockwise,
Front, Clockwise,
Back, Count
Count };
};
enum class FrontFace : uint8 enum class PrimitiveType : uint8
{ {
CounterClockwise, TriangleList,
Clockwise, TriangleStrip,
Count LineList,
}; LineStrip,
PointList,
Count
};
enum class PrimitiveType : uint8 struct RasterizerState
{ {
TriangleList, FillMode FillMode;
TriangleStrip, CullMode CullMode;
LineList, FrontFace FrontFace;
LineStrip,
PointList,
Count
};
struct RasterizerState float DepthBiasConstantFactor; // How much depth value is added to each fragment
{ float DepthBiasClamp; // Maximum depth bias
FillMode FillMode; float DepthBiasSlopeFactor; // Scalar applied to Fragment's slope
CullMode CullMode; bool EnableDepthBias; // Bias fragment depth values
FrontFace FrontFace; bool EnableDepthClip; // True to clip, false to clamp
};
float DepthBiasConstantFactor; // How much depth value is added to each fragment enum class VertexInputRate : uint8
float DepthBiasClamp; // Maximum depth bias {
float DepthBiasSlopeFactor; // Scalar applied to Fragment's slope Vertex, // Use vertex index
bool EnableDepthBias; // Bias fragment depth values Instance, // Use instance index
bool EnableDepthClip; // True to clip, false to clamp Count
}; };
enum class VertexInputRate : uint8 struct VertexBufferDescription
{ {
Vertex, // Use vertex index uint32 Slot; // Binding Slot
Instance, // Use instance index uint32 PitchInBytes; // Pitch between two elements
Count VertexInputRate InputRate;
}; uint32 InstanceStepRate; // Only used when input rate == Instance. Number of instances to draw before advancing in the instance buffer by 1
};
struct VertexBufferDescription enum class VertexElementFormat : uint8
{ {
uint32 Slot; // Binding Slot Invalid,
uint32 PitchInBytes; // Pitch between two elements
VertexInputRate InputRate;
uint32 InstanceStepRate; // Only used when input rate == Instance. Number of instances to draw before advancing in the instance buffer by 1
};
enum class VertexElementFormat : uint8 /* 32-bit Signed Integers */
{ Int,
Invalid, Int2,
Int3,
Int4,
/* 32-bit Signed Integers */ /* 32-bit Unsigned Integers */
Int, UInt,
Int2, UInt2,
Int3, UInt3,
Int4, UInt4,
/* 32-bit Unsigned Integers */ /* 32-bit Floats */
UInt, Float,
UInt2, Float2,
UInt3, Float3,
UInt4, Float4,
/* 32-bit Floats */ /* 8-bit Signed Integers */
Float, Byte2,
Float2, Byte4,
Float3,
Float4,
/* 8-bit Signed Integers */ /* 8-bit Unsigned Integers */
Byte2, UByte2,
Byte4, UByte4,
/* 8-bit Unsigned Integers */ /* 8-bit Signed Normalized */
UByte2, Byte2_Norm,
UByte4, Byte4_Norm,
/* 8-bit Signed Normalized */ /* 8-bit Unsigned Normalized */
Byte2_Norm, UByte2_Norm,
Byte4_Norm, UByte4_Norm,
/* 8-bit Unsigned Normalized */ /* 16-bit Signed Integers */
UByte2_Norm, Short2,
UByte4_Norm, Short4,
/* 16-bit Signed Integers */ /* 16-bit Unsigned Integers */
Short2, UShort2,
Short4, UShort4,
/* 16-bit Unsigned Integers */ /* 16-bit Signed Normalized */
UShort2, Short2_Norm,
UShort4, Short4_Norm,
/* 16-bit Signed Normalized */ /* 16-bit Unsigned Normalized */
Short2_Norm, UShort2_Norm,
Short4_Norm, UShort4_Norm,
/* 16-bit Unsigned Normalized */ /* 16-bit Floats */
UShort2_Norm, Half2,
UShort4_Norm, Half4,
/* 16-bit Floats */ //
Half2, Count
Half4, };
// struct VertexAttribute
Count {
}; uint32 Location; // Shader input location index
uint32 BufferSlot; // Binding slot of associated vertex buffer
VertexElementFormat Format; // Size and type of attribute
uint32 Offset; // Offset of this attribute relative to the start of the vertex element
};
struct VertexAttribute struct VertexInputState
{ {
uint32 Location; // Shader input location index const VertexBufferDescription* VertexBufferDescriptions;
uint32 BufferSlot; // Binding slot of associated vertex buffer uint32 NumVertexBufferDescriptions;
VertexElementFormat Format; // Size and type of attribute const VertexAttribute* VertexAttributes;
uint32 Offset; // Offset of this attribute relative to the start of the vertex element uint32 NumVertexAttributes;
}; };
struct VertexInputState struct GraphicsPipelineTargetInfo
{ {
const VertexBufferDescription* VertexBufferDescriptions; const ColorTargetDescription* ColorTargetDescriptions;
uint32 NumVertexBufferDescriptions; size_t NumColorTargets;
const VertexAttribute* VertexAttributes; TextureFormat DepthStencilFormat;
uint32 NumVertexAttributes; bool HasDepthStencilTarget;
}; };
struct GraphicsPipelineTargetInfo enum class CompareOperation : uint8
{ {
const ColorTargetDescription* ColorTargetDescriptions; Invalid,
size_t NumColorTargets; Never, // The comparison always evaluates false.
TextureFormat DepthStencilFormat; Less, // The comparison evaluates reference < test.
bool HasDepthStencilTarget; Equal, // The comparison evaluates reference == test.
}; LessOrEqual, // The comparison evaluates reference <= test.
Greater, // The comparison evaluates reference > test.
NotEqual, // The comparison evaluates reference != test.
GreaterOrEqual, // The comparison evalutes reference >= test.
Always, // The comparison always evaluates true.
Count
};
enum class CompareOperation : uint8 enum class StencilOperation : uint8
{ {
Invalid, Invalid,
Never, // The comparison always evaluates false. Keep, // Keeps the current value.
Less, // The comparison evaluates reference < test. Zero, // Sets the value to 0.
Equal, // The comparison evaluates reference == test. Replace, // Sets the value to reference.
LessOrEqual, // The comparison evaluates reference <= test. IncrementAndClamp, // Increments the current value and clamps to the maximum value.
Greater, // The comparison evaluates reference > test. DecrementAndClamp, // Decrements the current value and clamps to 0.
NotEqual, // The comparison evaluates reference != test. Invert, // Bitwise-inverts the current value.
GreaterOrEqual, // The comparison evalutes reference >= test. IncrementAndWrap, // Increments the current value and wraps back to 0.
Always, // The comparison always evaluates true. DecrementAndWrap, // Decrements the current value and wraps to the maximum value.
Count Count
}; };
enum class StencilOperation : uint8 struct StencilOperationState
{ {
Invalid, StencilOperation FailOperation; // The action performed on samples that fail the stencil test.
Keep, // Keeps the current value. StencilOperation PassOperation; // The action performed on samples that pass the depth and stencil tests.
Zero, // Sets the value to 0. StencilOperation DepthFailOperation; // The action performed on samples that pass the stencil test and fail the depth test.
Replace, // Sets the value to reference. StencilOperation CompareOperation; // The comparison operator used in the stencil test.
IncrementAndClamp, // Increments the current value and clamps to the maximum value. };
DecrementAndClamp, // Decrements the current value and clamps to 0.
Invert, // Bitwise-inverts the current value.
IncrementAndWrap, // Increments the current value and wraps back to 0.
DecrementAndWrap, // Decrements the current value and wraps to the maximum value.
Count
};
struct StencilOperationState struct DepthStencilState
{ {
StencilOperation FailOperation; // The action performed on samples that fail the stencil test. CompareOperation CompareOperation; // The comparison operator used for depth testing.
StencilOperation PassOperation; // The action performed on samples that pass the depth and stencil tests. StencilOperationState BackStencilState; // The stencil op state for back-facing triangles.
StencilOperation DepthFailOperation; // The action performed on samples that pass the stencil test and fail the depth test. StencilOperationState FrontStencilState; // The stencil op state for front-facing triangles.
StencilOperation CompareOperation; // The comparison operator used in the stencil test. uint8 CompareMask; // Selects the bits of the stencil values participating in the stencil test.
}; uint8 WriteMask; // Selects the bits of the stencil values updated by the stencil test.
bool EnableDepthTest : 1; // true enables the depth test.
bool EnableDepthWrite : 1; // true enables depth writes. Depth writes are always disabled when enable_depth_test is false.
bool EnableStencilTest : 1; // true enables the stencil test.
};
struct DepthStencilState struct MultisampleState
{ {
CompareOperation CompareOperation; // The comparison operator used for depth testing. TextureSampleCount SampleCount;
StencilOperationState BackStencilState; // The stencil op state for back-facing triangles. uint32 SampleMask; // Which sample should be updated. If Enabled mask == false -> 0xFFFFFFFF
StencilOperationState FrontStencilState; // The stencil op state for front-facing triangles. bool EnableMask;
uint8 CompareMask; // Selects the bits of the stencil values participating in the stencil test. };
uint8 WriteMask; // Selects the bits of the stencil values updated by the stencil test.
bool EnableDepthTest : 1; // true enables the depth test.
bool EnableDepthWrite : 1; // true enables depth writes. Depth writes are always disabled when enable_depth_test is false.
bool EnableStencilTest : 1; // true enables the stencil test.
};
struct MultisampleState struct GraphicsPipelineCreateInfo
{ {
TextureSampleCount SampleCount; Shader* VertexShader;
uint32 SampleMask; // Which sample should be updated. If Enabled mask == false -> 0xFFFFFFFF Shader* FragmentShader;
bool EnableMask; PrimitiveType PrimitiveType;
}; GraphicsPipelineTargetInfo TargetInfo;
RasterizerState RasterizerState;
MultisampleState MultisampleState;
VertexInputState VertexInputState;
DepthStencilState DepthStencilState;
};
struct GraphicsPipelineCreateInfo // Opaque type
{ struct GraphicsPipeline;
Shader* VertexShader;
Shader* FragmentShader;
PrimitiveType PrimitiveType;
GraphicsPipelineTargetInfo TargetInfo;
RasterizerState RasterizerState;
MultisampleState MultisampleState;
VertexInputState VertexInputState;
DepthStencilState DepthStencilState;
};
// Opaque type
struct GraphicsPipeline;
} // namespace Juliet
+5 -8
View File
@@ -1,12 +1,9 @@
#pragma once #pragma once
#include <Graphics/Graphics.h> #include <Graphics/Graphics.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet extern bool ImGuiRenderer_Initialize(GraphicsDevice* device);
{ extern void ImGuiRenderer_Shutdown(GraphicsDevice* device);
extern bool ImGuiRenderer_Initialize(GraphicsDevice* device); extern void ImGuiRenderer_NewFrame();
extern void ImGuiRenderer_Shutdown(GraphicsDevice* device); extern JULIET_API void ImGuiRenderer_Render(CommandList* cmdList, RenderPass* renderPass);
extern void ImGuiRenderer_NewFrame();
extern JULIET_API void ImGuiRenderer_Render(CommandList* cmdList, RenderPass* renderPass);
} // namespace Juliet
+7 -10
View File
@@ -1,15 +1,12 @@
#pragma once #pragma once
#include <Juliet.h> #include <Juliet.h>
#include <Core/Math/Vector.h> #include <Core/Math/Vector.h>
namespace Juliet struct PointLight
{ {
struct PointLight Vector3 Position;
{ float Radius;
Vector3 Position; Vector3 Color;
float Radius; float Intensity;
Vector3 Color; };
float Intensity;
};
} // namespace Juliet
+25 -28
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
@@ -7,34 +7,31 @@
#include <Core/Math/Vector.h> #include <Core/Math/Vector.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet struct Arena;
struct Vertex;
using MeshAssetID = index_t;
using MaterialAssetID = index_t;
using MeshInstanceID = index_t;
struct MeshAsset
{ {
struct Arena; String Name;
struct Vertex; size_t VertexCount;
size_t IndexCount;
using MeshAssetID = index_t; index_t VertexOffset;
using MaterialAssetID = index_t; index_t IndexOffset;
using MeshInstanceID = index_t; };
struct MeshAsset struct MaterialAsset
{ {
String Name; Vector4 AlbedoColor = {1.0f, 1.0f, 1.0f, 1.0f};
size_t VertexCount; };
size_t IndexCount;
index_t VertexOffset; struct MeshInstance
index_t IndexOffset; {
}; MeshAssetID MeshAsset;
MaterialAssetID MaterialAsset;
struct MaterialAsset Matrix Transform = MatrixIdentity();
{ };
Vector4 AlbedoColor = {1.0f, 1.0f, 1.0f, 1.0f};
};
struct MeshInstance
{
MeshAssetID MeshAsset;
MaterialAssetID MaterialAsset;
Matrix Transform = MatrixIdentity();
};
} // namespace Juliet
+38 -41
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
#include <Core/Math/Matrix.h> #include <Core/Math/Matrix.h>
@@ -9,52 +9,49 @@
#include <Graphics/Mesh.h> #include <Graphics/Mesh.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet struct GraphicsTransferBuffer;
{ struct RenderPass;
struct GraphicsTransferBuffer; struct CommandList;
struct RenderPass; struct GraphicsBuffer;
struct CommandList; struct Window;
struct GraphicsBuffer; struct GraphicsPipeline;
struct Window; struct GraphicsDevice;
struct GraphicsPipeline; using LightID = index_t;
struct GraphicsDevice;
using LightID = index_t;
constexpr size_t kGeometryPage = Megabytes(64); constexpr size_t kGeometryPage = Megabytes(64);
constexpr size_t kIndexPage = Megabytes(32); constexpr size_t kIndexPage = Megabytes(32);
constexpr size_t kDefaultMeshNumber = 500; constexpr size_t kDefaultMeshNumber = 500;
constexpr size_t kDefaultVertexCount = 2'000'000; // Fit less than one geometry page constexpr size_t kDefaultVertexCount = 2'000'000; // Fit less than one geometry page
constexpr size_t kDefaultIndexCount = 16'000'000; // Fit less than one index page constexpr size_t kDefaultIndexCount = 16'000'000; // Fit less than one index page
constexpr size_t kDefaultLightCount = 1024; constexpr size_t kDefaultLightCount = 1024;
JULIET_API void InitializeMeshRenderer(NonNullPtr<Arena> assetArena, NonNullPtr<Arena> instanceArena); JULIET_API void InitializeMeshRenderer(NonNullPtr<Arena> assetArena, NonNullPtr<Arena> instanceArena);
[[nodiscard]] JULIET_API bool InitializeMeshRendererGraphics(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window); [[nodiscard]] JULIET_API bool InitializeMeshRendererGraphics(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
JULIET_API void ShutdownMeshRendererGraphics(); JULIET_API void ShutdownMeshRendererGraphics();
JULIET_API void ShutdownMeshRenderer(); JULIET_API void ShutdownMeshRenderer();
JULIET_API void LoadMeshesOnGPU(NonNullPtr<CommandList> cmdList); JULIET_API void LoadMeshesOnGPU(NonNullPtr<CommandList> cmdList);
JULIET_API void RenderMeshes(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection); JULIET_API void RenderMeshes(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
// Lights // Lights
[[nodiscard]] JULIET_API LightID AddPointLight(const PointLight& light); [[nodiscard]] JULIET_API LightID AddPointLight(const PointLight& light);
JULIET_API void SetPointLightPosition(LightID id, const Vector3& position); JULIET_API void SetPointLightPosition(LightID id, const Vector3& position);
JULIET_API void SetPointLightColor(LightID id, const Vector3& color); JULIET_API void SetPointLightColor(LightID id, const Vector3& color);
JULIET_API void SetPointLightRadius(LightID id, float radius); JULIET_API void SetPointLightRadius(LightID id, float radius);
JULIET_API void SetPointLightIntensity(LightID id, float intensity); JULIET_API void SetPointLightIntensity(LightID id, float intensity);
JULIET_API void ClearPointLights(); JULIET_API void ClearPointLights();
JULIET_API void SetGlobalLight(const Vector3& direction, const Vector3& color, float ambientIntensity); JULIET_API void SetGlobalLight(const Vector3& direction, const Vector3& color, float ambientIntensity);
// Assets & Instances // Assets & Instances
[[nodiscard]] JULIET_API MeshAssetID GetOrCreateMeshAsset(String name); [[nodiscard]] JULIET_API MeshAssetID GetOrCreateMeshAsset(String name);
[[nodiscard]] JULIET_API MeshInstanceID CreateMeshInstance(MeshAssetID meshAsset, MaterialAssetID materialAsset, const Matrix& transform); [[nodiscard]] JULIET_API MeshInstanceID CreateMeshInstance(MeshAssetID meshAsset, MaterialAssetID materialAsset, const Matrix& transform);
JULIET_API void SetMeshInstanceTransform(MeshInstanceID id, const Matrix& transform); JULIET_API void SetMeshInstanceTransform(MeshInstanceID id, const Matrix& transform);
// Primitives // Primitives
JULIET_API MeshAssetID GetCubePrimitiveMeshAssetID(); JULIET_API MeshAssetID GetCubePrimitiveMeshAssetID();
JULIET_API MeshAssetID GetQuadPrimitiveMeshAssetID(); JULIET_API MeshAssetID GetQuadPrimitiveMeshAssetID();
JULIET_API MeshAssetID GetSpherePrimitiveMeshAssetID(); JULIET_API MeshAssetID GetSpherePrimitiveMeshAssetID();
#if ALLOW_SHADER_HOT_RELOAD #if ALLOW_SHADER_HOT_RELOAD
JULIET_API void ReloadMeshRendererShaders(); JULIET_API void ReloadMeshRendererShaders();
#endif #endif
} // namespace Juliet
+19 -22
View File
@@ -1,32 +1,29 @@
#pragma once #pragma once
#include <Core/Math/Matrix.h> #include <Core/Math/Matrix.h>
#include <Core/Math/Vector.h> #include <Core/Math/Vector.h>
#include <Juliet.h> #include <Juliet.h>
namespace Juliet struct PushData
{ {
struct PushData Matrix ViewProjection;
{ uint32 MeshIndex;
Matrix ViewProjection; uint32 TransformsBufferIndex;
uint32 MeshIndex; uint32 BufferIndex;
uint32 TransformsBufferIndex; uint32 TextureIndex;
uint32 BufferIndex; uint32 VertexOffset;
uint32 TextureIndex; uint32 LightBufferIndex;
uint32 VertexOffset; uint32 ActiveLightCount;
uint32 LightBufferIndex; float GlobalAmbientIntensity;
uint32 ActiveLightCount;
float GlobalAmbientIntensity;
Vector3 GlobalLightDirection; Vector3 GlobalLightDirection;
uint32 Pad1; uint32 Pad1;
Vector3 GlobalLightColor; Vector3 GlobalLightColor;
uint32 Pad2; uint32 Pad2;
float Scale[2]; float Scale[2];
float Translate[2]; float Translate[2];
Vector4 MeshAlbedo; Vector4 MeshAlbedo;
}; };
} // namespace Juliet
+95 -98
View File
@@ -1,115 +1,112 @@
#pragma once #pragma once
#include <Graphics/Colors.h> #include <Graphics/Colors.h>
#include <Graphics/Texture.h> #include <Graphics/Texture.h>
namespace Juliet enum struct LoadOperation : uint8
{ {
enum struct LoadOperation : uint8 Load, // Load the texture from memory (preserve)
Clear, // Clear the texture
Ignore // Ignore the content of the texture (undefined)
};
enum struct StoreOperation : uint8
{
Store, // Store the result of the render pass into memory
Ignore, // Whatever is generated is ignored (undefined)
Resolve, // Resolve MipMaps into non mip map texture. Discard MipMap content
ResolveAndStore // Same but store the MipMap content to memory
};
struct ColorTargetInfo
{
Texture* TargetTexture;
uint32 MipLevel;
union
{ {
Load, // Load the texture from memory (preserve) uint32 DepthPlane;
Clear, // Clear the texture uint32 LayerIndex;
Ignore // Ignore the content of the texture (undefined)
}; };
bool CycleTexture; // Whether the texture should be cycled if already bound (and load operation != LOAD)
enum struct StoreOperation : uint8 Texture* ResolveTexture;
{ uint32 ResolveMipLevel;
Store, // Store the result of the render pass into memory uint32 ResolveLayerIndex;
Ignore, // Whatever is generated is ignored (undefined) bool CycleResolveTexture;
Resolve, // Resolve MipMaps into non mip map texture. Discard MipMap content
ResolveAndStore // Same but store the MipMap content to memory
};
struct ColorTargetInfo FColor ClearColor;
{ LoadOperation LoadOperation;
Texture* TargetTexture; StoreOperation StoreOperation;
uint32 MipLevel; };
union
{
uint32 DepthPlane;
uint32 LayerIndex;
};
bool CycleTexture; // Whether the texture should be cycled if already bound (and load operation != LOAD)
Texture* ResolveTexture; struct DepthStencilTargetInfo
uint32 ResolveMipLevel; {
uint32 ResolveLayerIndex; Texture* TargetTexture;
bool CycleResolveTexture; uint32 MipLevel;
uint32 LayerIndex;
FColor ClearColor; float ClearDepth;
LoadOperation LoadOperation; uint8 ClearStencil;
StoreOperation StoreOperation; LoadOperation LoadOperation;
}; StoreOperation StoreOperation;
};
struct DepthStencilTargetInfo enum class BlendFactor : uint8
{ {
Texture* TargetTexture; Invalid,
uint32 MipLevel; Zero,
uint32 LayerIndex; One,
Src_Color,
One_Minus_Src_Color,
Dst_Color,
One_Minus_Dst_Color,
Src_Alpha,
One_Minus_Src_Alpha,
Dst_Alpha,
One_Minus_Dst_Alpha,
Constant_Color,
One_MINUS_Constant_Color,
Src_Alpha_Saturate, // min(source alpha, 1 - destination alpha)
Count
};
float ClearDepth; enum class BlendOperation : uint8
uint8 ClearStencil; {
LoadOperation LoadOperation; Invalid,
StoreOperation StoreOperation; Add, // (source * source_factor) + (destination * destination_factor)
}; Subtract, // (source * source_factor) - (destination * destination_factor)
ReverseSubtract, // (destination * destination_factor) - (source * source_factor)
Min, // min(source, destination)
Max, // max(source, destination)
Count
};
enum class BlendFactor : uint8 enum class ColorComponentFlags : uint8
{ {
Invalid, R = 1u << 0,
Zero, G = 1u << 1,
One, B = 1u << 2,
Src_Color, A = 1u << 3
One_Minus_Src_Color, };
Dst_Color,
One_Minus_Dst_Color,
Src_Alpha,
One_Minus_Src_Alpha,
Dst_Alpha,
One_Minus_Dst_Alpha,
Constant_Color,
One_MINUS_Constant_Color,
Src_Alpha_Saturate, // min(source alpha, 1 - destination alpha)
Count
};
enum class BlendOperation : uint8 struct ColorTargetBlendState
{ {
Invalid, BlendFactor SourceColorBlendFactor; // The value to be multiplied by the source RGB value.
Add, // (source * source_factor) + (destination * destination_factor) BlendFactor DestinationColorBlendFactor; // The value to be multiplied by the destination RGB value.
Subtract, // (source * source_factor) - (destination * destination_factor) BlendOperation ColorBlendOperation; // The blend operation for the RGB components.
ReverseSubtract, // (destination * destination_factor) - (source * source_factor) BlendFactor SourceAlphaBlendFactor; // The value to be multiplied by the source alpha.
Min, // min(source, destination) BlendFactor DestinationAlphaBlendFactor; // The value to be multiplied by the destination alpha.
Max, // max(source, destination) BlendOperation AlphaBlendOperation; // The blend operation for the alpha component.
Count ColorComponentFlags ColorWriteMask; // A bitmask specifying which of the RGBA components are enabled for writing. Writes to all channels if enable_color_write_mask is false.
}; bool EnableBlend : 1; // Whether blending is enabled for the color target.
bool EnableColorWriteMask : 1; // Whether the color write mask is enabled.
};
enum class ColorComponentFlags : uint8 struct ColorTargetDescription
{ {
R = 1u << 0, TextureFormat Format;
G = 1u << 1, ColorTargetBlendState BlendState;
B = 1u << 2, };
A = 1u << 3
};
struct ColorTargetBlendState // Opaque Type
{ struct RenderPass;
BlendFactor SourceColorBlendFactor; // The value to be multiplied by the source RGB value.
BlendFactor DestinationColorBlendFactor; // The value to be multiplied by the destination RGB value.
BlendOperation ColorBlendOperation; // The blend operation for the RGB components.
BlendFactor SourceAlphaBlendFactor; // The value to be multiplied by the source alpha.
BlendFactor DestinationAlphaBlendFactor; // The value to be multiplied by the destination alpha.
BlendOperation AlphaBlendOperation; // The blend operation for the alpha component.
ColorComponentFlags ColorWriteMask; // A bitmask specifying which of the RGBA components are enabled for writing. Writes to all channels if enable_color_write_mask is false.
bool EnableBlend : 1; // Whether blending is enabled for the color target.
bool EnableColorWriteMask : 1; // Whether the color write mask is enabled.
};
struct ColorTargetDescription
{
TextureFormat Format;
ColorTargetBlendState BlendState;
};
// Opaque Type
struct RenderPass;
} // namespace Juliet
+14 -17
View File
@@ -1,23 +1,20 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
namespace Juliet // Opaque type
struct Shader;
enum class ShaderStage : uint8
{ {
// Opaque type Vertex,
struct Shader; Fragment,
Compute
};
enum class ShaderStage : uint8 struct ShaderCreateInfo
{ {
Vertex, ShaderStage Stage;
Fragment, String EntryPoint;
Compute };
};
struct ShaderCreateInfo
{
ShaderStage Stage;
String EntryPoint;
};
} // namespace Juliet
+15 -18
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include <Juliet.h> #include <Juliet.h>
@@ -6,26 +6,23 @@
#include <Core/Math/Matrix.h> #include <Core/Math/Matrix.h>
#include <Graphics/GraphicsConfig.h> #include <Graphics/GraphicsConfig.h>
namespace Juliet struct RenderPass;
struct CommandList;
struct Window;
struct GraphicsPipeline;
struct GraphicsDevice;
struct SkyboxRenderer
{ {
struct RenderPass; GraphicsDevice* Device;
struct CommandList; GraphicsPipeline* Pipeline;
struct Window; };
struct GraphicsPipeline;
struct GraphicsDevice;
struct SkyboxRenderer [[nodiscard]] JULIET_API bool InitializeSkyboxRenderer(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
{ JULIET_API void ShutdownSkyboxRenderer();
GraphicsDevice* Device; JULIET_API void RenderSkybox(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
GraphicsPipeline* Pipeline;
};
[[nodiscard]] JULIET_API bool InitializeSkyboxRenderer(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
JULIET_API void ShutdownSkyboxRenderer();
JULIET_API void RenderSkybox(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
#if ALLOW_SHADER_HOT_RELOAD #if ALLOW_SHADER_HOT_RELOAD
JULIET_API void ReloadSkyboxShaders(); JULIET_API void ReloadSkyboxShaders();
#endif #endif
} // namespace Juliet
+176 -179
View File
@@ -1,183 +1,180 @@
#pragma once #pragma once
namespace Juliet enum struct TextureFormat : uint8
{ {
enum struct TextureFormat : uint8 Invalid,
/* Unsigned Normalized Float Color Formats */
A8_UNORM,
R8_UNORM,
R8G8_UNORM,
R8G8B8A8_UNORM,
R16_UNORM,
R16G16_UNORM,
R16G16B16A16_UNORM,
R10G10B10A2_UNORM,
B5G6R5_UNORM,
B5G5R5A1_UNORM,
B4G4R4A4_UNORM,
B8G8R8A8_UNORM,
/* Compressed Unsigned Normalized Float Color Formats */
BC1_RGBA_UNORM,
BC2_RGBA_UNORM,
BC3_RGBA_UNORM,
BC4_R_UNORM,
BC5_RG_UNORM,
BC7_RGBA_UNORM,
/* Compressed Signed Float Color Formats */
BC6H_RGB_FLOAT,
/* Compressed Unsigned Float Color Formats */
BC6H_RGB_UFLOAT,
/* Signed Normalized Float Color Formats */
R8_SNORM,
R8G8_SNORM,
R8G8B8A8_SNORM,
R16_SNORM,
R16G16_SNORM,
R16G16B16A16_SNORM,
/* Signed Float Color Formats */
R16_FLOAT,
R16G16_FLOAT,
R16G16B16A16_FLOAT,
R32_FLOAT,
R32G32_FLOAT,
R32G32B32A32_FLOAT,
/* Unsigned Float Color Formats */
R11G11B10_UFLOAT,
/* Unsigned Integer Color Formats */
R8_UINT,
R8G8_UINT,
R8G8B8A8_UINT,
R16_UINT,
R16G16_UINT,
R16G16B16A16_UINT,
R32_UINT,
R32G32_UINT,
R32G32B32A32_UINT,
/* Signed Integer Color Formats */
R8_INT,
R8G8_INT,
R8G8B8A8_INT,
R16_INT,
R16G16_INT,
R16G16B16A16_INT,
R32_INT,
R32G32_INT,
R32G32B32A32_INT,
/* SRGB Unsigned Normalized Color Formats */
R8G8B8A8_UNORM_SRGB,
B8G8R8A8_UNORM_SRGB,
/* Compressed SRGB Unsigned Normalized Color Formats */
BC1_RGBA_UNORM_SRGB,
BC2_RGBA_UNORM_SRGB,
BC3_RGBA_UNORM_SRGB,
BC7_RGBA_UNORM_SRGB,
/* Depth Formats */
D16_UNORM,
D24_UNORM,
D32_FLOAT,
D24_UNORM_S8_UINT,
D32_FLOAT_S8_UINT,
/* Compressed ASTC Normalized Float Color Formats*/
ASTC_4x4_UNORM,
ASTC_5x4_UNORM,
ASTC_5x5_UNORM,
ASTC_6x5_UNORM,
ASTC_6x6_UNORM,
ASTC_8x5_UNORM,
ASTC_8x6_UNORM,
ASTC_8x8_UNORM,
ASTC_10x5_UNORM,
ASTC_10x6_UNORM,
ASTC_10x8_UNORM,
ASTC_10x10_UNORM,
ASTC_12x10_UNORM,
ASTC_12x12_UNORM,
/* Compressed SRGB ASTC Normalized Float Color Formats*/
ASTC_4x4_UNORM_SRGB,
ASTC_5x4_UNORM_SRGB,
ASTC_5x5_UNORM_SRGB,
ASTC_6x5_UNORM_SRGB,
ASTC_6x6_UNORM_SRGB,
ASTC_8x5_UNORM_SRGB,
ASTC_8x6_UNORM_SRGB,
ASTC_8x8_UNORM_SRGB,
ASTC_10x5_UNORM_SRGB,
ASTC_10x6_UNORM_SRGB,
ASTC_10x8_UNORM_SRGB,
ASTC_10x10_UNORM_SRGB,
ASTC_12x10_UNORM_SRGB,
ASTC_12x12_UNORM_SRGB,
/* Compressed ASTC Signed Float Color Formats*/
ASTC_4x4_FLOAT,
ASTC_5x4_FLOAT,
ASTC_5x5_FLOAT,
ASTC_6x5_FLOAT,
ASTC_6x6_FLOAT,
ASTC_8x5_FLOAT,
ASTC_8x6_FLOAT,
ASTC_8x8_FLOAT,
ASTC_10x5_FLOAT,
ASTC_10x6_FLOAT,
ASTC_10x8_FLOAT,
ASTC_10x10_FLOAT,
ASTC_12x10_FLOAT,
ASTC_12x12_FLOAT,
Count
};
enum struct TextureUsageFlag : uint8
{
None = 0,
Sampler = 1 << 0, // Textures supports sampling
ColorTarget = 1 << 1, // Texture is color render target
DepthStencilTarget = 1 << 2, // Texture is depth stencil target
GraphicsStorageRead = 1 << 3, // Support Storage read at graphics stage
ComputeStorageRead = 1 << 4, // Support Storage read at compute stage
ComputeStorageWrite = 1 << 5, // Support Storage Write at compute stage
ComputeStorageSimultaneousReadWrite =
1 << 6, // Supports reads and writes in the same compute shader. Not equivalent to ComputeStorageRead | ComputeStorageWrite
};
enum struct TextureType : uint8
{
Texture_2D,
Texture_2DArray,
Texture_3D,
Texture_3DArray,
Texture_Cube,
Texture_CubeArray,
};
enum struct TextureSampleCount : uint8
{
One,
Two,
Four,
Eight,
};
// Create Information structs
struct TextureCreateInfo
{
TextureType Type;
TextureFormat Format;
TextureUsageFlag Flags;
TextureSampleCount SampleCount;
uint32 Width;
uint32 Height;
union
{ {
Invalid, uint32 LayerCount;
uint32 DepthPlane;
}; // LayerCount is used in 2d array textures and Depth for 3d textures
uint32 MipLevelCount;
};
/* Unsigned Normalized Float Color Formats */ // Opaque Type
A8_UNORM, struct Texture;
R8_UNORM,
R8G8_UNORM,
R8G8B8A8_UNORM,
R16_UNORM,
R16G16_UNORM,
R16G16B16A16_UNORM,
R10G10B10A2_UNORM,
B5G6R5_UNORM,
B5G5R5A1_UNORM,
B4G4R4A4_UNORM,
B8G8R8A8_UNORM,
/* Compressed Unsigned Normalized Float Color Formats */
BC1_RGBA_UNORM,
BC2_RGBA_UNORM,
BC3_RGBA_UNORM,
BC4_R_UNORM,
BC5_RG_UNORM,
BC7_RGBA_UNORM,
/* Compressed Signed Float Color Formats */
BC6H_RGB_FLOAT,
/* Compressed Unsigned Float Color Formats */
BC6H_RGB_UFLOAT,
/* Signed Normalized Float Color Formats */
R8_SNORM,
R8G8_SNORM,
R8G8B8A8_SNORM,
R16_SNORM,
R16G16_SNORM,
R16G16B16A16_SNORM,
/* Signed Float Color Formats */
R16_FLOAT,
R16G16_FLOAT,
R16G16B16A16_FLOAT,
R32_FLOAT,
R32G32_FLOAT,
R32G32B32A32_FLOAT,
/* Unsigned Float Color Formats */
R11G11B10_UFLOAT,
/* Unsigned Integer Color Formats */
R8_UINT,
R8G8_UINT,
R8G8B8A8_UINT,
R16_UINT,
R16G16_UINT,
R16G16B16A16_UINT,
R32_UINT,
R32G32_UINT,
R32G32B32A32_UINT,
/* Signed Integer Color Formats */
R8_INT,
R8G8_INT,
R8G8B8A8_INT,
R16_INT,
R16G16_INT,
R16G16B16A16_INT,
R32_INT,
R32G32_INT,
R32G32B32A32_INT,
/* SRGB Unsigned Normalized Color Formats */
R8G8B8A8_UNORM_SRGB,
B8G8R8A8_UNORM_SRGB,
/* Compressed SRGB Unsigned Normalized Color Formats */
BC1_RGBA_UNORM_SRGB,
BC2_RGBA_UNORM_SRGB,
BC3_RGBA_UNORM_SRGB,
BC7_RGBA_UNORM_SRGB,
/* Depth Formats */
D16_UNORM,
D24_UNORM,
D32_FLOAT,
D24_UNORM_S8_UINT,
D32_FLOAT_S8_UINT,
/* Compressed ASTC Normalized Float Color Formats*/
ASTC_4x4_UNORM,
ASTC_5x4_UNORM,
ASTC_5x5_UNORM,
ASTC_6x5_UNORM,
ASTC_6x6_UNORM,
ASTC_8x5_UNORM,
ASTC_8x6_UNORM,
ASTC_8x8_UNORM,
ASTC_10x5_UNORM,
ASTC_10x6_UNORM,
ASTC_10x8_UNORM,
ASTC_10x10_UNORM,
ASTC_12x10_UNORM,
ASTC_12x12_UNORM,
/* Compressed SRGB ASTC Normalized Float Color Formats*/
ASTC_4x4_UNORM_SRGB,
ASTC_5x4_UNORM_SRGB,
ASTC_5x5_UNORM_SRGB,
ASTC_6x5_UNORM_SRGB,
ASTC_6x6_UNORM_SRGB,
ASTC_8x5_UNORM_SRGB,
ASTC_8x6_UNORM_SRGB,
ASTC_8x8_UNORM_SRGB,
ASTC_10x5_UNORM_SRGB,
ASTC_10x6_UNORM_SRGB,
ASTC_10x8_UNORM_SRGB,
ASTC_10x10_UNORM_SRGB,
ASTC_12x10_UNORM_SRGB,
ASTC_12x12_UNORM_SRGB,
/* Compressed ASTC Signed Float Color Formats*/
ASTC_4x4_FLOAT,
ASTC_5x4_FLOAT,
ASTC_5x5_FLOAT,
ASTC_6x5_FLOAT,
ASTC_6x6_FLOAT,
ASTC_8x5_FLOAT,
ASTC_8x6_FLOAT,
ASTC_8x8_FLOAT,
ASTC_10x5_FLOAT,
ASTC_10x6_FLOAT,
ASTC_10x8_FLOAT,
ASTC_10x10_FLOAT,
ASTC_12x10_FLOAT,
ASTC_12x12_FLOAT,
Count
};
enum struct TextureUsageFlag : uint8
{
None = 0,
Sampler = 1 << 0, // Textures supports sampling
ColorTarget = 1 << 1, // Texture is color render target
DepthStencilTarget = 1 << 2, // Texture is depth stencil target
GraphicsStorageRead = 1 << 3, // Support Storage read at graphics stage
ComputeStorageRead = 1 << 4, // Support Storage read at compute stage
ComputeStorageWrite = 1 << 5, // Support Storage Write at compute stage
ComputeStorageSimultaneousReadWrite =
1 << 6, // Supports reads and writes in the same compute shader. Not equivalent to ComputeStorageRead | ComputeStorageWrite
};
enum struct TextureType : uint8
{
Texture_2D,
Texture_2DArray,
Texture_3D,
Texture_3DArray,
Texture_Cube,
Texture_CubeArray,
};
enum struct TextureSampleCount : uint8
{
One,
Two,
Four,
Eight,
};
// Create Information structs
struct TextureCreateInfo
{
TextureType Type;
TextureFormat Format;
TextureUsageFlag Flags;
TextureSampleCount SampleCount;
uint32 Width;
uint32 Height;
union
{
uint32 LayerCount;
uint32 DepthPlane;
}; // LayerCount is used in 2d array textures and Depth for 3d textures
uint32 MipLevelCount;
};
// Opaque Type
struct Texture;
} // namespace Juliet
+7 -10
View File
@@ -1,13 +1,10 @@
#pragma once #pragma once
namespace Juliet struct Vertex
{ {
struct Vertex float Position[3];
{ float Normal[3];
float Position[3]; float Color[4];
float Normal[3]; };
float Color[4];
};
using Index = uint16; using Index = uint16;
} // namespace Juliet
@@ -1,20 +1,17 @@
#include <Core/Application/ApplicationManager.h> #include <Core/Application/ApplicationManager.h>
#include <Core/JulietInit.h> #include <Core/JulietInit.h>
#include <Engine/Engine.h> #include <Engine/Engine.h>
namespace Juliet void StartApplication(IApplication& app, JulietInit_Flags flags)
{ {
void StartApplication(IApplication& app, JulietInit_Flags flags) InitializeEngine(flags);
{
InitializeEngine(flags);
LoadApplication(app); LoadApplication(app);
RunEngine(); RunEngine();
UnloadApplication(); UnloadApplication();
ShutdownEngine(); ShutdownEngine();
} }
} // namespace Juliet
+23 -26
View File
@@ -1,38 +1,35 @@
#include <Core/Logging/LogManager.h> #include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h> #include <Core/Logging/LogTypes.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
#include <comdef.h> // For _com_error to decode HRESULTs #include <comdef.h> // For _com_error to decode HRESULTs
#include <intrin.h> // For __debugbreak #include <intrin.h> // For __debugbreak
namespace Juliet void JulietAssert(const char* expression, const char* message, std::source_location location, long handleResult)
{ {
void JulietAssert(const char* expression, const char* message, std::source_location location, long handleResult) 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(),
location.function_name());
if (handleResult < 0)
{ {
Log(LogLevel::Error, LogCategory::Core, "--- ASSERTION FAILED ---"); _com_error err(handleResult);
Log(LogLevel::Error, LogCategory::Core, "Expression: %s", expression); // Using %ls because ErrorMessage() returns a wide string (wchar_t*)
Log(LogLevel::Error, LogCategory::Core, "Message: %s", message); Log(LogLevel::Error, LogCategory::Graphics, "HRESULT: 0x%08X (%ls)", handleResult, err.ErrorMessage());
Log(LogLevel::Error, LogCategory::Core, "Location: %s(%u): %s", location.file_name(), location.line(),
location.function_name());
if (handleResult < 0)
{
_com_error err(handleResult);
// Using %ls because ErrorMessage() returns a wide string (wchar_t*)
Log(LogLevel::Error, LogCategory::Graphics, "HRESULT: 0x%08X (%ls)", handleResult, err.ErrorMessage());
}
Log(LogLevel::Error, LogCategory::Core, "-------------------------");
JULIET_PLATFORM_BREAK();
} }
void Free(ByteBuffer& buffer) Log(LogLevel::Error, LogCategory::Core, "-------------------------");
JULIET_PLATFORM_BREAK();
}
void Free(ByteBuffer& buffer)
{
if (buffer.Data)
{ {
if (buffer.Data) Free(buffer.Data);
{
Free(buffer.Data);
}
buffer = {};
} }
} // namespace Juliet buffer = {};
}
File diff suppressed because it is too large Load Diff
+1 -4
View File
@@ -1,5 +1,2 @@
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
namespace Juliet
{
}
+133 -136
View File
@@ -1,162 +1,159 @@
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/HAL/Display/Display_cpp.h> #include <Core/HAL/Display/Display_cpp.h>
#include <Core/HAL/Display/DisplayDevice.h> #include <Core/HAL/Display/DisplayDevice.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
namespace Juliet namespace
{ {
namespace DisplayDevice* g_CurrentDisplayDevice = nullptr;
void DestroyPlatformWindow(index_t windowIndex);
} // namespace
namespace Internal::Display
{
// TODO : IfDef new factories that are not compatible
constexpr DisplayDeviceFactory* Factories[] = { &Win32DisplayDeviceFactory, nullptr };
} // namespace Internal::Display
void InitializeDisplaySystem()
{
Assert(!g_CurrentDisplayDevice);
Arena* arena = ArenaAllocate({ .Name = "Display System" });
DisplayDevice* candidateDevice = nullptr;
DisplayDeviceFactory* candidateFactory = nullptr;
for (DisplayDeviceFactory* factory : Internal::Display::Factories)
{ {
DisplayDevice* g_CurrentDisplayDevice = nullptr; if (factory)
void DestroyPlatformWindow(index_t windowIndex);
} // namespace
namespace Internal::Display
{
// TODO : IfDef new factories that are not compatible
constexpr DisplayDeviceFactory* Factories[] = { &Win32DisplayDeviceFactory, nullptr };
} // namespace Internal::Display
void InitializeDisplaySystem()
{
Assert(!g_CurrentDisplayDevice);
Arena* arena = ArenaAllocate({ .Name = "Display System" });
DisplayDevice* candidateDevice = nullptr;
DisplayDeviceFactory* candidateFactory = nullptr;
for (DisplayDeviceFactory* factory : Internal::Display::Factories)
{ {
if (factory) candidateDevice = factory->CreateDevice(arena);
if (candidateDevice)
{ {
candidateDevice = factory->CreateDevice(arena); candidateFactory = factory;
if (candidateDevice)
{
candidateFactory = factory;
break;
}
}
}
// TODO : handle error instead of crashing
Assert(candidateDevice);
g_CurrentDisplayDevice = candidateDevice;
g_CurrentDisplayDevice->Arena = arena;
g_CurrentDisplayDevice->Name = candidateFactory->Name;
if (!g_CurrentDisplayDevice->Initialize(g_CurrentDisplayDevice))
{
ShutdownDisplaySystem();
}
}
void ShutdownDisplaySystem()
{
if (!g_CurrentDisplayDevice)
{
return;
}
// Destroy all Windows that are still alive
for (index_t idx = g_CurrentDisplayDevice->Windows.Size(); idx-- > 0;)
{
DestroyPlatformWindow(idx);
}
g_CurrentDisplayDevice->Shutdown(g_CurrentDisplayDevice);
// Free anything that was freed by the shutdown and then free the display
// no op for now
g_CurrentDisplayDevice->Free(g_CurrentDisplayDevice);
ArenaRelease(g_CurrentDisplayDevice->Arena);
g_CurrentDisplayDevice = nullptr;
}
Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int /*flags*/ /* = 0 unused */)
{
Assert(g_CurrentDisplayDevice->CreatePlatformWindow);
Window window = {};
window.Arena = ArenaAllocate({ .Name = "Window" });
window.Width = width;
window.Height = height;
window.Title = StringCopy(window.Arena, WrapString(title));
g_CurrentDisplayDevice->Windows.PushBack(window);
auto* pWindow = g_CurrentDisplayDevice->Windows.Last();
if (!g_CurrentDisplayDevice->CreatePlatformWindow(g_CurrentDisplayDevice, pWindow))
{
ArenaRelease(window.Arena);
return nullptr;
}
// TODO : make SHOW optional on creation with a flag
g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, pWindow);
return pWindow;
}
namespace
{
void DestroyPlatformWindow(index_t windowIndex)
{
VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
Window* window = &windows[windowIndex];
HideWindow(window);
g_CurrentDisplayDevice->DestroyPlatformWindow(g_CurrentDisplayDevice, window);
ArenaClear(window->Arena);
ArenaRelease(window->Arena);
windows.RemoveAtFast(windowIndex);
}
} // namespace
void DestroyPlatformWindow(NonNullPtr<Window> window)
{
// Find and destroy
VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
for (index_t idx = windows.Size(); idx-- > 0;)
{
Window& windowRef = windows[idx];
if (windowRef.ID == window->ID)
{
DestroyPlatformWindow(idx);
break; break;
} }
} }
} }
void ShowWindow(NonNullPtr<Window> window) // TODO : handle error instead of crashing
Assert(candidateDevice);
g_CurrentDisplayDevice = candidateDevice;
g_CurrentDisplayDevice->Arena = arena;
g_CurrentDisplayDevice->Name = candidateFactory->Name;
if (!g_CurrentDisplayDevice->Initialize(g_CurrentDisplayDevice))
{ {
g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, window); ShutdownDisplaySystem();
}
}
void ShutdownDisplaySystem()
{
if (!g_CurrentDisplayDevice)
{
return;
} }
void HideWindow(NonNullPtr<Window> window) // Destroy all Windows that are still alive
for (index_t idx = g_CurrentDisplayDevice->Windows.Size(); idx-- > 0;)
{ {
g_CurrentDisplayDevice->HideWindow(g_CurrentDisplayDevice, window); DestroyPlatformWindow(idx);
} }
WindowID GetWindowID(NonNullPtr<Window> window) g_CurrentDisplayDevice->Shutdown(g_CurrentDisplayDevice);
// Free anything that was freed by the shutdown and then free the display
// no op for now
g_CurrentDisplayDevice->Free(g_CurrentDisplayDevice);
ArenaRelease(g_CurrentDisplayDevice->Arena);
g_CurrentDisplayDevice = nullptr;
}
Window* CreatePlatformWindow(const char* title, uint16 width, uint16 height, int /*flags*/ /* = 0 unused */)
{
Assert(g_CurrentDisplayDevice->CreatePlatformWindow);
Window window = {};
window.Arena = ArenaAllocate({ .Name = "Window" });
window.Width = width;
window.Height = height;
window.Title = StringCopy(window.Arena, WrapString(title));
g_CurrentDisplayDevice->Windows.PushBack(window);
auto* pWindow = g_CurrentDisplayDevice->Windows.Last();
if (!g_CurrentDisplayDevice->CreatePlatformWindow(g_CurrentDisplayDevice, pWindow))
{ {
return window->ID; ArenaRelease(window.Arena);
return nullptr;
} }
void SetWindowTitle(NonNullPtr<Window> window, String title) // TODO : make SHOW optional on creation with a flag
{ g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, pWindow);
g_CurrentDisplayDevice->SetWindowTitle(g_CurrentDisplayDevice, window, title);
}
// Display Device Utils. Not exposed in the API return pWindow;
DisplayDevice* GetDisplayDevice() }
namespace
{
void DestroyPlatformWindow(index_t windowIndex)
{ {
return g_CurrentDisplayDevice; VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
Window* window = &windows[windowIndex];
HideWindow(window);
g_CurrentDisplayDevice->DestroyPlatformWindow(g_CurrentDisplayDevice, window);
ArenaClear(window->Arena);
ArenaRelease(window->Arena);
windows.RemoveAtFast(windowIndex);
} }
} // namespace Juliet } // namespace
void DestroyPlatformWindow(NonNullPtr<Window> window)
{
// Find and destroy
VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
for (index_t idx = windows.Size(); idx-- > 0;)
{
Window& windowRef = windows[idx];
if (windowRef.ID == window->ID)
{
DestroyPlatformWindow(idx);
break;
}
}
}
void ShowWindow(NonNullPtr<Window> window)
{
g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, window);
}
void HideWindow(NonNullPtr<Window> window)
{
g_CurrentDisplayDevice->HideWindow(g_CurrentDisplayDevice, window);
}
WindowID GetWindowID(NonNullPtr<Window> window)
{
return window->ID;
}
void SetWindowTitle(NonNullPtr<Window> window, String title)
{
g_CurrentDisplayDevice->SetWindowTitle(g_CurrentDisplayDevice, window, title);
}
// Display Device Utils. Not exposed in the API
DisplayDevice* GetDisplayDevice()
{
return g_CurrentDisplayDevice;
}
+30 -33
View File
@@ -1,47 +1,44 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
#include <Core/HAL/Display/Window.h> #include <Core/HAL/Display/Window.h>
namespace Juliet // Driver to the display device.
// Functions ptr will be set by the chosen factory
// Acts as a singleton after Initialize has been called and is freed in Shutdown.
struct DisplayDevice
{ {
// Driver to the display device. Arena* Arena;
// Functions ptr will be set by the chosen factory
// Acts as a singleton after Initialize has been called and is freed in Shutdown.
struct DisplayDevice
{
Arena* Arena;
const char* Name = "Unknown"; const char* Name = "Unknown";
// Initialize all subsystems needed for the device to works // Initialize all subsystems needed for the device to works
bool (*Initialize)(NonNullPtr<DisplayDevice> self); bool (*Initialize)(NonNullPtr<DisplayDevice> self);
void (*Shutdown)(NonNullPtr<DisplayDevice> self); void (*Shutdown)(NonNullPtr<DisplayDevice> self);
void (*Free)(NonNullPtr<DisplayDevice> self); void (*Free)(NonNullPtr<DisplayDevice> self);
// Window management // Window management
bool (*CreatePlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window); bool (*CreatePlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
void (*DestroyPlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window); void (*DestroyPlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
void (*ShowWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window); void (*ShowWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
void (*HideWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window); void (*HideWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
void (*SetWindowTitle)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title); void (*SetWindowTitle)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title);
// Events // Events
void (*PumpEvents)(NonNullPtr<DisplayDevice> self); void (*PumpEvents)(NonNullPtr<DisplayDevice> self);
VectorArena<Window> Windows; VectorArena<Window> Windows;
}; };
struct DisplayDeviceFactory struct DisplayDeviceFactory
{ {
const char* Name = "Unknown"; const char* Name = "Unknown";
DisplayDevice* (*CreateDevice)(Arena* arena); DisplayDevice* (*CreateDevice)(Arena* arena);
}; };
// TODO : Support more platforms // TODO : Support more platforms
extern DisplayDeviceFactory Win32DisplayDeviceFactory; extern DisplayDeviceFactory Win32DisplayDeviceFactory;
// Utils // Utils
extern DisplayDevice* GetDisplayDevice(); extern DisplayDevice* GetDisplayDevice();
} // namespace Juliet
+3 -6
View File
@@ -1,7 +1,4 @@
#pragma once #pragma once
namespace Juliet void InitializeDisplaySystem();
{ void ShutdownDisplaySystem();
void InitializeDisplaySystem();
void ShutdownDisplaySystem();
} // namespace Juliet
@@ -1,8 +1,8 @@
#include <Core/HAL/Display/DisplayDevice.h> #include <Core/HAL/Display/DisplayDevice.h>
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h> #include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
#include <Core/HAL/Display/Win32/Win32Window.h> #include <Core/HAL/Display/Win32/Win32Window.h>
namespace Juliet::Win32 namespace Win32
{ {
namespace namespace
{ {
@@ -43,10 +43,7 @@ namespace Juliet::Win32
} }
} // namespace } // namespace
} // namespace Juliet::Win32 } // namespace Win32
// Factory cannot be in an anonymous/unknown namespace // Factory cannot be in an anonymous/unknown namespace
namespace Juliet DisplayDeviceFactory Win32DisplayDeviceFactory = { .Name = "Win32", .CreateDevice = Win32::CreateDevice };
{
DisplayDeviceFactory Win32DisplayDeviceFactory = { .Name = "Win32", .CreateDevice = Win32::CreateDevice };
}
@@ -1,4 +1,4 @@
#include <Core/Common/EnumUtils.h> #include <Core/Common/EnumUtils.h>
#include <Core/HAL/Display/DisplayDevice.h> #include <Core/HAL/Display/DisplayDevice.h>
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h> #include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
#include <Core/HAL/Display/Win32/Win32Window.h> #include <Core/HAL/Display/Win32/Win32Window.h>
@@ -20,7 +20,7 @@
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
#endif #endif
namespace Juliet::Win32 namespace Win32
{ {
namespace namespace
{ {
@@ -276,4 +276,4 @@ namespace Juliet::Win32
return CallWindowProcA(DefWindowProcA, handle, message, wParam, lParam); return CallWindowProcA(DefWindowProcA, handle, message, wParam, lParam);
} }
} // namespace Juliet::Win32 } // namespace Win32
@@ -1,15 +1,12 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/HAL/Win32.h> #include <Core/HAL/Win32.h>
namespace Juliet struct DisplayDevice;
{
struct DisplayDevice;
}
namespace Juliet::Win32 namespace Win32
{ {
extern void PumpEvents(NonNullPtr<DisplayDevice> self); extern void PumpEvents(NonNullPtr<DisplayDevice> self);
extern LRESULT CALLBACK Win32MainWindowCallback(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam); extern LRESULT CALLBACK Win32MainWindowCallback(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam);
} // namespace Juliet::Win32 } // namespace Win32
@@ -1,10 +1,10 @@
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h> #include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
#include <Core/HAL/Display/Win32/Win32Window.h> #include <Core/HAL/Display/Win32/Win32Window.h>
#include <Core/HAL/Display/Window.h> #include <Core/HAL/Display/Window.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
#include <Core/Memory/MemoryArena.h> #include <Core/Memory/MemoryArena.h>
namespace Juliet::Win32 namespace Win32
{ {
namespace namespace
{ {
@@ -101,4 +101,4 @@ namespace Juliet::Win32
auto& win32State = static_cast<Window32State&>(*window->State); auto& win32State = static_cast<Window32State&>(*window->State);
SetWindowTextA(win32State.Handle, CStr(title)); SetWindowTextA(win32State.Handle, CStr(title));
} }
} // namespace Juliet::Win32 } // namespace Win32
@@ -1,16 +1,13 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/HAL/Display/Window.h> #include <Core/HAL/Display/Window.h>
#include <Core/HAL/Win32.h> #include <Core/HAL/Win32.h>
namespace Juliet struct DisplayDevice;
{ struct Window;
struct DisplayDevice;
struct Window;
} // namespace Juliet
namespace Juliet::Win32 namespace Win32
{ {
// TODO : Evaluate if its worth the burden of casting to Window32State all the time // TODO : Evaluate if its worth the burden of casting to Window32State all the time
struct Window32State : WindowState struct Window32State : WindowState
@@ -26,4 +23,4 @@ namespace Juliet::Win32
extern void ShowWindow(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window); extern void ShowWindow(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
extern void HideWindow(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window); extern void HideWindow(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
extern void SetWindowTitle(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title); extern void SetWindowTitle(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title);
} // namespace Juliet::Win32 } // namespace Win32
+14 -17
View File
@@ -1,24 +1,21 @@
#pragma once #pragma once
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/HAL/Display/Display.h> #include <Core/HAL/Display/Display.h>
namespace Juliet struct Window;
struct WindowState
{ {
struct Window; Window* Window;
struct WindowState };
{
Window* Window;
};
struct Window struct Window
{ {
WindowID ID; WindowID ID;
WindowState* State; WindowState* State;
Arena* Arena; Arena* Arena;
int32 Width; int32 Width;
int32 Height; int32 Height;
String Title; String Title;
}; };
} // namespace Juliet
@@ -1,44 +1,41 @@
#include <Core/HAL/DynLib/DynamicLibrary.h> #include <Core/HAL/DynLib/DynamicLibrary.h>
#include <Core/HAL/Win32.h> #include <Core/HAL/Win32.h>
#include <Core/Logging/LogManager.h> #include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h> #include <Core/Logging/LogTypes.h>
namespace Juliet DynamicLibrary* LoadDynamicLibrary(const char* filename)
{ {
DynamicLibrary* LoadDynamicLibrary(const char* filename) if (!filename)
{ {
if (!filename) Log(LogLevel::Error, LogCategory::Core, "Library filename is invalid (empty)");
{ return nullptr;
Log(LogLevel::Error, LogCategory::Core, "Library filename is invalid (empty)");
return nullptr;
}
HMODULE handle = LoadLibraryA(filename);
// Generate an error message if all loads failed
if (!handle)
{
Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", filename);
return nullptr;
}
return reinterpret_cast<DynamicLibrary*>(handle);
} }
FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName) HMODULE handle = LoadLibraryA(filename);
// Generate an error message if all loads failed
if (!handle)
{ {
Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", filename);
return nullptr;
}
return reinterpret_cast<DynamicLibrary*>(handle);
}
FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName)
{
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 4191) // Disable "unsafe conversion from FARPROC" #pragma warning(disable: 4191) // Disable "unsafe conversion from FARPROC"
auto function = reinterpret_cast<FunctionPtr>(GetProcAddress(reinterpret_cast<HMODULE>(lib.Get()), functionName)); auto function = reinterpret_cast<FunctionPtr>(GetProcAddress(reinterpret_cast<HMODULE>(lib.Get()), functionName));
if (!function) if (!function)
{
Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", functionName);
}
return function;
#pragma warning(pop)
}
void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib)
{ {
FreeLibrary(reinterpret_cast<HMODULE>(lib.Get())); Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", functionName);
} }
} // namespace Juliet return function;
#pragma warning(pop)
}
void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib)
{
FreeLibrary(reinterpret_cast<HMODULE>(lib.Get()));
}
+127 -130
View File
@@ -1,165 +1,162 @@
#include <Core/Common/EnumUtils.h> #include <Core/Common/EnumUtils.h>
#include <Core/HAL/Event/Keyboard_Private.h> #include <Core/HAL/Event/Keyboard_Private.h>
#include <Core/HAL/Event/KeyboardMapping.h> #include <Core/HAL/Event/KeyboardMapping.h>
#include <Core/HAL/Event/SystemEvent.h> #include <Core/HAL/Event/SystemEvent.h>
namespace Juliet constexpr KeyboardID kGlobalKeyboardID = 0;
namespace
{ {
constexpr KeyboardID kGlobalKeyboardID = 0; struct KeyboardState
namespace
{ {
struct KeyboardState KeyState KeyState[ToUnderlying(ScanCode::Count)];
KeyMod KeyModState;
} KeyboardState;
bool SendKeyboardKey_Internal(uint64 timestamp, KeyboardID /*ID*/, Key key, KeyPosition keyPosition)
{
Assert(key.KeyCode == KeyCode::Unknown); // At this point Keycode is not yet extracted
auto& keyboardState = KeyboardState; // Needed because MSVC debugger ignores variable in anonymouse namespace
auto type = EventType::None;
const bool isKeyDown = keyPosition == KeyPosition::Down;
if (isKeyDown)
{ {
KeyState KeyState[ToUnderlying(ScanCode::Count)]; type = EventType::Key_Down;
KeyMod KeyModState; }
} KeyboardState; else
bool SendKeyboardKey_Internal(uint64 timestamp, KeyboardID /*ID*/, Key key, KeyPosition keyPosition)
{ {
Assert(key.KeyCode == KeyCode::Unknown); // At this point Keycode is not yet extracted type = EventType::Key_Up;
}
auto& keyboardState = KeyboardState; // Needed because MSVC debugger ignores variable in anonymouse namespace bool isKeyRepeat = false;
if (key.ScanCode > ScanCode::Unknown && key.ScanCode < ScanCode::Count)
{
auto& currentKeyState = keyboardState.KeyState[ToUnderlying(key.ScanCode)];
auto type = EventType::None; // If state didn't change, this is a key repeat
const bool isKeyDown = keyPosition == KeyPosition::Down;
if (isKeyDown) if (isKeyDown)
{ {
type = EventType::Key_Down; if (currentKeyState.Position == KeyPosition::Down)
{
isKeyRepeat = true;
}
} }
else else
{ {
type = EventType::Key_Up; if (currentKeyState.Position == KeyPosition::Up)
}
bool isKeyRepeat = false;
if (key.ScanCode > ScanCode::Unknown && key.ScanCode < ScanCode::Count)
{
auto& currentKeyState = keyboardState.KeyState[ToUnderlying(key.ScanCode)];
// If state didn't change, this is a key repeat
if (isKeyDown)
{ {
if (currentKeyState.Position == KeyPosition::Down) return false;
{
isKeyRepeat = true;
}
} }
else
{
if (currentKeyState.Position == KeyPosition::Up)
{
return false;
}
}
currentKeyState.Position = keyPosition;
key.KeyCode = GetKeyCodeFromScanCode(key.ScanCode, keyboardState.KeyModState);
}
else if (key.Raw == 0)
{
return false;
} }
if (!isKeyRepeat) currentKeyState.Position = keyPosition;
{ key.KeyCode = GetKeyCodeFromScanCode(key.ScanCode, keyboardState.KeyModState);
KeyMod newModifier = {}; }
else if (key.Raw == 0)
{
return false;
}
if (!isKeyRepeat)
{
KeyMod newModifier = {};
switch (key.KeyCode)
{
case KeyCode::LeftControl: newModifier = KeyMod::LeftControl; break;
case KeyCode::RightControl: newModifier = KeyMod::RightControl; break;
case KeyCode::LeftShift: newModifier = KeyMod::LeftShift; break;
case KeyCode::RightShift: newModifier = KeyMod::RightShift; break;
case KeyCode::LeftAlt: newModifier = KeyMod::LeftAlt; break;
case KeyCode::RightAlt: newModifier = KeyMod::RightAlt; break;
case KeyCode::LeftOSCommand: newModifier = KeyMod::LeftOSCommand; break;
case KeyCode::RightOSCommand: newModifier = KeyMod::RightOSCommand; break;
default: newModifier = KeyMod::None; break;
}
if (type == EventType::Key_Down)
{
switch (key.KeyCode) switch (key.KeyCode)
{ {
case KeyCode::LeftControl: newModifier = KeyMod::LeftControl; break; case KeyCode::NumlockClear: newModifier ^= KeyMod::NumLock; break;
case KeyCode::RightControl: newModifier = KeyMod::RightControl; break; case KeyCode::CapsLock: newModifier ^= KeyMod::CapsLock; break;
case KeyCode::LeftShift: newModifier = KeyMod::LeftShift; break; case KeyCode::ScrollLock: newModifier ^= KeyMod::ScrollLock; break;
case KeyCode::RightShift: newModifier = KeyMod::RightShift; break; default: keyboardState.KeyModState |= newModifier;
case KeyCode::LeftAlt: newModifier = KeyMod::LeftAlt; break;
case KeyCode::RightAlt: newModifier = KeyMod::RightAlt; break;
case KeyCode::LeftOSCommand: newModifier = KeyMod::LeftOSCommand; break;
case KeyCode::RightOSCommand: newModifier = KeyMod::RightOSCommand; break;
default: newModifier = KeyMod::None; break;
}
if (type == EventType::Key_Down)
{
switch (key.KeyCode)
{
case KeyCode::NumlockClear: newModifier ^= KeyMod::NumLock; break;
case KeyCode::CapsLock: newModifier ^= KeyMod::CapsLock; break;
case KeyCode::ScrollLock: newModifier ^= KeyMod::ScrollLock; break;
default: keyboardState.KeyModState |= newModifier;
}
}
else
{
// Remove from any keymod not pressed from the modifier
keyboardState.KeyModState &= ~newModifier;
}
}
SystemEvent evt;
evt.Timestamp = timestamp;
evt.Type = type;
evt.Data.Keyboard.AssociatedKeyboardID = kGlobalKeyboardID;
evt.Data.Keyboard.Key = key;
evt.Data.Keyboard.KeyState = { keyPosition, 0.0f };
evt.Data.Keyboard.KeyModeState = keyboardState.KeyModState;
bool evtPosted = AddEvent(evt);
return evtPosted;
}
} // namespace
bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition)
{
return SendKeyboardKey_Internal(timestamp, ID, key, keyPosition);
}
void UpdateKeyboardstate(float deltaTime)
{
for (KeyState& state : KeyboardState.KeyState)
{
if (state.Position == KeyPosition::Down)
{
if (state.Time < 0.0f)
{
state.Time = 0.0f;
}
else
{
state.Time += deltaTime;
} }
} }
else else
{ {
state.Time = -1.0f; // Remove from any keymod not pressed from the modifier
keyboardState.KeyModState &= ~newModifier;
} }
} }
}
bool IsKeyDown(ScanCode scanCode) SystemEvent evt;
evt.Timestamp = timestamp;
evt.Type = type;
evt.Data.Keyboard.AssociatedKeyboardID = kGlobalKeyboardID;
evt.Data.Keyboard.Key = key;
evt.Data.Keyboard.KeyState = { keyPosition, 0.0f };
evt.Data.Keyboard.KeyModeState = keyboardState.KeyModState;
bool evtPosted = AddEvent(evt);
return evtPosted;
}
} // namespace
bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition)
{
return SendKeyboardKey_Internal(timestamp, ID, key, keyPosition);
}
void UpdateKeyboardstate(float deltaTime)
{
for (KeyState& state : KeyboardState.KeyState)
{ {
return KeyboardState.KeyState[ToUnderlying(scanCode)].Position == KeyPosition::Down; if (state.Position == KeyPosition::Down)
{
if (state.Time < 0.0f)
{
state.Time = 0.0f;
}
else
{
state.Time += deltaTime;
}
}
else
{
state.Time = -1.0f;
}
} }
}
bool IsKeyPressed(ScanCode scanCode) bool IsKeyDown(ScanCode scanCode)
{ {
auto& keyState = KeyboardState.KeyState[ToUnderlying(scanCode)]; return KeyboardState.KeyState[ToUnderlying(scanCode)].Position == KeyPosition::Down;
return keyState.Position == KeyPosition::Down && keyState.Time == 0.0f; }
}
KeyMod GetKeyModState() bool IsKeyPressed(ScanCode scanCode)
{ {
auto& keyboardState = KeyboardState; auto& keyState = KeyboardState.KeyState[ToUnderlying(scanCode)];
return keyboardState.KeyModState; return keyState.Position == KeyPosition::Down && keyState.Time == 0.0f;
} }
KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState) KeyMod GetKeyModState()
{ {
return GetKeyCodeFromDefaultMapping(scanCode, keyModState); auto& keyboardState = KeyboardState;
} return keyboardState.KeyModState;
}
static_assert(sizeof(KeyPosition) == sizeof(bool)); KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState)
static_assert(ToUnderlying(KeyPosition::Down) == true); {
static_assert(ToUnderlying(KeyPosition::Up) == false); return GetKeyCodeFromDefaultMapping(scanCode, keyModState);
static_assert(sizeof(ScanCode) == sizeof(uint16)); }
static_assert(ToUnderlying(ScanCode::Count) == 512);
} // namespace Juliet static_assert(sizeof(KeyPosition) == sizeof(bool));
static_assert(ToUnderlying(KeyPosition::Down) == true);
static_assert(ToUnderlying(KeyPosition::Up) == false);
static_assert(sizeof(ScanCode) == sizeof(uint16));
static_assert(ToUnderlying(ScanCode::Count) == 512);
+191 -194
View File
@@ -1,204 +1,201 @@
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
#include <Core/Common/EnumUtils.h> #include <Core/Common/EnumUtils.h>
#include <Core/HAL/Event/KeyboardMapping.h> #include <Core/HAL/Event/KeyboardMapping.h>
#include <Core/HAL/Keyboard/KeyCode.h> #include <Core/HAL/Keyboard/KeyCode.h>
#include <Core/HAL/Keyboard/ScanCode.h> #include <Core/HAL/Keyboard/ScanCode.h>
namespace Juliet namespace
{ {
namespace // clang-format off
KeyCode UnshiftedDefaultSymbols[] = {
KeyCode::Num1,
KeyCode::Num2,
KeyCode::Num3,
KeyCode::Num4,
KeyCode::Num5,
KeyCode::Num6,
KeyCode::Num7,
KeyCode::Num8,
KeyCode::Num9,
KeyCode::Num0,
KeyCode::Return,
KeyCode::Escape,
KeyCode::Backspace,
KeyCode::Tab,
KeyCode::Space,
KeyCode::Minus,
KeyCode::Equals,
KeyCode::LeftBracket,
KeyCode::RightBracket,
KeyCode::Backslash,
KeyCode::Hash,
KeyCode::Semicolon,
KeyCode::Apostrophe,
KeyCode::GraveAccent,
KeyCode::Comma,
KeyCode::Period,
KeyCode::Slash,
};
KeyCode ShiftedDefaultSymbols[] = {
KeyCode::ExclamationPoint,
KeyCode::CommercialAt,
KeyCode::Hash,
KeyCode::Dollar,
KeyCode::Percent,
KeyCode::Caret,
KeyCode::Ampersand,
KeyCode::Asterisk,
KeyCode::LeftParenthesis,
KeyCode::RightParenthesis,
KeyCode::Return,
KeyCode::Escape,
KeyCode::Backspace,
KeyCode::Tab,
KeyCode::Space,
KeyCode::Underscore,
KeyCode::Plus,
KeyCode::LeftBrace,
KeyCode::RightBrace,
KeyCode::Pipe,
KeyCode::Hash,
KeyCode::Colon,
KeyCode::DoubleApostrophe,
KeyCode::Tilde,
KeyCode::LessThan,
KeyCode::GreaterThan,
KeyCode::QuestionMark,
};
// clang-format on
KeyCode GetNonPrintableKeys(ScanCode scanCode)
{ {
// clang-format off switch (scanCode)
KeyCode UnshiftedDefaultSymbols[] = {
KeyCode::Num1,
KeyCode::Num2,
KeyCode::Num3,
KeyCode::Num4,
KeyCode::Num5,
KeyCode::Num6,
KeyCode::Num7,
KeyCode::Num8,
KeyCode::Num9,
KeyCode::Num0,
KeyCode::Return,
KeyCode::Escape,
KeyCode::Backspace,
KeyCode::Tab,
KeyCode::Space,
KeyCode::Minus,
KeyCode::Equals,
KeyCode::LeftBracket,
KeyCode::RightBracket,
KeyCode::Backslash,
KeyCode::Hash,
KeyCode::Semicolon,
KeyCode::Apostrophe,
KeyCode::GraveAccent,
KeyCode::Comma,
KeyCode::Period,
KeyCode::Slash,
};
KeyCode ShiftedDefaultSymbols[] = {
KeyCode::ExclamationPoint,
KeyCode::CommercialAt,
KeyCode::Hash,
KeyCode::Dollar,
KeyCode::Percent,
KeyCode::Caret,
KeyCode::Ampersand,
KeyCode::Asterisk,
KeyCode::LeftParenthesis,
KeyCode::RightParenthesis,
KeyCode::Return,
KeyCode::Escape,
KeyCode::Backspace,
KeyCode::Tab,
KeyCode::Space,
KeyCode::Underscore,
KeyCode::Plus,
KeyCode::LeftBrace,
KeyCode::RightBrace,
KeyCode::Pipe,
KeyCode::Hash,
KeyCode::Colon,
KeyCode::DoubleApostrophe,
KeyCode::Tilde,
KeyCode::LessThan,
KeyCode::GreaterThan,
KeyCode::QuestionMark,
};
// clang-format on
KeyCode GetNonPrintableKeys(ScanCode scanCode)
{ {
switch (scanCode) case ScanCode::Delete: return KeyCode::Delete;
{ case ScanCode::CapsLock: return KeyCode::CapsLock;
case ScanCode::Delete: return KeyCode::Delete; case ScanCode::F1: return KeyCode::F1;
case ScanCode::CapsLock: return KeyCode::CapsLock; case ScanCode::F2: return KeyCode::F2;
case ScanCode::F1: return KeyCode::F1; case ScanCode::F3: return KeyCode::F3;
case ScanCode::F2: return KeyCode::F2; case ScanCode::F4: return KeyCode::F4;
case ScanCode::F3: return KeyCode::F3; case ScanCode::F5: return KeyCode::F5;
case ScanCode::F4: return KeyCode::F4; case ScanCode::F6: return KeyCode::F6;
case ScanCode::F5: return KeyCode::F5; case ScanCode::F7: return KeyCode::F7;
case ScanCode::F6: return KeyCode::F6; case ScanCode::F8: return KeyCode::F8;
case ScanCode::F7: return KeyCode::F7; case ScanCode::F9: return KeyCode::F9;
case ScanCode::F8: return KeyCode::F8; case ScanCode::F10: return KeyCode::F10;
case ScanCode::F9: return KeyCode::F9; case ScanCode::F11: return KeyCode::F11;
case ScanCode::F10: return KeyCode::F10; case ScanCode::F12: return KeyCode::F12;
case ScanCode::F11: return KeyCode::F11; case ScanCode::PrintScreen: return KeyCode::PrintScreen;
case ScanCode::F12: return KeyCode::F12; case ScanCode::ScrollLock: return KeyCode::ScrollLock;
case ScanCode::PrintScreen: return KeyCode::PrintScreen; case ScanCode::Pause: return KeyCode::Pause;
case ScanCode::ScrollLock: return KeyCode::ScrollLock; case ScanCode::Insert: return KeyCode::Insert;
case ScanCode::Pause: return KeyCode::Pause; case ScanCode::Home: return KeyCode::Home;
case ScanCode::Insert: return KeyCode::Insert; case ScanCode::PageUp: return KeyCode::PageUp;
case ScanCode::Home: return KeyCode::Home; case ScanCode::End: return KeyCode::End;
case ScanCode::PageUp: return KeyCode::PageUp; case ScanCode::PageDown: return KeyCode::PageDown;
case ScanCode::End: return KeyCode::End; case ScanCode::RightArrow: return KeyCode::RightArrow;
case ScanCode::PageDown: return KeyCode::PageDown; case ScanCode::LeftArrow: return KeyCode::LeftArrow;
case ScanCode::RightArrow: return KeyCode::RightArrow; case ScanCode::DownArrow: return KeyCode::DownArrow;
case ScanCode::LeftArrow: return KeyCode::LeftArrow; case ScanCode::UpArrow: return KeyCode::UpArrow;
case ScanCode::DownArrow: return KeyCode::DownArrow; case ScanCode::NumlockClear: return KeyCode::NumlockClear;
case ScanCode::UpArrow: return KeyCode::UpArrow; case ScanCode::KeyPad_Divide: return KeyCode::KeyPad_Divide;
case ScanCode::NumlockClear: return KeyCode::NumlockClear; case ScanCode::KeyPad_Multiply: return KeyCode::KeyPad_Multiply;
case ScanCode::KeyPad_Divide: return KeyCode::KeyPad_Divide; case ScanCode::KeyPad_Minus: return KeyCode::KeyPad_Minus;
case ScanCode::KeyPad_Multiply: return KeyCode::KeyPad_Multiply; case ScanCode::KeyPad_Plus: return KeyCode::KeyPad_Plus;
case ScanCode::KeyPad_Minus: return KeyCode::KeyPad_Minus; case ScanCode::KeyPad_Enter: return KeyCode::KeyPad_Enter;
case ScanCode::KeyPad_Plus: return KeyCode::KeyPad_Plus; case ScanCode::KeyPad_Num1: return KeyCode::KeyPad_Num1;
case ScanCode::KeyPad_Enter: return KeyCode::KeyPad_Enter; case ScanCode::KeyPad_Num2: return KeyCode::KeyPad_Num2;
case ScanCode::KeyPad_Num1: return KeyCode::KeyPad_Num1; case ScanCode::KeyPad_Num3: return KeyCode::KeyPad_Num3;
case ScanCode::KeyPad_Num2: return KeyCode::KeyPad_Num2; case ScanCode::KeyPad_Num4: return KeyCode::KeyPad_Num4;
case ScanCode::KeyPad_Num3: return KeyCode::KeyPad_Num3; case ScanCode::KeyPad_Num5: return KeyCode::KeyPad_Num5;
case ScanCode::KeyPad_Num4: return KeyCode::KeyPad_Num4; case ScanCode::KeyPad_Num6: return KeyCode::KeyPad_Num6;
case ScanCode::KeyPad_Num5: return KeyCode::KeyPad_Num5; case ScanCode::KeyPad_Num7: return KeyCode::KeyPad_Num7;
case ScanCode::KeyPad_Num6: return KeyCode::KeyPad_Num6; case ScanCode::KeyPad_Num8: return KeyCode::KeyPad_Num8;
case ScanCode::KeyPad_Num7: return KeyCode::KeyPad_Num7; case ScanCode::KeyPad_Num9: return KeyCode::KeyPad_Num9;
case ScanCode::KeyPad_Num8: return KeyCode::KeyPad_Num8; case ScanCode::KeyPad_Num0: return KeyCode::KeyPad_Num0;
case ScanCode::KeyPad_Num9: return KeyCode::KeyPad_Num9; case ScanCode::KeyPad_Period: return KeyCode::KeyPad_Period;
case ScanCode::KeyPad_Num0: return KeyCode::KeyPad_Num0; case ScanCode::Power: return KeyCode::Power;
case ScanCode::KeyPad_Period: return KeyCode::KeyPad_Period; case ScanCode::KeyPad_Equals: return KeyCode::KeyPad_Equals;
case ScanCode::Power: return KeyCode::Power; case ScanCode::F13: return KeyCode::F13;
case ScanCode::KeyPad_Equals: return KeyCode::KeyPad_Equals; case ScanCode::F14: return KeyCode::F14;
case ScanCode::F13: return KeyCode::F13; case ScanCode::F15: return KeyCode::F15;
case ScanCode::F14: return KeyCode::F14; case ScanCode::F16: return KeyCode::F16;
case ScanCode::F15: return KeyCode::F15; case ScanCode::F17: return KeyCode::F17;
case ScanCode::F16: return KeyCode::F16; case ScanCode::F18: return KeyCode::F18;
case ScanCode::F17: return KeyCode::F17; case ScanCode::F19: return KeyCode::F19;
case ScanCode::F18: return KeyCode::F18; case ScanCode::F20: return KeyCode::F20;
case ScanCode::F19: return KeyCode::F19; case ScanCode::F21: return KeyCode::F21;
case ScanCode::F20: return KeyCode::F20; case ScanCode::F22: return KeyCode::F22;
case ScanCode::F21: return KeyCode::F21; case ScanCode::F23: return KeyCode::F23;
case ScanCode::F22: return KeyCode::F22; case ScanCode::F24: return KeyCode::F24;
case ScanCode::F23: return KeyCode::F23; case ScanCode::Mute: return KeyCode::Mute;
case ScanCode::F24: return KeyCode::F24; case ScanCode::VolumeUp: return KeyCode::VolumeUp;
case ScanCode::Mute: return KeyCode::Mute; case ScanCode::VolumeDown: return KeyCode::VolumeDown;
case ScanCode::VolumeUp: return KeyCode::VolumeUp; case ScanCode::KeyPad_Comma: return KeyCode::KeyPad_Comma;
case ScanCode::VolumeDown: return KeyCode::VolumeDown; case ScanCode::LeftControl: return KeyCode::LeftControl;
case ScanCode::KeyPad_Comma: return KeyCode::KeyPad_Comma; case ScanCode::LeftShift: return KeyCode::LeftShift;
case ScanCode::LeftControl: return KeyCode::LeftControl; case ScanCode::LeftAlt: return KeyCode::LeftAlt;
case ScanCode::LeftShift: return KeyCode::LeftShift; case ScanCode::LeftOSCommand: return KeyCode::LeftOSCommand;
case ScanCode::LeftAlt: return KeyCode::LeftAlt; case ScanCode::RightControl: return KeyCode::RightControl;
case ScanCode::LeftOSCommand: return KeyCode::LeftOSCommand; case ScanCode::RightShift: return KeyCode::RightShift;
case ScanCode::RightControl: return KeyCode::RightControl; case ScanCode::RightAlt: return KeyCode::RightAlt;
case ScanCode::RightShift: return KeyCode::RightShift; case ScanCode::RightOSCommand: return KeyCode::RightOSCommand;
case ScanCode::RightAlt: return KeyCode::RightAlt; case ScanCode::Sleep: return KeyCode::Sleep;
case ScanCode::RightOSCommand: return KeyCode::RightOSCommand; case ScanCode::WakeUp: return KeyCode::WakeUp;
case ScanCode::Sleep: return KeyCode::Sleep; case ScanCode::Media_NextTrack: return KeyCode::Media_NextTrack;
case ScanCode::WakeUp: return KeyCode::WakeUp; case ScanCode::Media_PreviousTrack: return KeyCode::Media_PreviousTrack;
case ScanCode::Media_NextTrack: return KeyCode::Media_NextTrack; case ScanCode::Media_Stop: return KeyCode::Media_Stop;
case ScanCode::Media_PreviousTrack: return KeyCode::Media_PreviousTrack; case ScanCode::Media_Eject: return KeyCode::Media_Eject;
case ScanCode::Media_Stop: return KeyCode::Media_Stop; case ScanCode::Media_PlayPause: return KeyCode::Media_PlayPause;
case ScanCode::Media_Eject: return KeyCode::Media_Eject; case ScanCode::Media_Select: return KeyCode::Media_Select;
case ScanCode::Media_PlayPause: return KeyCode::Media_PlayPause; default: return KeyCode::Unknown;
case ScanCode::Media_Select: return KeyCode::Media_Select;
default: return KeyCode::Unknown;
}
} }
} // namespace
KeyCode GetKeyCodeFromDefaultMapping(ScanCode scanCode, KeyMod keyModState)
{
if (scanCode <= ScanCode::Unknown || scanCode > ScanCode::Count)
{
Assert(false , "Unsupported KeyCode (out of bounds)");
return KeyCode::Unknown;
}
if (scanCode < ScanCode::A)
{
return KeyCode::Unknown;
}
// Handles A-Z characters
if (scanCode <= ScanCode::Z)
{
const auto index = scanCode - ScanCode::A;
bool isShiftPressed = (keyModState & KeyMod::Shift) != KeyMod::None;
if ((keyModState & KeyMod::CapsLock) != KeyMod::None)
{
isShiftPressed = !isShiftPressed;
}
if (isShiftPressed)
{
return ToEnum<KeyCode>(static_cast<uint32>('A') + index);
}
return ToEnum<KeyCode>(static_cast<uint32>('a') + index);
}
// Handles Num1 to Num0
if (scanCode <= ScanCode::Num0)
{
const auto index = scanCode - ScanCode::Num1;
const bool isShiftPressed = (keyModState & KeyMod::Shift) != KeyMod::None;
if (isShiftPressed)
{
return ShiftedDefaultSymbols[index];
}
return UnshiftedDefaultSymbols[index];
}
// Handle everything else (characters that do not convert to ASCII code)
return GetNonPrintableKeys(scanCode);
} }
} // namespace Juliet } // namespace
KeyCode GetKeyCodeFromDefaultMapping(ScanCode scanCode, KeyMod keyModState)
{
if (scanCode <= ScanCode::Unknown || scanCode > ScanCode::Count)
{
Assert(false , "Unsupported KeyCode (out of bounds)");
return KeyCode::Unknown;
}
if (scanCode < ScanCode::A)
{
return KeyCode::Unknown;
}
// Handles A-Z characters
if (scanCode <= ScanCode::Z)
{
const auto index = scanCode - ScanCode::A;
bool isShiftPressed = (keyModState & KeyMod::Shift) != KeyMod::None;
if ((keyModState & KeyMod::CapsLock) != KeyMod::None)
{
isShiftPressed = !isShiftPressed;
}
if (isShiftPressed)
{
return ToEnum<KeyCode>(static_cast<uint32>('A') + index);
}
return ToEnum<KeyCode>(static_cast<uint32>('a') + index);
}
// Handles Num1 to Num0
if (scanCode <= ScanCode::Num0)
{
const auto index = scanCode - ScanCode::Num1;
const bool isShiftPressed = (keyModState & KeyMod::Shift) != KeyMod::None;
if (isShiftPressed)
{
return ShiftedDefaultSymbols[index];
}
return UnshiftedDefaultSymbols[index];
}
// Handle everything else (characters that do not convert to ASCII code)
return GetNonPrintableKeys(scanCode);
}
+3 -6
View File
@@ -1,10 +1,7 @@
#pragma once #pragma once
#include <Core/HAL/Keyboard/KeyCode.h> #include <Core/HAL/Keyboard/KeyCode.h>
#include <Core/HAL/Keyboard/ScanCode.h> #include <Core/HAL/Keyboard/ScanCode.h>
namespace Juliet // Transforms ScanCode into KeyCode using the default US ASCII Mapping
{ extern KeyCode GetKeyCodeFromDefaultMapping(ScanCode scanCode, KeyMod keyModState);
// Transforms ScanCode into KeyCode using the default US ASCII Mapping
extern KeyCode GetKeyCodeFromDefaultMapping(ScanCode scanCode, KeyMod keyModState);
} // namespace Juliet
+4 -7
View File
@@ -1,12 +1,9 @@
#pragma once #pragma once
#include <Core/HAL/Keyboard/Keyboard.h> #include <Core/HAL/Keyboard/Keyboard.h>
#include <Core/HAL/Keyboard/KeyCode.h> #include <Core/HAL/Keyboard/KeyCode.h>
namespace Juliet extern bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition);
{ extern void UpdateKeyboardstate(float deltaTime);
extern bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition);
extern void UpdateKeyboardstate(float deltaTime);
extern const KeyboardID kGlobalKeyboardID; extern const KeyboardID kGlobalKeyboardID;
} // namespace Juliet
+116 -119
View File
@@ -1,158 +1,155 @@
#include <Core/Common/EnumUtils.h> #include <Core/Common/EnumUtils.h>
#include <Core/HAL/Display/Window.h> #include <Core/HAL/Display/Window.h>
#include <Core/HAL/Event/Mouse_Private.h> #include <Core/HAL/Event/Mouse_Private.h>
#include <Core/HAL/Event/SystemEvent.h> #include <Core/HAL/Event/SystemEvent.h>
#include <Core/HAL/Mouse/Mouse.h> #include <Core/HAL/Mouse/Mouse.h>
namespace Juliet namespace
{ {
namespace Mouse MouseState;
void ConstraintMousePositionToWindow(Mouse& mouseState, Window* window, float& x, float& y)
{ {
Mouse MouseState; float x_min = 0.f, x_max = (float)(window->Width - 1);
float y_min = 0.f, y_max = (float)(window->Height - 1);
void ConstraintMousePositionToWindow(Mouse& mouseState, Window* window, float& x, float& y) if (x >= (x_max + 1))
{ {
float x_min = 0.f, x_max = (float)(window->Width - 1); x = std::max(x_max, mouseState.X_Previous);
float y_min = 0.f, y_max = (float)(window->Height - 1);
if (x >= (x_max + 1))
{
x = std::max(x_max, mouseState.X_Previous);
}
x = std::max(x, x_min);
if (y >= (y_max + 1))
{
y = std::max(y_max, mouseState.Y_Previous);
}
y = std::max(y, y_min);
} }
x = std::max(x, x_min);
void SendMouseMotion_Internal(uint64 timestamp, Window* window, MouseID mouseID, float x, float y) if (y >= (y_max + 1))
{ {
auto& mouseState = GetMouseState(); y = std::max(y_max, mouseState.Y_Previous);
float xDisplacement = 0.0f;
float yDisplacement = 0.0f;
ConstraintMousePositionToWindow(mouseState, window, x, y);
if (mouseState.HasPosition)
{
xDisplacement = x - mouseState.X_Previous;
yDisplacement = y - mouseState.Y_Previous;
}
if (mouseState.HasPosition && xDisplacement == 0.0f && yDisplacement == 0.0f)
{
// Skip it because state didnt change
return;
}
mouseState.X = x;
mouseState.Y = y;
mouseState.HasPosition = true;
mouseState.X_Previous = x;
mouseState.Y_Previous = y;
mouseState.DeltaX += xDisplacement;
mouseState.DeltaY += yDisplacement;
SystemEvent evt;
evt.Type = EventType::Mouse_Move;
evt.Timestamp = timestamp;
evt.Data.MouseMovement.WindowID = window->ID;
evt.Data.MouseMovement.AssociatedMouseID = mouseID;
evt.Data.MouseMovement.X = x;
evt.Data.MouseMovement.Y = y;
evt.Data.MouseMovement.X_Displacement = xDisplacement;
evt.Data.MouseMovement.Y_Displacement = yDisplacement;
evt.Data.MouseMovement.ButtonState = mouseState.ButtonState;
AddEvent(evt);
} }
y = std::max(y, y_min);
} // namespace
constexpr MouseID kGlobalMouseID = 0;
Mouse& GetMouseState()
{
return MouseState;
} }
void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y) void SendMouseMotion_Internal(uint64 timestamp, Window* window, MouseID mouseID, float x, float y)
{ {
// TODO : Update Mouse focus and send Mouse Enter / Mouse Leave event auto& mouseState = GetMouseState();
float xDisplacement = 0.0f;
float yDisplacement = 0.0f;
SendMouseMotion_Internal(timestamp, window, ID, x, y); ConstraintMousePositionToWindow(mouseState, window, x, y);
}
void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed) if (mouseState.HasPosition)
{
Mouse& mouseState = GetMouseState();
MouseButton flags = mouseState.ButtonState;
auto type = EventType::None;
if (pressed)
{ {
type = EventType::Mouse_ButtonPressed; xDisplacement = x - mouseState.X_Previous;
flags |= button; yDisplacement = y - mouseState.Y_Previous;
}
else
{
type = EventType::Mouse_ButtonReleased;
flags = flags & ~button;
} }
if (flags == mouseState.ButtonState) if (mouseState.HasPosition && xDisplacement == 0.0f && yDisplacement == 0.0f)
{ {
// Skip it because state didnt change
return; return;
} }
mouseState.ButtonState = flags; mouseState.X = x;
mouseState.Y = y;
mouseState.HasPosition = true;
mouseState.X_Previous = x;
mouseState.Y_Previous = y;
mouseState.DeltaX += xDisplacement;
mouseState.DeltaY += yDisplacement;
// TODO : Send Event!
SystemEvent evt; SystemEvent evt;
evt.Timestamp = timestamp; evt.Type = EventType::Mouse_Move;
evt.Type = type; evt.Timestamp = timestamp;
evt.Data.MouseButton.AssociatedMouseID = mouseID; evt.Data.MouseMovement.WindowID = window->ID;
evt.Data.MouseButton.WindowID = window->ID; evt.Data.MouseMovement.AssociatedMouseID = mouseID;
evt.Data.MouseButton.ButtonState = button; evt.Data.MouseMovement.X = x;
evt.Data.MouseButton.X = mouseState.X; evt.Data.MouseMovement.Y = y;
evt.Data.MouseButton.Y = mouseState.Y; evt.Data.MouseMovement.X_Displacement = xDisplacement;
evt.Data.MouseButton.IsPressed = pressed; evt.Data.MouseMovement.Y_Displacement = yDisplacement;
evt.Data.MouseMovement.ButtonState = mouseState.ButtonState;
AddEvent(evt); AddEvent(evt);
} }
bool IsMouseButtonDown(MouseButton button) } // namespace
constexpr MouseID kGlobalMouseID = 0;
Mouse& GetMouseState()
{
return MouseState;
}
void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y)
{
// TODO : Update Mouse focus and send Mouse Enter / Mouse Leave event
SendMouseMotion_Internal(timestamp, window, ID, x, y);
}
void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed)
{
Mouse& mouseState = GetMouseState();
MouseButton flags = mouseState.ButtonState;
auto type = EventType::None;
if (pressed)
{ {
auto& mouseState = GetMouseState(); type = EventType::Mouse_ButtonPressed;
return (mouseState.ButtonState & button) != MouseButton::None; flags |= button;
}
else
{
type = EventType::Mouse_ButtonReleased;
flags = flags & ~button;
} }
MousePosition GetMousePosition() if (flags == mouseState.ButtonState)
{ {
auto& mouseState = GetMouseState(); return;
return { .X = mouseState.X, .Y = mouseState.Y };
} }
MousePosition GetMouseDelta() mouseState.ButtonState = flags;
{
auto& mouseState = GetMouseState();
return { .X = mouseState.DeltaX, .Y = mouseState.DeltaY };
}
MouseButton GetMouseButtonState() // TODO : Send Event!
{ SystemEvent evt;
const auto& mouseState = GetMouseState(); evt.Timestamp = timestamp;
return mouseState.ButtonState; evt.Type = type;
} evt.Data.MouseButton.AssociatedMouseID = mouseID;
evt.Data.MouseButton.WindowID = window->ID;
evt.Data.MouseButton.ButtonState = button;
evt.Data.MouseButton.X = mouseState.X;
evt.Data.MouseButton.Y = mouseState.Y;
evt.Data.MouseButton.IsPressed = pressed;
AddEvent(evt);
}
void UpdateMouseState() bool IsMouseButtonDown(MouseButton button)
{ {
auto& mouseState = GetMouseState(); auto& mouseState = GetMouseState();
mouseState.DeltaX = 0.0f; return (mouseState.ButtonState & button) != MouseButton::None;
mouseState.DeltaY = 0.0f; }
}
MousePosition GetMousePosition()
{
auto& mouseState = GetMouseState();
return { .X = mouseState.X, .Y = mouseState.Y };
}
MousePosition GetMouseDelta()
{
auto& mouseState = GetMouseState();
return { .X = mouseState.DeltaX, .Y = mouseState.DeltaY };
}
MouseButton GetMouseButtonState()
{
const auto& mouseState = GetMouseState();
return mouseState.ButtonState;
}
void UpdateMouseState()
{
auto& mouseState = GetMouseState();
mouseState.DeltaX = 0.0f;
mouseState.DeltaY = 0.0f;
}
} // namespace Juliet
+18 -21
View File
@@ -1,32 +1,29 @@
#pragma once #pragma once
#include <Core/HAL/Mouse/Mouse.h> #include <Core/HAL/Mouse/Mouse.h>
namespace Juliet struct Window;
struct Mouse
{ {
struct Window; float X;
float Y;
struct Mouse float X_Previous;
{ float Y_Previous;
float X;
float Y;
float X_Previous; float DeltaX;
float Y_Previous; float DeltaY;
float DeltaX; MouseButton ButtonState;
float DeltaY;
MouseButton ButtonState; bool HasPosition : 1;
};
bool HasPosition : 1; Mouse& GetMouseState();
};
Mouse& GetMouseState(); extern void UpdateMouseState();
extern void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y);
extern void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed);
extern void UpdateMouseState(); extern const MouseID kGlobalMouseID;
extern void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y);
extern void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed);
extern const MouseID kGlobalMouseID;
} // namespace Juliet
+65 -68
View File
@@ -1,4 +1,4 @@
#include <Core/HAL/Display/DisplayDevice.h> #include <Core/HAL/Display/DisplayDevice.h>
#include <Core/HAL/Event/SystemEvent.h> #include <Core/HAL/Event/SystemEvent.h>
#include <Core/HAL/Event/Keyboard_Private.h> #include <Core/HAL/Event/Keyboard_Private.h>
@@ -9,92 +9,89 @@
#pragma pop_macro("global") #pragma pop_macro("global")
namespace Juliet namespace
{ {
namespace // TODO : make my own queue / using vector
std::queue<SystemEvent> eventQueue;
// Update all systems event loops and gather events into the main queue
void PumpEvents()
{ {
// TODO : make my own queue / using vector if (DisplayDevice* displayDevice = GetDisplayDevice())
std::queue<SystemEvent> eventQueue;
// Update all systems event loops and gather events into the main queue
void PumpEvents()
{ {
if (DisplayDevice* displayDevice = GetDisplayDevice()) displayDevice->PumpEvents(displayDevice);
{
displayDevice->PumpEvents(displayDevice);
}
} }
bool AddEvent_Internal(const SystemEvent& event)
{
auto& newEvent = eventQueue.emplace();
newEvent = event;
// TODO : Logs
return true;
}
} // namespace
bool GetEvent(SystemEvent& event)
{
return WaitEvent(event, 0);
} }
bool WaitEvent(SystemEvent& event, int32 timeoutInNS /* = -1 */) bool AddEvent_Internal(const SystemEvent& event)
{ {
using namespace std::chrono; auto& newEvent = eventQueue.emplace();
newEvent = event;
// Handle the "Infinite Wait" and "Timed Wait" logic // TODO : Logs
const bool isInfinite = (timeoutInNS < 0);
const nanoseconds timeout(timeoutInNS);
const auto startTime = steady_clock::now();
while (true) return true;
}
} // namespace
bool GetEvent(SystemEvent& event)
{
return WaitEvent(event, 0);
}
bool WaitEvent(SystemEvent& event, int32 timeoutInNS /* = -1 */)
{
using namespace std::chrono;
// Handle the "Infinite Wait" and "Timed Wait" logic
const bool isInfinite = (timeoutInNS < 0);
const nanoseconds timeout(timeoutInNS);
const auto startTime = steady_clock::now();
while (true)
{
PumpEvents();
if (!eventQueue.empty())
{ {
PumpEvents(); event = eventQueue.front();
eventQueue.pop();
return true;
}
if (!eventQueue.empty()) // If timeout is 0, we only check once (PumpEvents already ran)
{ if (timeoutInNS == 0)
event = eventQueue.front(); {
eventQueue.pop(); break;
return true; }
}
// If timeout is 0, we only check once (PumpEvents already ran) // Check if we have exceeded our time limit
if (timeoutInNS == 0) if (!isInfinite)
{
auto elapsed = steady_clock::now() - startTime;
if (elapsed >= timeout)
{ {
break; break;
} }
// Check if we have exceeded our time limit
if (!isInfinite)
{
auto elapsed = steady_clock::now() - startTime;
if (elapsed >= timeout)
{
break;
}
}
} }
return false;
} }
bool AddEvent(SystemEvent& event) return false;
}
bool AddEvent(SystemEvent& event)
{
if (event.Timestamp == 0)
{ {
if (event.Timestamp == 0) event.Timestamp = 1; // TODO : Clock::Now();
{
event.Timestamp = 1; // TODO : Clock::Now();
}
return AddEvent_Internal(event);
} }
void Events_NewFrame(float deltaTime) return AddEvent_Internal(event);
{ }
UpdateKeyboardstate(deltaTime);
UpdateMouseState(); void Events_NewFrame(float deltaTime)
} {
UpdateKeyboardstate(deltaTime);
UpdateMouseState();
}
} // namespace Juliet
+3 -3
View File
@@ -1,8 +1,8 @@
#pragma once #pragma once
#include <Core/HAL/Keyboard/ScanCode.h> #include <Core/HAL/Keyboard/ScanCode.h>
namespace Juliet::Win32 namespace Win32
{ {
// Conversion table from Win32 scan code to HID Usage Page (see Keyboard.h) // Conversion table from Win32 scan code to HID Usage Page (see Keyboard.h)
// https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag // https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag
@@ -267,4 +267,4 @@ namespace Juliet::Win32
}; };
// clang-format on // clang-format on
} // namespace Juliet::Win32 } // namespace Win32
+10 -13
View File
@@ -1,21 +1,18 @@
#include <Core/HAL/Display/Window.h> #include <Core/HAL/Display/Window.h>
#include <Core/HAL/Event/SystemEvent.h> #include <Core/HAL/Event/SystemEvent.h>
#include <Core/HAL/Event/WindowEvent.h> #include <Core/HAL/Event/WindowEvent.h>
namespace Juliet bool SendWindowEvent(Window* window, EventType type)
{ {
bool SendWindowEvent(Window* window, EventType type) Assert(window);
{
Assert(window);
SystemEvent evt; SystemEvent evt;
evt.Timestamp = 0; evt.Timestamp = 0;
evt.Type = type; evt.Type = type;
evt.Data.Window.AssociatedWindowID = window->ID; evt.Data.Window.AssociatedWindowID = window->ID;
bool evtPosted = AddEvent(evt); bool evtPosted = AddEvent(evt);
return evtPosted; return evtPosted;
} }
} // namespace Juliet
+4 -7
View File
@@ -1,9 +1,6 @@
#pragma once #pragma once
namespace Juliet struct Window;
{ enum class EventType : uint32;
struct Window;
enum class EventType : uint32;
extern bool SendWindowEvent(Window* window, EventType type); extern bool SendWindowEvent(Window* window, EventType type);
} // namespace Juliet
+80 -83
View File
@@ -1,4 +1,4 @@
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/HAL/Filesystem/Filesystem.h> #include <Core/HAL/Filesystem/Filesystem.h>
@@ -9,93 +9,90 @@
#include <Core/Logging/LogTypes.h> #include <Core/Logging/LogTypes.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
namespace Juliet namespace
{ {
namespace String CachedBasePath = {};
{ String CachedAssetBasePath = {};
String CachedBasePath = {};
String CachedAssetBasePath = {};
bool DirectoryExists(const char* path) bool DirectoryExists(const char* path)
{
Assert(path);
DWORD attributes = GetFileAttributesA(path);
return (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY);
}
} // namespace
String GetBasePath()
{
Assert(IsValid(CachedBasePath));
return CachedBasePath;
}
String GetAssetBasePath()
{
Assert(IsValid(CachedAssetBasePath));
return CachedAssetBasePath;
}
[[nodiscard]] String GetAssetPath(NonNullPtr<Arena> arena, String filename)
{
Assert(IsValid(CachedAssetBasePath));
Assert(IsValid(filename));
size_t totalSize = CachedAssetBasePath.Size + filename.Size + 1;
char* buffer = ArenaPushArray<char>(arena, totalSize);
Assert(buffer);
juliet_snprintf(buffer, totalSize, "%s%s", CStr(CachedAssetBasePath), CStr(filename));
return { buffer, totalSize - 1 };
}
bool IsAbsolutePath(String path)
{
if (!IsValid(path))
{
return false;
}
return Platform::IsAbsolutePath(path);
}
void InitFilesystem(NonNullPtr<Arena> arena)
{
CachedBasePath = Platform::GetBasePath(arena);
String basePath = GetBasePath();
Assert(IsValid(basePath));
// Probe candidate paths for compiled shader directory
// 1. Shipping layout: Assets/Shaders/ next to the exe
// 2. Dev layout: ../../Assets/compiled/ (exe is in bin/x64Clang-<Config>/)
constexpr const char* kCandidates[] = { "Assets/Shaders/", "../../Assets/compiled/" };
for (const char* candidate : kCandidates)
{
char probePath[512];
juliet_snprintf(probePath, sizeof(probePath), "%s%s", CStr(basePath), candidate);
if (DirectoryExists(probePath))
{ {
Assert(path); size_t len = strlen(probePath);
DWORD attributes = GetFileAttributesA(path); if (char* buffer = ArenaPushArray<char>(arena, len + 1 JULIET_DEBUG_PARAM("CachedAssetBasePath")))
return (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY);
}
} // namespace
String GetBasePath()
{
Assert(IsValid(CachedBasePath));
return CachedBasePath;
}
String GetAssetBasePath()
{
Assert(IsValid(CachedAssetBasePath));
return CachedAssetBasePath;
}
[[nodiscard]] String GetAssetPath(NonNullPtr<Arena> arena, String filename)
{
Assert(IsValid(CachedAssetBasePath));
Assert(IsValid(filename));
size_t totalSize = CachedAssetBasePath.Size + filename.Size + 1;
char* buffer = ArenaPushArray<char>(arena, totalSize);
Assert(buffer);
juliet_snprintf(buffer, totalSize, "%s%s", CStr(CachedAssetBasePath), CStr(filename));
return { buffer, totalSize - 1 };
}
bool IsAbsolutePath(String path)
{
if (!IsValid(path))
{
return false;
}
return Platform::IsAbsolutePath(path);
}
void InitFilesystem(NonNullPtr<Arena> arena)
{
CachedBasePath = Platform::GetBasePath(arena);
String basePath = GetBasePath();
Assert(IsValid(basePath));
// Probe candidate paths for compiled shader directory
// 1. Shipping layout: Assets/Shaders/ next to the exe
// 2. Dev layout: ../../Assets/compiled/ (exe is in bin/x64Clang-<Config>/)
constexpr const char* kCandidates[] = { "Assets/Shaders/", "../../Assets/compiled/" };
for (const char* candidate : kCandidates)
{
char probePath[512];
juliet_snprintf(probePath, sizeof(probePath), "%s%s", CStr(basePath), candidate);
if (DirectoryExists(probePath))
{ {
size_t len = strlen(probePath); juliet_snprintf(buffer, len + 1, "%s", probePath);
if (char* buffer = ArenaPushArray<char>(arena, len + 1 JULIET_DEBUG_PARAM("CachedAssetBasePath"))) CachedAssetBasePath = { buffer, len };
{ Log(LogLevel::Message, LogCategory::Core, "Asset base path: %s", buffer);
juliet_snprintf(buffer, len + 1, "%s", probePath);
CachedAssetBasePath = { buffer, len };
Log(LogLevel::Message, LogCategory::Core, "Asset base path: %s", buffer);
}
return;
} }
return;
} }
Log(LogLevel::Error, LogCategory::Core, "Filesystem: Could not find Assets/compiled/ directory!");
} }
void ShutdownFilesystem() Log(LogLevel::Error, LogCategory::Core, "Filesystem: Could not find Assets/compiled/ directory!");
{ }
CachedBasePath.Size = 0;
CachedBasePath.Str = nullptr; void ShutdownFilesystem()
CachedAssetBasePath.Size = 0; {
CachedAssetBasePath.Str = nullptr; CachedBasePath.Size = 0;
} CachedBasePath.Str = nullptr;
} // namespace Juliet CachedAssetBasePath.Size = 0;
CachedAssetBasePath.Str = nullptr;
}
@@ -1,7 +1,7 @@
#pragma once #pragma once
namespace Juliet::Platform namespace Platform
{ {
extern String GetBasePath(NonNullPtr<Arena> arena); extern String GetBasePath(NonNullPtr<Arena> arena);
extern bool IsAbsolutePath(String path); extern bool IsAbsolutePath(String path);
} // namespace Juliet::Platform } // namespace Platform
@@ -1,7 +1,4 @@
#pragma once #pragma once
namespace Juliet extern void InitFilesystem(NonNullPtr<Arena> arena);
{ extern void ShutdownFilesystem();
extern void InitFilesystem(NonNullPtr<Arena> arena);
extern void ShutdownFilesystem();
} // namespace Juliet
@@ -1,11 +1,11 @@
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Core/HAL/Filesystem/Filesystem_Platform.h> #include <Core/HAL/Filesystem/Filesystem_Platform.h>
#include <Core/HAL/Win32.h> #include <Core/HAL/Win32.h>
#include <Core/Logging/LogManager.h> #include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h> #include <Core/Logging/LogTypes.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
namespace Juliet::Platform namespace Platform
{ {
String GetBasePath(NonNullPtr<Arena> arena) String GetBasePath(NonNullPtr<Arena> arena)
{ {
@@ -91,4 +91,4 @@ namespace Juliet::Platform
return false; return false;
} }
} // namespace Juliet::Platform } // namespace Platform

Some files were not shown because too many files have changed in this diff Show More