Add ecs ComponentListener

- Add ecs ComponentListener which listens to Component addition and
  removal
- Add RefCounter class used to keep track of moves and copies
This commit is contained in:
Thraix
2023-05-29 17:49:37 +02:00
parent 5a615ecc4e
commit 3ec9bcd152
24 changed files with 351 additions and 70 deletions
+7
View File
@@ -180,6 +180,7 @@
<ClCompile Include="src\copium\core\Scene.cpp" /> <ClCompile Include="src\copium\core\Scene.cpp" />
<ClCompile Include="src\copium\core\Vulkan.cpp" /> <ClCompile Include="src\copium\core\Vulkan.cpp" />
<ClCompile Include="src\copium\core\Window.cpp" /> <ClCompile Include="src\copium\core\Window.cpp" />
<ClCompile Include="src\copium\ecs\ComponentListener.cpp" />
<ClCompile Include="src\copium\ecs\ComponentPoolBase.cpp" /> <ClCompile Include="src\copium\ecs\ComponentPoolBase.cpp" />
<ClCompile Include="src\copium\ecs\ECSManager.cpp" /> <ClCompile Include="src\copium\ecs\ECSManager.cpp" />
<ClCompile Include="src\copium\ecs\Entity.cpp" /> <ClCompile Include="src\copium\ecs\Entity.cpp" />
@@ -213,6 +214,7 @@
<ClCompile Include="src\copium\pipeline\DescriptorSet.cpp" /> <ClCompile Include="src\copium\pipeline\DescriptorSet.cpp" />
<ClCompile Include="src\copium\sampler\Font.cpp" /> <ClCompile Include="src\copium\sampler\Font.cpp" />
<ClCompile Include="src\copium\util\BoundingBox.cpp" /> <ClCompile Include="src\copium\util\BoundingBox.cpp" />
<ClCompile Include="src\copium\util\RefCounter.cpp" />
<ClCompile Include="src\copium\util\RuntimeException.cpp" /> <ClCompile Include="src\copium\util\RuntimeException.cpp" />
<ClCompile Include="src\copium\util\FileSystem.cpp" /> <ClCompile Include="src\copium\util\FileSystem.cpp" />
<ClCompile Include="src\copium\buffer\Framebuffer.cpp" /> <ClCompile Include="src\copium\buffer\Framebuffer.cpp" />
@@ -249,6 +251,7 @@
<ClInclude Include="src\copium\core\Scene.h" /> <ClInclude Include="src\copium\core\Scene.h" />
<ClInclude Include="src\copium\core\Vulkan.h" /> <ClInclude Include="src\copium\core\Vulkan.h" />
<ClInclude Include="src\copium\core\Window.h" /> <ClInclude Include="src\copium\core\Window.h" />
<ClInclude Include="src\copium\ecs\ComponentListener.h" />
<ClInclude Include="src\copium\ecs\ComponentPool.h" /> <ClInclude Include="src\copium\ecs\ComponentPool.h" />
<ClInclude Include="src\copium\ecs\ComponentPoolBase.h" /> <ClInclude Include="src\copium\ecs\ComponentPoolBase.h" />
<ClInclude Include="src\copium\ecs\Config.h" /> <ClInclude Include="src\copium\ecs\Config.h" />
@@ -280,6 +283,9 @@
<ClInclude Include="src\copium\example\CameraUpdateSystem.h" /> <ClInclude Include="src\copium\example\CameraUpdateSystem.h" />
<ClInclude Include="src\copium\example\Components.h" /> <ClInclude Include="src\copium\example\Components.h" />
<ClInclude Include="src\copium\example\FrameCountSystem.h" /> <ClInclude Include="src\copium\example\FrameCountSystem.h" />
<ClInclude Include="src\copium\example\HealthChangeSystem.h" />
<ClInclude Include="src\copium\example\HealthComponentListener.h" />
<ClInclude Include="src\copium\example\HealthDisplaySystem.h" />
<ClInclude Include="src\copium\example\PhysicsSystem.h" /> <ClInclude Include="src\copium\example\PhysicsSystem.h" />
<ClInclude Include="src\copium\example\PlayerControllerSystem.h" /> <ClInclude Include="src\copium\example\PlayerControllerSystem.h" />
<ClInclude Include="src\copium\example\RenderSystem.h" /> <ClInclude Include="src\copium\example\RenderSystem.h" />
@@ -302,6 +308,7 @@
<ClInclude Include="src\copium\pipeline\DescriptorSet.h" /> <ClInclude Include="src\copium\pipeline\DescriptorSet.h" />
<ClInclude Include="src\copium\pipeline\DescriptorPool.h" /> <ClInclude Include="src\copium\pipeline\DescriptorPool.h" />
<ClInclude Include="src\copium\util\Enum.h" /> <ClInclude Include="src\copium\util\Enum.h" />
<ClInclude Include="src\copium\util\RefCounter.h" />
<ClInclude Include="src\copium\util\RuntimeException.h" /> <ClInclude Include="src\copium\util\RuntimeException.h" />
<ClInclude Include="src\copium\util\FileSystem.h" /> <ClInclude Include="src\copium\util\FileSystem.h" />
<ClInclude Include="src\copium\buffer\Framebuffer.h" /> <ClInclude Include="src\copium\buffer\Framebuffer.h" />
+21
View File
@@ -219,6 +219,12 @@
<ClCompile Include="src\copium\event\Input.cpp"> <ClCompile Include="src\copium\event\Input.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\copium\util\RefCounter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\copium\ecs\ComponentListener.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\copium\sampler\DepthAttachment.h"> <ClInclude Include="src\copium\sampler\DepthAttachment.h">
@@ -485,5 +491,20 @@
<ClInclude Include="src\copium\example\CameraFollowPlayerSystem.h"> <ClInclude Include="src\copium\example\CameraFollowPlayerSystem.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\copium\example\HealthDisplaySystem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\copium\example\HealthChangeSystem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\copium\util\RefCounter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\copium\ecs\ComponentListener.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\copium\example\HealthComponentListener.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>
+2 -36
View File
@@ -5,51 +5,17 @@
namespace Copium namespace Copium
{ {
AssetRef::AssetRef(AssetHandle handle) AssetRef::AssetRef(AssetHandle handle)
: handle{handle}, refCounter{new int{1}} : handle{handle}
{} {}
AssetRef::~AssetRef() AssetRef::~AssetRef()
{ {
if (refCounter == nullptr) if (refCounter.LastRef())
return;
(*refCounter)--;
if (*refCounter == 0)
{ {
AssetManager::UnloadAsset(handle); 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 AssetRef::operator AssetHandle() const
{ {
return handle; return handle;
+2 -7
View File
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "copium/asset/AssetMeta.h" #include "copium/asset/AssetMeta.h"
#include "copium/util/RefCounter.h"
namespace Copium namespace Copium
{ {
@@ -8,18 +9,12 @@ namespace Copium
{ {
private: private:
AssetHandle handle; AssetHandle handle;
int* refCounter; RefCounter refCounter;
public: public:
AssetRef(AssetHandle handle); AssetRef(AssetHandle handle);
~AssetRef(); ~AssetRef();
AssetRef(const AssetRef& other);
AssetRef(AssetRef&& other);
AssetRef& operator=(const AssetRef& rhs);
AssetRef& operator=(AssetRef&& rhs);
operator AssetHandle() const; operator AssetHandle() const;
}; };
+1 -8
View File
@@ -77,7 +77,7 @@ namespace Copium
Vulkan::GetSwapChain().SubmitToGraphicsQueue(*commandBuffer); Vulkan::GetSwapChain().SubmitToGraphicsQueue(*commandBuffer);
Vulkan::GetSwapChain().EndPresent(); Vulkan::GetSwapChain().EndPresent();
return !glfwWindowShouldClose(Vulkan::GetWindow().GetWindow()); return !Vulkan::GetWindow().ShouldClose();
} }
EventResult Application::OnEvent(const Event& event) EventResult Application::OnEvent(const Event& event)
@@ -100,13 +100,6 @@ namespace Copium
return EventResult::Focus; return EventResult::Focus;
} }
case EventType::KeyPress:
{
const KeyPressEvent& keyPressEvent = static_cast<const KeyPressEvent&>(event);
CP_INFO("%d", keyPressEvent.GetButton());
return EventResult::Handled;
}
case EventType::MouseScroll: case EventType::MouseScroll:
{ {
const MouseScrollEvent& mouseScrollEvent = static_cast<const MouseScrollEvent&>(event); const MouseScrollEvent& mouseScrollEvent = static_cast<const MouseScrollEvent&>(event);
+9 -2
View File
@@ -7,14 +7,17 @@
#include "copium/ecs/Entity.h" #include "copium/ecs/Entity.h"
#include "copium/ecs/System.h" #include "copium/ecs/System.h"
#include "copium/event/MouseMoveEvent.h" #include "copium/event/MouseMoveEvent.h"
#include "copium/example/CameraFollowPlayerSystem.h"
#include "copium/example/CameraUpdateSystem.h" #include "copium/example/CameraUpdateSystem.h"
#include "copium/example/Components.h" #include "copium/example/Components.h"
#include "copium/example/FrameCountSystem.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/MouseFollowSystem.h"
#include "copium/example/RenderSystem.h"
#include "copium/example/PhysicsSystem.h" #include "copium/example/PhysicsSystem.h"
#include "copium/example/PlayerControllerSystem.h" #include "copium/example/PlayerControllerSystem.h"
#include "copium/example/CameraFollowPlayerSystem.h" #include "copium/example/RenderSystem.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
@@ -30,11 +33,14 @@ namespace Copium
ecs->AddSystem<PlayerControllerSystem>(); ecs->AddSystem<PlayerControllerSystem>();
ecs->AddSystem<PhysicsSystem>(); ecs->AddSystem<PhysicsSystem>();
ecs->AddSystem<HealthChangeSystem>();
ecs->AddSystem<HealthDisplaySystem>();
ecs->AddSystem<CameraFollowPlayerSystem>(); ecs->AddSystem<CameraFollowPlayerSystem>();
ecs->AddSystem<CameraUpdateSystem>(&viewMatrix, &projectionMatrix, &invPvMatrix); ecs->AddSystem<CameraUpdateSystem>(&viewMatrix, &projectionMatrix, &invPvMatrix);
ecs->AddSystem<MouseFollowSystem>(&invPvMatrix); ecs->AddSystem<MouseFollowSystem>(&invPvMatrix);
ecs->AddSystem<FrameCountSystem>(); ecs->AddSystem<FrameCountSystem>();
ecs->AddSystem<RenderSystem>(renderer.get(), descriptorSetRenderer.get(), &commandBuffer, &viewMatrix, &projectionMatrix); // better way to store the RenderSystem data? ecs->AddSystem<RenderSystem>(renderer.get(), descriptorSetRenderer.get(), &commandBuffer, &viewMatrix, &projectionMatrix); // better way to store the RenderSystem data?
ecs->SetComponentListener<HealthComponentListener>();
// TODO: Load from scene file // TODO: Load from scene file
for (int y = 0; y < 10; y++) for (int y = 0; y < 10; y++)
@@ -72,6 +78,7 @@ namespace Copium
Entity entityPlayer = Entity::Create(ecs.get()); Entity entityPlayer = Entity::Create(ecs.get());
entityPlayer.AddComponent<PlayerC>(entityCamera); entityPlayer.AddComponent<PlayerC>(entityCamera);
entityPlayer.AddComponent<HealthC>(10, 10);
entityPlayer.AddComponent<PhysicsC>(0.1f, glm::vec2{0.0f, 0.0f}, glm::vec2{0.0f, 0.0f}); entityPlayer.AddComponent<PhysicsC>(0.1f, glm::vec2{0.0f, 0.0f}, glm::vec2{0.0f, 0.0f});
entityPlayer.AddComponent<TransformC>(glm::vec2{0.0f}, glm::vec2{1.0f}); entityPlayer.AddComponent<TransformC>(glm::vec2{0.0f}, glm::vec2{1.0f});
entityPlayer.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox2.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f}); entityPlayer.AddComponent<TextureC>(AssetRef{AssetManager::LoadAsset("fox2.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
@@ -4,6 +4,8 @@
#include "copium/core/Vulkan.h" #include "copium/core/Vulkan.h"
#include "copium/sampler/Image.h" #include "copium/sampler/Image.h"
#include <GLFW/glfw3.h>
namespace Copium namespace Copium
{ {
SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice) SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice)
+18
View File
@@ -12,6 +12,8 @@
#include "copium/event/WindowResizeEvent.h" #include "copium/event/WindowResizeEvent.h"
#include "copium/event/WindowFocusEvent.h" #include "copium/event/WindowFocusEvent.h"
#include <GLFW/glfw3.h>
namespace Copium namespace Copium
{ {
Window::Window(const std::string& windowName, int width, int height, WindowMode mode) Window::Window(const std::string& windowName, int width, int height, WindowMode mode)
@@ -27,6 +29,22 @@ namespace Copium
glfwDestroyWindow(window); 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 VkSurfaceKHR Window::GetSurface() const
{ {
return surface; return surface;
+12 -2
View File
@@ -3,11 +3,17 @@
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include "copium/util/Enum.h" #include "copium/util/Enum.h"
#include <GLFW/glfw3.h> #include <vulkan/vulkan.hpp>
#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); CP_ENUM_CREATOR(Copium, WindowMode, CP_WINDOW_MODE_ENUMS);
struct GLFWwindow;
namespace Copium namespace Copium
{ {
class Window final class Window final
@@ -24,6 +30,10 @@ namespace Copium
Window(const std::string& windowName, int width, int height, WindowMode mode); Window(const std::string& windowName, int width, int height, WindowMode mode);
~Window(); ~Window();
bool ShouldClose() const;
int GetWidth() const;
int GetHeight() const;
VkSurfaceKHR GetSurface() const; VkSurfaceKHR GetSurface() const;
GLFWwindow* GetWindow(); GLFWwindow* GetWindow();
@@ -0,0 +1,19 @@
#pragma once
#include "copium/ecs/ECSManager.h"
namespace Copium
{
template <typename Component>
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) {}
};
}
+30 -8
View File
@@ -3,6 +3,7 @@
#include "copium/ecs/Config.h" #include "copium/ecs/Config.h"
#include "copium/ecs/EntitySet.h" #include "copium/ecs/EntitySet.h"
#include "copium/ecs/ComponentPoolBase.h" #include "copium/ecs/ComponentPoolBase.h"
#include "copium/ecs/ComponentListener.h"
#include <vector> #include <vector>
@@ -14,8 +15,18 @@ namespace Copium
using Iterator = typename std::vector<Component>::iterator; using Iterator = typename std::vector<Component>::iterator;
private: private:
std::vector<Component> components; std::vector<Component> components;
ComponentListener<Component>* listener = nullptr;
public: public:
ComponentPool()
{}
~ComponentPool() override
{
if(listener)
delete listener;
}
ComponentPool(EntityId entity, const Component& component) ComponentPool(EntityId entity, const Component& component)
{ {
Emplace(entity, component); Emplace(entity, component);
@@ -25,21 +36,27 @@ namespace Copium
{ {
components.push_back(component); components.push_back(component);
entities.Emplace(entity); entities.Emplace(entity);
if(listener)
listener->Added(entity, components.back());
return components.back(); return components.back();
} }
void Pop() bool Erase(EntityId entity) override
{
components.pop_back();
entities.Pop();
}
bool Erase(EntityId entity)
{ {
size_t index = entities.Find(entity); size_t index = entities.Find(entity);
if (!entities.Erase(entity)) if (!entities.Erase(entity))
return false; return false;
if (listener)
{
auto it = components.begin() + index;
Component component = *it;
components.erase(it);
listener->Removed(entity, component);
}
else
{
components.erase(components.begin() + index); components.erase(components.begin() + index);
}
return true; return true;
} }
@@ -61,13 +78,18 @@ namespace Copium
return nullptr; return nullptr;
} }
void SetComponentListener(ComponentListener<Component>* listener)
{
ComponentPool::listener = listener;
}
Component& operator[](size_t index) Component& operator[](size_t index)
{ {
CP_ASSERT(index < components.size(), "Index Out of Bound Exception"); CP_ASSERT(index < components.size(), "Index Out of Bound Exception");
return components[index]; return components[index];
} }
size_t Size() size_t Size() override
{ {
return components.size(); return components.size();
} }
@@ -15,7 +15,6 @@ namespace Copium
virtual ~ComponentPoolBase() = default; virtual ~ComponentPoolBase() = default;
virtual size_t Size() = 0; virtual size_t Size() = 0;
virtual void Pop() = 0;
virtual bool Erase(EntityId entity) = 0; virtual bool Erase(EntityId entity) = 0;
std::vector<EntityId>& GetEntities(); std::vector<EntityId>& GetEntities();
const std::vector<EntityId>& GetEntities() const; const std::vector<EntityId>& GetEntities() const;
+19
View File
@@ -48,6 +48,25 @@ namespace Copium
bool ValidEntity(EntityId entity); bool ValidEntity(EntityId entity);
void Each(std::function<void(EntityId)> function); void Each(std::function<void(EntityId)> function);
template <typename Listener, typename... Args>
void SetComponentListener(const Args&... args)
{
using Component = typename Listener::component_type;
auto pool = GetComponentPool<Component>();
Listener* listener = new Listener{args...};
listener->manager = this;
if (pool)
{
pool->SetComponentListener(listener);
}
else
{
ComponentPool<Component>* pool{new ComponentPool<Component>{}};
componentPool.emplace(GetComponentId<Component>(), pool);
pool->SetComponentListener(listener);
}
}
template <typename... Components> template <typename... Components>
std::tuple<Components&...> AddComponents(EntityId entity, Components&&... components) std::tuple<Components&...> AddComponents(EntityId entity, Components&&... components)
{ {
+9
View File
@@ -1,6 +1,9 @@
#include "copium/event/Input.h" #include "copium/event/Input.h"
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include "copium/core/Vulkan.h"
#include <glm/gtc/matrix_transform.hpp>
namespace Copium namespace Copium
{ {
@@ -63,6 +66,11 @@ namespace Copium
return mousePos; 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) void Input::OnKey(int keyCode, bool pressed)
{ {
CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range"); CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range");
@@ -85,5 +93,6 @@ namespace Copium
void Input::Update() void Input::Update()
{ {
memset(keyEventList, false, sizeof(keyEventList)); memset(keyEventList, false, sizeof(keyEventList));
memset(mouseEventList, false, sizeof(mouseEventList));
} }
} }
+1
View File
@@ -35,6 +35,7 @@ namespace Copium
static bool IsMouseDown(int button); static bool IsMouseDown(int button);
static bool IsMouseUp(int button); static bool IsMouseUp(int button);
static glm::vec2 GetMouseWindowPos();
static glm::vec2 GetMousePos(); static glm::vec2 GetMousePos();
static void OnKey(int keyCode, bool pressed); static void OnKey(int keyCode, bool pressed);
@@ -57,4 +57,13 @@ namespace Copium
{ {
Entity camera; Entity camera;
}; };
struct HealthC
{
int current;
int max;
Entity background;
Entity foreground;
};
} }
@@ -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<HealthC>
{
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);
}
};
}
@@ -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<HealthC>
{
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<TransformC>(glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 0.2f});
health.background.AddComponent<ColorC>(glm::vec3{0.9f, 0.2f, 0.2f});
health.foreground = Entity::Create(manager);
health.foreground.AddComponent<TransformC>(glm::vec2{0.0f, 0.0f}, glm::vec2{std::clamp(health.current, 0, health.max) / (float)health.max, 0.2f});
health.foreground.AddComponent<ColorC>(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();
}
};
}
@@ -0,0 +1,22 @@
#pragma once
#include "copium/ecs/System.h"
#include "copium/example/Components.h"
namespace Copium
{
class HealthDisplaySystem : public System<HealthC, TransformC>
{
void RunEntity(Entity entity, HealthC& health, TransformC& transform) override
{
TransformC& foregroundTransform = health.foreground.GetComponent<TransformC>();
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<TransformC>();
backgroundTransform.position = transform.position + glm::vec2{0.0f, transform.size.y * 1.13};
}
};
}
@@ -18,8 +18,19 @@ namespace Copium
if (Input::IsKeyDown(CP_KEY_A)) force.x -= 1.0f; if (Input::IsKeyDown(CP_KEY_A)) force.x -= 1.0f;
if (Input::IsKeyDown(CP_KEY_D)) force.x += 1.0f; if (Input::IsKeyDown(CP_KEY_D)) force.x += 1.0f;
glm::normalize(force); if (force.x != 0 || force.y != 0)
{
force = glm::normalize(force);
physics.force += force * magnitude; physics.force += force * magnitude;
} }
if (Input::IsKeyPressed(CP_KEY_H))
{
if (entity.HasComponent<HealthC>())
entity.RemoveComponent<HealthC>();
else
entity.AddComponent<HealthC>(8, 10);
}
}
}; };
} }
+2 -3
View File
@@ -16,10 +16,9 @@ int main(int argc, char** argv)
Copium::Application application; Copium::Application application;
while (application.Update()) while (application.Update())
{ {
glfwPollEvents();
Copium::EventDispatcher::Dispatch();
Copium::Input::Update(); Copium::Input::Update();
glfwPollEvents();
Copium::EventDispatcher::Dispatch();
} }
} }
Copium::Vulkan::Destroy(); Copium::Vulkan::Destroy();
@@ -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;
}
}
+24
View File
@@ -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;
};
}