diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj index 00a63eb..ea8af2a 100644 --- a/CopiumEngine/CopiumEngine.vcxproj +++ b/CopiumEngine/CopiumEngine.vcxproj @@ -184,10 +184,12 @@ + + @@ -252,6 +254,7 @@ + @@ -260,6 +263,7 @@ + diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters index 69674bb..c7a2f53 100644 --- a/CopiumEngine/CopiumEngine.vcxproj.filters +++ b/CopiumEngine/CopiumEngine.vcxproj.filters @@ -210,6 +210,12 @@ Source Files + + Source Files + + + Source Files + @@ -452,5 +458,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Scene.cpp b/CopiumEngine/src/copium/core/Scene.cpp index 572343a..60e635c 100644 --- a/CopiumEngine/src/copium/core/Scene.cpp +++ b/CopiumEngine/src/copium/core/Scene.cpp @@ -23,8 +23,9 @@ namespace Copium renderer = std::make_unique(); descriptorSetRenderer = renderer->GetGraphicsPipeline().CreateDescriptorSet(descriptorPool, 1); ecs = std::make_unique(); - ecs->AddSystem(); ecs->AddSystem(renderer.get(), descriptorSetRenderer.get(), &commandBuffer); // better way to store the RenderSystem data? + ecs->AddSystem().Before(); + ecs->AddSystem(); // TODO: Load from scene file for (int y = 0; y < 10; y++) @@ -66,8 +67,7 @@ namespace Copium EventResult Scene::OnEvent(const Event& event) { - // ecs->UpdateEventSystems(event); - MouseFollowSystem{ecs.get(), event}.Run(); // TODO: Remove when I figure out how to handle events in systems + ecs->UpdateSystems(EventSignal{event}); return EventResult::Continue; } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/ecs/ECSManager.cpp b/CopiumEngine/src/copium/ecs/ECSManager.cpp index e9adee7..2bdb1c3 100644 --- a/CopiumEngine/src/copium/ecs/ECSManager.cpp +++ b/CopiumEngine/src/copium/ecs/ECSManager.cpp @@ -22,6 +22,13 @@ namespace Copium systemPool->Update(); } + void ECSManager::UpdateSystems(const Signal& signal) + { + // TODO: Maybe we want a different pool for Signal based Systems for performance reasons? + // Maybe even a pool for each type of Signal? + systemPool->Update(signal); + } + size_t ECSManager::GetEntityCount() const { return entities.size(); diff --git a/CopiumEngine/src/copium/ecs/ECSManager.h b/CopiumEngine/src/copium/ecs/ECSManager.h index 5c28705..1069b9c 100644 --- a/CopiumEngine/src/copium/ecs/ECSManager.h +++ b/CopiumEngine/src/copium/ecs/ECSManager.h @@ -3,6 +3,7 @@ #include "copium/ecs/ComponentPool.h" #include "copium/ecs/Config.h" +#include "copium/ecs/Signal.h" #include "copium/ecs/SystemPool.h" #include "copium/util/Common.h" @@ -33,6 +34,7 @@ namespace Copium } void UpdateSystems(); + void UpdateSystems(const Signal& signal); EntityId CreateEntity(); void DestroyEntity(EntityId entity); diff --git a/CopiumEngine/src/copium/ecs/Signal.cpp b/CopiumEngine/src/copium/ecs/Signal.cpp new file mode 100644 index 0000000..5eae991 --- /dev/null +++ b/CopiumEngine/src/copium/ecs/Signal.cpp @@ -0,0 +1,10 @@ +#include "copium/ecs/Signal.h" + +namespace Copium +{ + int Signal::GetAllocatedId() + { + allocatedIds++; + return allocatedIds; + } +} diff --git a/CopiumEngine/src/copium/ecs/Signal.h b/CopiumEngine/src/copium/ecs/Signal.h new file mode 100644 index 0000000..389661f --- /dev/null +++ b/CopiumEngine/src/copium/ecs/Signal.h @@ -0,0 +1,36 @@ +#pragma once + +#define CP_SIGNAL_DECLERATION(SignalClass) \ + static int GetIdStatic(); \ + int GetId() const override + +#define CP_SIGNAL_DEFINITION(SignalClass) \ + int SignalClass::GetIdStatic() \ + { \ + static int id = GetAllocatedId(); \ + return id; \ + } \ + \ + int SignalClass::GetId() const \ + { \ + return GetIdStatic(); \ + } + +namespace Copium +{ + class Signal + { + private: + static inline int allocatedIds = 0; + + public: + Signal() = default; + virtual ~Signal() = default; + + virtual int GetId() const = 0; + + protected: + static int GetAllocatedId(); + }; + +} diff --git a/CopiumEngine/src/copium/ecs/System.h b/CopiumEngine/src/copium/ecs/System.h index acee026..ed80d0d 100644 --- a/CopiumEngine/src/copium/ecs/System.h +++ b/CopiumEngine/src/copium/ecs/System.h @@ -15,6 +15,12 @@ namespace Copium manager->Each([&](EntityId entityId, Components&... components) { RunEntity(Entity{manager, entityId}, components...); }); } - virtual void RunEntity(Entity entity, Components&... components) = 0; + void Run(const Signal& signal) override + { + manager->Each([&](EntityId entityId, Components&... components) { RunEntity(signal, Entity{manager, entityId}, components...); }); + } + + virtual void RunEntity(Entity entity, Components&... components) {}; + virtual void RunEntity(const Signal& signal, Entity entity, Components&... components) {}; }; } diff --git a/CopiumEngine/src/copium/ecs/SystemBase.h b/CopiumEngine/src/copium/ecs/SystemBase.h index 87cc114..a8d18da 100644 --- a/CopiumEngine/src/copium/ecs/SystemBase.h +++ b/CopiumEngine/src/copium/ecs/SystemBase.h @@ -1,5 +1,7 @@ #pragma once +#include "copium/ecs/Signal.h" + namespace Copium { class ECSManager; @@ -12,5 +14,6 @@ namespace Copium public: virtual void Run() = 0; + virtual void Run(const Signal& signal) = 0; }; } diff --git a/CopiumEngine/src/copium/ecs/SystemPool.cpp b/CopiumEngine/src/copium/ecs/SystemPool.cpp index 24299ba..eb7ea15 100644 --- a/CopiumEngine/src/copium/ecs/SystemPool.cpp +++ b/CopiumEngine/src/copium/ecs/SystemPool.cpp @@ -32,6 +32,14 @@ namespace Copium } } + void SystemPool::Update(const Signal& signal) + { + for (auto& system : systemOrder) + { + system->Run(signal); + } + } + void SystemPool::MoveSystemAfter(const std::type_index& systemId, const std::type_index& afterSystemId) { auto it1 = systems.find(systemId); diff --git a/CopiumEngine/src/copium/ecs/SystemPool.h b/CopiumEngine/src/copium/ecs/SystemPool.h index 17c21f1..b0abe1c 100644 --- a/CopiumEngine/src/copium/ecs/SystemPool.h +++ b/CopiumEngine/src/copium/ecs/SystemPool.h @@ -2,6 +2,7 @@ #include "copium/ecs/SystemBase.h" #include "copium/ecs/SystemOrderer.h" +#include "copium/ecs/Signal.h" #include "copium/util/Common.h" #include @@ -25,6 +26,7 @@ namespace Copium ~SystemPool(); SystemOrderer AddSystem(const std::type_index& systemId, SystemBase* system); void Update(); + void Update(const Signal& signal); void MoveSystemAfter(const std::type_index& systemId, const std::type_index& afterSystemId); void MoveSystemBefore(const std::type_index& systemId, const std::type_index& beforeSystemId); diff --git a/CopiumEngine/src/copium/event/EventSignal.cpp b/CopiumEngine/src/copium/event/EventSignal.cpp new file mode 100644 index 0000000..badffe5 --- /dev/null +++ b/CopiumEngine/src/copium/event/EventSignal.cpp @@ -0,0 +1,15 @@ +#include "copium/event/EventSignal.h" + +namespace Copium +{ + EventSignal::EventSignal(const Event& event) + : event{event} + {} + + const Event& EventSignal::GetEvent() const + { + return event; + } + + CP_SIGNAL_DEFINITION(EventSignal); +} diff --git a/CopiumEngine/src/copium/event/EventSignal.h b/CopiumEngine/src/copium/event/EventSignal.h new file mode 100644 index 0000000..cde8b12 --- /dev/null +++ b/CopiumEngine/src/copium/event/EventSignal.h @@ -0,0 +1,22 @@ +#pragma once + +#include "copium/event/Event.h" +#include "copium/ecs/Signal.h" + +namespace Copium +{ + + class EventSignal : public Signal + { + private: + const Event& event; + + public: + EventSignal(const Event& event); + + const Event& GetEvent() const; + + CP_SIGNAL_DECLERATION(EventSignal); + }; + +} diff --git a/CopiumEngine/src/copium/example/MouseFollowSystem.h b/CopiumEngine/src/copium/example/MouseFollowSystem.h index 96ee3d5..fd14c18 100644 --- a/CopiumEngine/src/copium/example/MouseFollowSystem.h +++ b/CopiumEngine/src/copium/example/MouseFollowSystem.h @@ -3,6 +3,7 @@ #include "copium/core/Vulkan.h" #include "copium/ecs/System.h" #include "copium/event/Event.h" +#include "copium/event/EventSignal.h" #include "copium/event/MouseMoveEvent.h" #include "copium/example/Components.h" @@ -11,23 +12,19 @@ namespace Copium class MouseFollowSystem : public System { public: - const Event& event; - public: - MouseFollowSystem(ECSManager* manager, const Event& event) - : event{event} + void RunEntity(const Signal& signal, Entity entity, MouseFollowC& mouseFollow, TransformC& transform) { - System::manager = manager; - } - - void RunEntity(Entity entity, MouseFollowC& mouseFollow, TransformC& transform) - { - if (event.GetType() == EventType::MouseMove) + if (signal.GetId() == EventSignal::GetIdStatic()) { - const MouseMoveEvent& mouseMoveEvent = static_cast(event); - float aspect = Vulkan::GetSwapChain().GetExtent().width / (float)Vulkan::GetSwapChain().GetExtent().height; - transform.position = {(mouseMoveEvent.GetPos().x / Vulkan::GetSwapChain().GetExtent().width - 0.5) * 2.0 * aspect, - -(mouseMoveEvent.GetPos().y / Vulkan::GetSwapChain().GetExtent().height - 0.5) * 2.0}; - transform.position -= transform.size * glm::vec2{0.5f}; + const EventSignal& eventSignal = static_cast(signal); + if (eventSignal.GetEvent().GetType() == EventType::MouseMove) + { + const MouseMoveEvent& mouseMoveEvent = static_cast(eventSignal.GetEvent()); + float aspect = Vulkan::GetSwapChain().GetExtent().width / (float)Vulkan::GetSwapChain().GetExtent().height; + transform.position = {(mouseMoveEvent.GetPos().x / Vulkan::GetSwapChain().GetExtent().width - 0.5) * 2.0 * aspect, + -(mouseMoveEvent.GetPos().y / Vulkan::GetSwapChain().GetExtent().height - 0.5) * 2.0}; + transform.position -= transform.size * glm::vec2{0.5f}; + } } } }; diff --git a/CopiumEngine/src/copium/example/RenderSystem.h b/CopiumEngine/src/copium/example/RenderSystem.h index f46c701..236e789 100644 --- a/CopiumEngine/src/copium/example/RenderSystem.h +++ b/CopiumEngine/src/copium/example/RenderSystem.h @@ -13,6 +13,7 @@ namespace Copium class RenderSystem : public System { private: + // Find better way to store these? Renderer* renderer; DescriptorSet* descriptorSet; CommandBuffer* commandBuffer; @@ -51,10 +52,6 @@ namespace Copium uniformBuffer.Set("view", glm::mat4(1)); uniformBuffer.Update(); - // Not sure how to put this in the ECSManager system handler - // Potentially have the system take in the descriptorSetRenderer as constructor parameter - // But not sure how commandBuffer can be added, since it can change each frame - // Maybe introducing Resource concept to ECSManager? renderer->SetDescriptorSet(*descriptorSet); renderer->Begin(*commandBuffer); System::Run();