From 3ec9bcd1525fd3599e21008926585cda56f99458 Mon Sep 17 00:00:00 2001 From: Thraix Date: Mon, 29 May 2023 17:49:37 +0200 Subject: [PATCH] Add ecs ComponentListener - Add ecs ComponentListener which listens to Component addition and removal - Add RefCounter class used to keep track of moves and copies --- CopiumEngine/CopiumEngine.vcxproj | 7 ++ CopiumEngine/CopiumEngine.vcxproj.filters | 21 ++++++ CopiumEngine/src/copium/asset/AssetRef.cpp | 38 +--------- CopiumEngine/src/copium/asset/AssetRef.h | 9 +-- CopiumEngine/src/copium/core/Application.cpp | 9 +-- CopiumEngine/src/copium/core/Scene.cpp | 11 ++- CopiumEngine/src/copium/core/SwapChain.cpp | 2 + CopiumEngine/src/copium/core/Window.cpp | 18 +++++ CopiumEngine/src/copium/core/Window.h | 14 +++- .../src/copium/ecs/ComponentListener.cpp | 0 .../src/copium/ecs/ComponentListener.h | 19 +++++ CopiumEngine/src/copium/ecs/ComponentPool.h | 40 ++++++++--- .../src/copium/ecs/ComponentPoolBase.h | 1 - CopiumEngine/src/copium/ecs/ECSManager.h | 19 +++++ CopiumEngine/src/copium/event/Input.cpp | 9 +++ CopiumEngine/src/copium/event/Input.h | 1 + CopiumEngine/src/copium/example/Components.h | 9 +++ .../src/copium/example/HealthChangeSystem.h | 21 ++++++ .../copium/example/HealthComponentListener.h | 35 +++++++++ .../src/copium/example/HealthDisplaySystem.h | 22 ++++++ .../copium/example/PlayerControllerSystem.h | 15 +++- CopiumEngine/src/copium/main.cpp | 5 +- CopiumEngine/src/copium/util/RefCounter.cpp | 72 +++++++++++++++++++ CopiumEngine/src/copium/util/RefCounter.h | 24 +++++++ 24 files changed, 351 insertions(+), 70 deletions(-) create mode 100644 CopiumEngine/src/copium/ecs/ComponentListener.cpp create mode 100644 CopiumEngine/src/copium/ecs/ComponentListener.h create mode 100644 CopiumEngine/src/copium/example/HealthChangeSystem.h create mode 100644 CopiumEngine/src/copium/example/HealthComponentListener.h create mode 100644 CopiumEngine/src/copium/example/HealthDisplaySystem.h create mode 100644 CopiumEngine/src/copium/util/RefCounter.cpp create mode 100644 CopiumEngine/src/copium/util/RefCounter.h diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj index f0a2c9d..08bf85e 100644 --- a/CopiumEngine/CopiumEngine.vcxproj +++ b/CopiumEngine/CopiumEngine.vcxproj @@ -180,6 +180,7 @@ + @@ -213,6 +214,7 @@ + @@ -249,6 +251,7 @@ + @@ -280,6 +283,9 @@ + + + @@ -302,6 +308,7 @@ + diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters index f6736cb..76a1787 100644 --- a/CopiumEngine/CopiumEngine.vcxproj.filters +++ b/CopiumEngine/CopiumEngine.vcxproj.filters @@ -219,6 +219,12 @@ Source Files + + Source Files + + + Source Files + @@ -485,5 +491,20 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/CopiumEngine/src/copium/asset/AssetRef.cpp b/CopiumEngine/src/copium/asset/AssetRef.cpp index 9842da7..8fea83a 100644 --- a/CopiumEngine/src/copium/asset/AssetRef.cpp +++ b/CopiumEngine/src/copium/asset/AssetRef.cpp @@ -5,51 +5,17 @@ namespace Copium { AssetRef::AssetRef(AssetHandle handle) - : handle{handle}, refCounter{new int{1}} + : handle{handle} {} AssetRef::~AssetRef() { - if (refCounter == nullptr) - return; - - (*refCounter)--; - if (*refCounter == 0) + if (refCounter.LastRef()) { AssetManager::UnloadAsset(handle); - delete refCounter; } } - AssetRef::AssetRef(const AssetRef& other) - : handle{other.handle}, refCounter{other.refCounter} - { - (*refCounter)++; - } - - AssetRef::AssetRef(AssetRef&& other) - : handle{other.handle}, refCounter{other.refCounter} - { - other.refCounter = nullptr; - } - - AssetRef& AssetRef::operator=(const AssetRef& rhs) - { - handle = rhs.handle; - refCounter = rhs.refCounter; - - (*refCounter)++; - return *this; - } - - AssetRef& AssetRef::operator=(AssetRef&& rhs) - { - handle = rhs.handle; - refCounter = rhs.refCounter; - rhs.refCounter = nullptr; - return *this; - } - AssetRef::operator AssetHandle() const { return handle; diff --git a/CopiumEngine/src/copium/asset/AssetRef.h b/CopiumEngine/src/copium/asset/AssetRef.h index 2885265..3cf4dea 100644 --- a/CopiumEngine/src/copium/asset/AssetRef.h +++ b/CopiumEngine/src/copium/asset/AssetRef.h @@ -1,6 +1,7 @@ #pragma once #include "copium/asset/AssetMeta.h" +#include "copium/util/RefCounter.h" namespace Copium { @@ -8,18 +9,12 @@ namespace Copium { private: AssetHandle handle; - int* refCounter; + RefCounter refCounter; public: AssetRef(AssetHandle handle); ~AssetRef(); - AssetRef(const AssetRef& other); - AssetRef(AssetRef&& other); - - AssetRef& operator=(const AssetRef& rhs); - AssetRef& operator=(AssetRef&& rhs); - operator AssetHandle() const; }; diff --git a/CopiumEngine/src/copium/core/Application.cpp b/CopiumEngine/src/copium/core/Application.cpp index ae13e4c..f527d3a 100644 --- a/CopiumEngine/src/copium/core/Application.cpp +++ b/CopiumEngine/src/copium/core/Application.cpp @@ -77,7 +77,7 @@ namespace Copium Vulkan::GetSwapChain().SubmitToGraphicsQueue(*commandBuffer); Vulkan::GetSwapChain().EndPresent(); - return !glfwWindowShouldClose(Vulkan::GetWindow().GetWindow()); + return !Vulkan::GetWindow().ShouldClose(); } EventResult Application::OnEvent(const Event& event) @@ -100,13 +100,6 @@ namespace Copium return EventResult::Focus; } - case EventType::KeyPress: - { - const KeyPressEvent& keyPressEvent = static_cast(event); - CP_INFO("%d", keyPressEvent.GetButton()); - - return EventResult::Handled; - } case EventType::MouseScroll: { const MouseScrollEvent& mouseScrollEvent = static_cast(event); diff --git a/CopiumEngine/src/copium/core/Scene.cpp b/CopiumEngine/src/copium/core/Scene.cpp index bbaba39..33a87c4 100644 --- a/CopiumEngine/src/copium/core/Scene.cpp +++ b/CopiumEngine/src/copium/core/Scene.cpp @@ -7,14 +7,17 @@ #include "copium/ecs/Entity.h" #include "copium/ecs/System.h" #include "copium/event/MouseMoveEvent.h" +#include "copium/example/CameraFollowPlayerSystem.h" #include "copium/example/CameraUpdateSystem.h" #include "copium/example/Components.h" #include "copium/example/FrameCountSystem.h" +#include "copium/example/HealthChangeSystem.h" +#include "copium/example/HealthComponentListener.h" +#include "copium/example/HealthDisplaySystem.h" #include "copium/example/MouseFollowSystem.h" -#include "copium/example/RenderSystem.h" #include "copium/example/PhysicsSystem.h" #include "copium/example/PlayerControllerSystem.h" -#include "copium/example/CameraFollowPlayerSystem.h" +#include "copium/example/RenderSystem.h" #include #include @@ -30,11 +33,14 @@ namespace Copium ecs->AddSystem(); ecs->AddSystem(); + ecs->AddSystem(); + ecs->AddSystem(); ecs->AddSystem(); ecs->AddSystem(&viewMatrix, &projectionMatrix, &invPvMatrix); ecs->AddSystem(&invPvMatrix); ecs->AddSystem(); ecs->AddSystem(renderer.get(), descriptorSetRenderer.get(), &commandBuffer, &viewMatrix, &projectionMatrix); // better way to store the RenderSystem data? + ecs->SetComponentListener(); // TODO: Load from scene file for (int y = 0; y < 10; y++) @@ -72,6 +78,7 @@ namespace Copium Entity entityPlayer = Entity::Create(ecs.get()); entityPlayer.AddComponent(entityCamera); + entityPlayer.AddComponent(10, 10); entityPlayer.AddComponent(0.1f, glm::vec2{0.0f, 0.0f}, glm::vec2{0.0f, 0.0f}); entityPlayer.AddComponent(glm::vec2{0.0f}, glm::vec2{1.0f}); entityPlayer.AddComponent(AssetRef{AssetManager::LoadAsset("fox2.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); diff --git a/CopiumEngine/src/copium/core/SwapChain.cpp b/CopiumEngine/src/copium/core/SwapChain.cpp index 5f45b87..b79191f 100644 --- a/CopiumEngine/src/copium/core/SwapChain.cpp +++ b/CopiumEngine/src/copium/core/SwapChain.cpp @@ -4,6 +4,8 @@ #include "copium/core/Vulkan.h" #include "copium/sampler/Image.h" +#include + namespace Copium { SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice) diff --git a/CopiumEngine/src/copium/core/Window.cpp b/CopiumEngine/src/copium/core/Window.cpp index ef59fa3..e0fcf10 100644 --- a/CopiumEngine/src/copium/core/Window.cpp +++ b/CopiumEngine/src/copium/core/Window.cpp @@ -12,6 +12,8 @@ #include "copium/event/WindowResizeEvent.h" #include "copium/event/WindowFocusEvent.h" +#include + namespace Copium { Window::Window(const std::string& windowName, int width, int height, WindowMode mode) @@ -27,6 +29,22 @@ namespace Copium glfwDestroyWindow(window); } + bool Window::ShouldClose() const + { + return glfwWindowShouldClose(window); + + } + + int Window::GetWidth() const + { + return width; + } + + int Window::GetHeight() const + { + return height; + } + VkSurfaceKHR Window::GetSurface() const { return surface; diff --git a/CopiumEngine/src/copium/core/Window.h b/CopiumEngine/src/copium/core/Window.h index e89db90..af90d39 100644 --- a/CopiumEngine/src/copium/core/Window.h +++ b/CopiumEngine/src/copium/core/Window.h @@ -3,11 +3,17 @@ #include "copium/util/Common.h" #include "copium/util/Enum.h" -#include +#include + +#define CP_WINDOW_MODE_ENUMS \ + Fullscreen, \ + BorderlessWindowed, \ + Windowed -#define CP_WINDOW_MODE_ENUMS Fullscreen, BorderlessWindowed, Windowed CP_ENUM_CREATOR(Copium, WindowMode, CP_WINDOW_MODE_ENUMS); +struct GLFWwindow; + namespace Copium { class Window final @@ -24,6 +30,10 @@ namespace Copium Window(const std::string& windowName, int width, int height, WindowMode mode); ~Window(); + bool ShouldClose() const; + + int GetWidth() const; + int GetHeight() const; VkSurfaceKHR GetSurface() const; GLFWwindow* GetWindow(); diff --git a/CopiumEngine/src/copium/ecs/ComponentListener.cpp b/CopiumEngine/src/copium/ecs/ComponentListener.cpp new file mode 100644 index 0000000..e69de29 diff --git a/CopiumEngine/src/copium/ecs/ComponentListener.h b/CopiumEngine/src/copium/ecs/ComponentListener.h new file mode 100644 index 0000000..71087df --- /dev/null +++ b/CopiumEngine/src/copium/ecs/ComponentListener.h @@ -0,0 +1,19 @@ +#pragma once + +#include "copium/ecs/ECSManager.h" + +namespace Copium +{ + template + class ComponentListener + { + public: + using component_type = Component; + friend class ECSManager; + protected: + ECSManager* manager; + public: + virtual void Added(EntityId entityId, Component& component) {} + virtual void Removed(EntityId entityId, Component& component) {} + }; +} diff --git a/CopiumEngine/src/copium/ecs/ComponentPool.h b/CopiumEngine/src/copium/ecs/ComponentPool.h index e250141..40df656 100644 --- a/CopiumEngine/src/copium/ecs/ComponentPool.h +++ b/CopiumEngine/src/copium/ecs/ComponentPool.h @@ -3,6 +3,7 @@ #include "copium/ecs/Config.h" #include "copium/ecs/EntitySet.h" #include "copium/ecs/ComponentPoolBase.h" +#include "copium/ecs/ComponentListener.h" #include @@ -14,8 +15,18 @@ namespace Copium using Iterator = typename std::vector::iterator; private: std::vector components; + ComponentListener* listener = nullptr; public: + ComponentPool() + {} + + ~ComponentPool() override + { + if(listener) + delete listener; + } + ComponentPool(EntityId entity, const Component& component) { Emplace(entity, component); @@ -25,21 +36,27 @@ namespace Copium { components.push_back(component); entities.Emplace(entity); + if(listener) + listener->Added(entity, components.back()); return components.back(); } - void Pop() - { - components.pop_back(); - entities.Pop(); - } - - bool Erase(EntityId entity) + bool Erase(EntityId entity) override { size_t index = entities.Find(entity); if (!entities.Erase(entity)) return false; - components.erase(components.begin() + index); + if (listener) + { + auto it = components.begin() + index; + Component component = *it; + components.erase(it); + listener->Removed(entity, component); + } + else + { + components.erase(components.begin() + index); + } return true; } @@ -61,13 +78,18 @@ namespace Copium return nullptr; } + void SetComponentListener(ComponentListener* listener) + { + ComponentPool::listener = listener; + } + Component& operator[](size_t index) { CP_ASSERT(index < components.size(), "Index Out of Bound Exception"); return components[index]; } - size_t Size() + size_t Size() override { return components.size(); } diff --git a/CopiumEngine/src/copium/ecs/ComponentPoolBase.h b/CopiumEngine/src/copium/ecs/ComponentPoolBase.h index c73806d..58ffa70 100644 --- a/CopiumEngine/src/copium/ecs/ComponentPoolBase.h +++ b/CopiumEngine/src/copium/ecs/ComponentPoolBase.h @@ -15,7 +15,6 @@ namespace Copium virtual ~ComponentPoolBase() = default; virtual size_t Size() = 0; - virtual void Pop() = 0; virtual bool Erase(EntityId entity) = 0; std::vector& GetEntities(); const std::vector& GetEntities() const; diff --git a/CopiumEngine/src/copium/ecs/ECSManager.h b/CopiumEngine/src/copium/ecs/ECSManager.h index 242abf8..e3cc344 100644 --- a/CopiumEngine/src/copium/ecs/ECSManager.h +++ b/CopiumEngine/src/copium/ecs/ECSManager.h @@ -48,6 +48,25 @@ namespace Copium bool ValidEntity(EntityId entity); void Each(std::function function); + template + void SetComponentListener(const Args&... args) + { + using Component = typename Listener::component_type; + auto pool = GetComponentPool(); + Listener* listener = new Listener{args...}; + listener->manager = this; + if (pool) + { + pool->SetComponentListener(listener); + } + else + { + ComponentPool* pool{new ComponentPool{}}; + componentPool.emplace(GetComponentId(), pool); + pool->SetComponentListener(listener); + } + } + template std::tuple AddComponents(EntityId entity, Components&&... components) { diff --git a/CopiumEngine/src/copium/event/Input.cpp b/CopiumEngine/src/copium/event/Input.cpp index 8a88c5b..c0d64a1 100644 --- a/CopiumEngine/src/copium/event/Input.cpp +++ b/CopiumEngine/src/copium/event/Input.cpp @@ -1,6 +1,9 @@ #include "copium/event/Input.h" #include "copium/util/Common.h" +#include "copium/core/Vulkan.h" + +#include namespace Copium { @@ -63,6 +66,11 @@ namespace Copium return mousePos; } + glm::vec2 Input::GetMouseWindowPos() + { + return glm::vec2{(mousePos.x + 1.0f) * 0.5f * Vulkan::GetWindow().GetWidth(), (1.0f - mousePos.y) * 0.5f * Vulkan::GetWindow().GetHeight()}; + } + void Input::OnKey(int keyCode, bool pressed) { CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range"); @@ -85,5 +93,6 @@ namespace Copium void Input::Update() { memset(keyEventList, false, sizeof(keyEventList)); + memset(mouseEventList, false, sizeof(mouseEventList)); } } diff --git a/CopiumEngine/src/copium/event/Input.h b/CopiumEngine/src/copium/event/Input.h index 05b284c..92b7dfd 100644 --- a/CopiumEngine/src/copium/event/Input.h +++ b/CopiumEngine/src/copium/event/Input.h @@ -35,6 +35,7 @@ namespace Copium static bool IsMouseDown(int button); static bool IsMouseUp(int button); + static glm::vec2 GetMouseWindowPos(); static glm::vec2 GetMousePos(); static void OnKey(int keyCode, bool pressed); diff --git a/CopiumEngine/src/copium/example/Components.h b/CopiumEngine/src/copium/example/Components.h index 7322a67..a7dab89 100644 --- a/CopiumEngine/src/copium/example/Components.h +++ b/CopiumEngine/src/copium/example/Components.h @@ -57,4 +57,13 @@ namespace Copium { Entity camera; }; + + struct HealthC + { + int current; + int max; + + Entity background; + Entity foreground; + }; } \ No newline at end of file diff --git a/CopiumEngine/src/copium/example/HealthChangeSystem.h b/CopiumEngine/src/copium/example/HealthChangeSystem.h new file mode 100644 index 0000000..0de9195 --- /dev/null +++ b/CopiumEngine/src/copium/example/HealthChangeSystem.h @@ -0,0 +1,21 @@ +#pragma once + +#include "copium/ecs/System.h" +#include "copium/example/Components.h" +#include "copium/event/Input.h" + +namespace Copium +{ + class HealthChangeSystem : public System + { + + void RunEntity(Entity entity, HealthC& health) override + { + if (Input::IsKeyPressed(CP_KEY_K)) + health.current++; + if (Input::IsKeyPressed(CP_KEY_J)) + health.current--; + health.current = std::clamp(health.current, 0, health.max); + } + }; +} diff --git a/CopiumEngine/src/copium/example/HealthComponentListener.h b/CopiumEngine/src/copium/example/HealthComponentListener.h new file mode 100644 index 0000000..cd64a12 --- /dev/null +++ b/CopiumEngine/src/copium/example/HealthComponentListener.h @@ -0,0 +1,35 @@ +#pragma once + +#include "copium/ecs/ComponentListener.h" +#include "copium/example/Components.h" +#include "copium/util/Common.h" + +namespace Copium +{ + class HealthComponentListener : public ComponentListener + { + void Added(EntityId entityId, HealthC& health) override + { + CP_ASSERT(!health.background, "Health already has background entity assigned"); + CP_ASSERT(!health.foreground, "Health already has foreground entity assigned"); + + health.background = Entity::Create(manager); + health.background.AddComponent(glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 0.2f}); + health.background.AddComponent(glm::vec3{0.9f, 0.2f, 0.2f}); + + health.foreground = Entity::Create(manager); + health.foreground.AddComponent(glm::vec2{0.0f, 0.0f}, glm::vec2{std::clamp(health.current, 0, health.max) / (float)health.max, 0.2f}); + health.foreground.AddComponent(glm::vec3{0.2f, 0.9f, 0.2f}); + } + + void Removed(EntityId entityId, HealthC& health) override + { + CP_ASSERT(health.background, "Health already removed background entity"); + CP_ASSERT(health.foreground, "Health already removed foreground entity"); + + health.background.Destroy(); + health.foreground.Destroy(); + } + }; + +} diff --git a/CopiumEngine/src/copium/example/HealthDisplaySystem.h b/CopiumEngine/src/copium/example/HealthDisplaySystem.h new file mode 100644 index 0000000..5785b13 --- /dev/null +++ b/CopiumEngine/src/copium/example/HealthDisplaySystem.h @@ -0,0 +1,22 @@ +#pragma once + +#include "copium/ecs/System.h" +#include "copium/example/Components.h" + + +namespace Copium +{ + class HealthDisplaySystem : public System + { + void RunEntity(Entity entity, HealthC& health, TransformC& transform) override + { + TransformC& foregroundTransform = health.foreground.GetComponent(); + foregroundTransform.position = transform.position + glm::vec2{0.0f, transform.size.y * 1.13}; + foregroundTransform.size = glm::vec2{std::clamp(health.current, 0, health.max) / (float)health.max, 0.2f}; + + TransformC& backgroundTransform = health.background.GetComponent(); + backgroundTransform.position = transform.position + glm::vec2{0.0f, transform.size.y * 1.13}; + } + }; + +} \ No newline at end of file diff --git a/CopiumEngine/src/copium/example/PlayerControllerSystem.h b/CopiumEngine/src/copium/example/PlayerControllerSystem.h index e8917ec..4ff3235 100644 --- a/CopiumEngine/src/copium/example/PlayerControllerSystem.h +++ b/CopiumEngine/src/copium/example/PlayerControllerSystem.h @@ -18,8 +18,19 @@ namespace Copium if (Input::IsKeyDown(CP_KEY_A)) force.x -= 1.0f; if (Input::IsKeyDown(CP_KEY_D)) force.x += 1.0f; - glm::normalize(force); - physics.force += force * magnitude; + if (force.x != 0 || force.y != 0) + { + force = glm::normalize(force); + physics.force += force * magnitude; + } + + if (Input::IsKeyPressed(CP_KEY_H)) + { + if (entity.HasComponent()) + entity.RemoveComponent(); + else + entity.AddComponent(8, 10); + } } }; } diff --git a/CopiumEngine/src/copium/main.cpp b/CopiumEngine/src/copium/main.cpp index a675239..b6ab848 100644 --- a/CopiumEngine/src/copium/main.cpp +++ b/CopiumEngine/src/copium/main.cpp @@ -16,10 +16,9 @@ int main(int argc, char** argv) Copium::Application application; while (application.Update()) { - glfwPollEvents(); - - Copium::EventDispatcher::Dispatch(); Copium::Input::Update(); + glfwPollEvents(); + Copium::EventDispatcher::Dispatch(); } } Copium::Vulkan::Destroy(); diff --git a/CopiumEngine/src/copium/util/RefCounter.cpp b/CopiumEngine/src/copium/util/RefCounter.cpp new file mode 100644 index 0000000..9229303 --- /dev/null +++ b/CopiumEngine/src/copium/util/RefCounter.cpp @@ -0,0 +1,72 @@ +#include "copium/util/RefCounter.h" + +#include "copium/util/Common.h" + +namespace Copium +{ + RefCounter::RefCounter() + : refCounter{new int{1}} + {} + + RefCounter::~RefCounter() + { + if (Valid()) + { + (*refCounter)--; + if (*refCounter == 0) + { + delete refCounter; + refCounter = nullptr; + } + } + } + + RefCounter::RefCounter(RefCounter&& rhs) + : refCounter(rhs.refCounter) + { + CP_ASSERT(Valid(), "RefCounter : Moving a deleted RefCounter"); + rhs.refCounter = nullptr; + } + + RefCounter::RefCounter(const RefCounter& rhs) + : refCounter{rhs.refCounter} + { + CP_ASSERT(Valid(), "RefCounter : Copying a deleted RefCounter"); + (*refCounter)++; + } + + RefCounter& RefCounter::operator=(RefCounter&& rhs) + { + CP_ASSERT(Valid(), "operator= : Moving a deleted RefCounter"); + + refCounter = rhs.refCounter; + rhs.refCounter = nullptr; + return *this; + } + + RefCounter& RefCounter::operator=(const RefCounter& rhs) + { + CP_ASSERT(Valid(), "operator= : Copying a deleted RefCounter"); + + refCounter = rhs.refCounter; + (*refCounter)++; + return *this; + } + + bool RefCounter::Valid() const + { + return refCounter != nullptr; + } + + bool RefCounter::LastRef() const + { + return Valid() && *refCounter == 1; + } + + int RefCounter::Counter() const + { + CP_ASSERT(Valid(), "Counter : referencing a deleted RefCounter"); + + return *refCounter; + } +} diff --git a/CopiumEngine/src/copium/util/RefCounter.h b/CopiumEngine/src/copium/util/RefCounter.h new file mode 100644 index 0000000..f286c25 --- /dev/null +++ b/CopiumEngine/src/copium/util/RefCounter.h @@ -0,0 +1,24 @@ +#pragma once + +namespace Copium +{ + class RefCounter final + { + private: + int* refCounter; + + public: + RefCounter(); + ~RefCounter(); + + RefCounter(RefCounter&& rhs); + RefCounter(const RefCounter& rhs); + + RefCounter& operator=(RefCounter&& rhs); + RefCounter& operator=(const RefCounter& rhs); + + bool Valid() const; + bool LastRef() const; + int Counter() const; + }; +}