diff --git a/Sandbox/src/Engine/Engine.cpp b/Sandbox/src/Engine/Engine.cpp index 5885069..0c06245 100644 --- a/Sandbox/src/Engine/Engine.cpp +++ b/Sandbox/src/Engine/Engine.cpp @@ -19,8 +19,6 @@ void Prune::Engine::Up() Engine::SDLInit(); Engine::SDLCreateWindow(); Engine::SDLCreateRenderer(); - - entt::registry m_Registry; } void Prune::Engine::Down() diff --git a/Sandbox/src/Engine/Engine.h b/Sandbox/src/Engine/Engine.h index 81d5d9e..58361ac 100644 --- a/Sandbox/src/Engine/Engine.h +++ b/Sandbox/src/Engine/Engine.h @@ -33,9 +33,7 @@ namespace Prune { SDL_Window* m_Window = nullptr; SDL_Renderer* m_Renderer = nullptr; - - entt::registry m_Registry; - + void SDLCreateRenderer(); void SDLCreateWindow(); void SDLInit(); diff --git a/Sandbox/src/Engine/Event/CollisionEvent.h b/Sandbox/src/Engine/Event/CollisionEvent.h new file mode 100644 index 0000000..1b5be27 --- /dev/null +++ b/Sandbox/src/Engine/Event/CollisionEvent.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include "../../../Event/Event.h" + +namespace Prune +{ + class CollisionEvent : public Event + { + public: + entt::entity a; + entt::entity b; + entt::registry& registry; + + CollisionEvent(entt::registry& registry, entt::entity a, entt::entity b) : registry(registry), a(a), b(b) {} + + private: + + }; +} \ No newline at end of file diff --git a/Sandbox/src/Engine/System/Update/BoxCollider2DCollisionSystem.cpp b/Sandbox/src/Engine/System/Update/BoxCollider2DCollisionSystem.cpp index d869946..b0afa41 100644 --- a/Sandbox/src/Engine/System/Update/BoxCollider2DCollisionSystem.cpp +++ b/Sandbox/src/Engine/System/Update/BoxCollider2DCollisionSystem.cpp @@ -1,9 +1,10 @@ #include "BoxCollider2DCollisionSystem.h" #include "../../Component/TransformComponent.h" #include "../../Component/BoxCollider2DComponent.h" +#include "../../Event/CollisionEvent.h" #include "../../../Log/Log.h" -void Prune::BoxCollider2DCollisionSystem::Update(entt::registry& registry) +void Prune::BoxCollider2DCollisionSystem::Update(entt::registry& registry, std::unique_ptr& eventBus) { auto outer_view = registry.view(); @@ -36,6 +37,7 @@ void Prune::BoxCollider2DCollisionSystem::Update(entt::registry& registry) if (collision) { + eventBus->EmitEvent(registry, inner_entity, outer_entity); PRUNE_LOG_INFO("There has been a collision!!!"); } } diff --git a/Sandbox/src/Engine/System/Update/BoxCollider2DCollisionSystem.h b/Sandbox/src/Engine/System/Update/BoxCollider2DCollisionSystem.h index 3a80cc9..5e306a4 100644 --- a/Sandbox/src/Engine/System/Update/BoxCollider2DCollisionSystem.h +++ b/Sandbox/src/Engine/System/Update/BoxCollider2DCollisionSystem.h @@ -1,5 +1,6 @@ #include #include +#include "../../../Event/EventBus.h" namespace Prune { @@ -13,7 +14,7 @@ namespace Prune BoxCollider2DCollisionSystem() = default; ~BoxCollider2DCollisionSystem() = default; - void Update(entt::registry& registry); + void Update(entt::registry& registry, std::unique_ptr& eventBus); private: bool checkForCollision( diff --git a/Sandbox/src/Engine/System/Update/DamageSystem.cpp b/Sandbox/src/Engine/System/Update/DamageSystem.cpp new file mode 100644 index 0000000..ff3baf2 --- /dev/null +++ b/Sandbox/src/Engine/System/Update/DamageSystem.cpp @@ -0,0 +1,15 @@ +#include "DamageSystem.h" +#include "../../../Log/Log.h" + +void Prune::DamageSystem::SubscribeToEvents(std::unique_ptr& eventBus) +{ + eventBus->SubscribeToEvent(this, &DamageSystem::OnCollision); +} + +void Prune::DamageSystem::OnCollision(CollisionEvent& event) +{ + event.registry.destroy(event.a); + event.registry.destroy(event.b); + + PRUNE_LOG_INFO("Called the OnCollision callback method and killed the entities"); +} diff --git a/Sandbox/src/Engine/System/Update/DamageSystem.h b/Sandbox/src/Engine/System/Update/DamageSystem.h new file mode 100644 index 0000000..3bd0833 --- /dev/null +++ b/Sandbox/src/Engine/System/Update/DamageSystem.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include "../../../Event/EventBus.h" +#include "../../Event/CollisionEvent.h" + +namespace Prune +{ + class DamageSystem + { + public: + DamageSystem() = default; + ~DamageSystem() = default; + + void SubscribeToEvents(std::unique_ptr& eventBus); + + void OnCollision(CollisionEvent& event); + + private: + }; +} diff --git a/Sandbox/src/Event/Event.h b/Sandbox/src/Event/Event.h new file mode 100644 index 0000000..9a39dc0 --- /dev/null +++ b/Sandbox/src/Event/Event.h @@ -0,0 +1,10 @@ +#pragma once + +namespace Prune +{ + class Event + { + public: + Event() = default; + }; +} diff --git a/Sandbox/src/Event/EventBus.h b/Sandbox/src/Event/EventBus.h new file mode 100644 index 0000000..8396999 --- /dev/null +++ b/Sandbox/src/Event/EventBus.h @@ -0,0 +1,86 @@ +#pragma once + +#include +#include +#include +#include +#include "Event.h" + +namespace Prune +{ + class IEventCallback + { + public: + virtual ~IEventCallback() = default; + + void Execute(Event& e) { + Call(e); + } + + private: + virtual void Call(Event& e) = 0; + + }; + + template + class EventCallback : public IEventCallback + { + private: + typedef void (TOwner::* CallbackFunction)(TEvent&); + + TOwner* ownerInstance; + CallbackFunction callbackFunction; + + virtual void Call(Event& e) override { + std::invoke(callbackFunction, ownerInstance, static_cast(e)); + } + + public: + EventCallback(TOwner* ownerInstance, CallbackFunction callbackFunction) + { + this->ownerInstance = ownerInstance; + this->callbackFunction = callbackFunction; + } + + virtual ~EventCallback() override = default; + }; + + typedef std::list> HandlerList; + class EventBus + { + public: + EventBus() = default; + ~EventBus() = default; + + void Reset() + { + subscribers.clear(); + } + + template + void SubscribeToEvent(TOwner* ownerInstance, void (TOwner::* callbackFunction)(TEvent&)) + { + if (!subscribers[typeid(TEvent)].get()) { + subscribers[typeid(TEvent)] = std::make_unique(); + } + auto subscriber = std::make_unique>(ownerInstance, callbackFunction); + subscribers[typeid(TEvent)]->push_back(std::move(subscriber)); + } + + template + void EmitEvent(TArgs&& ...args) { + auto handlers = subscribers[typeid(TEvent)].get(); + if (handlers) + { + for (auto it = handlers->begin(); it != handlers->end(); it++) + { + auto handler = it->get(); + TEvent event(std::forward(args)...); + handler->Execute(event); + } + } + } + private: + std::map> subscribers; + }; +} diff --git a/Sandbox/src/Game/Game.cpp b/Sandbox/src/Game/Game.cpp index b974604..9daa4c1 100644 --- a/Sandbox/src/Game/Game.cpp +++ b/Sandbox/src/Game/Game.cpp @@ -6,6 +6,7 @@ #include "../Engine/Component/VelocityComponent.h" #include "../Engine/System/Update/AnimatedSpriteSystem.h" #include "../Engine/System/Update/BoxCollider2DCollisionSystem.h" +#include "../Engine/System/Update/DamageSystem.h" #include "../Engine/System/Update/MovementSystem.h" #include "../Engine/System/Render/BoxCollider2DRenderSystem.h" #include "../Engine/System/Render/SpriteRenderSystem.h" @@ -15,6 +16,7 @@ Prune::Game::Game() InitECS(); m_SpriteLibrary = SpriteLibrary(); + m_EventBus = std::make_unique(); m_IsRunning = true; } @@ -38,6 +40,8 @@ void Prune::Game::Run() double deltaTime = (frameStartTime - frameEndTime) / 1000.f; + m_EventBus->Reset(); + RunSystems(deltaTime); Render(); @@ -115,6 +119,9 @@ void Prune::Game::AddSpritesToLibrary() void Prune::Game::RunSystems(double delta) { + DamageSystem damageSystem = DamageSystem(); + damageSystem.SubscribeToEvents(m_EventBus); + MovementSystem movementSystem = MovementSystem(); movementSystem.Update(m_Registry, delta); @@ -122,7 +129,7 @@ void Prune::Game::RunSystems(double delta) animatedSpriteSystem.Update(m_Registry); BoxCollider2DCollisionSystem boxCollider2DCollisionSystem = BoxCollider2DCollisionSystem(); - boxCollider2DCollisionSystem.Update(m_Registry); + boxCollider2DCollisionSystem.Update(m_Registry, m_EventBus); } void Prune::Game::RenderEntities() diff --git a/Sandbox/src/Game/Game.h b/Sandbox/src/Game/Game.h index 893462a..b9c6276 100644 --- a/Sandbox/src/Game/Game.h +++ b/Sandbox/src/Game/Game.h @@ -2,6 +2,7 @@ #include #include +#include "../Event/EventBus.h" #include "../Library/SpriteLibrary.h" namespace Prune @@ -19,6 +20,7 @@ namespace Prune private: SDL_Renderer* m_Renderer = nullptr; entt::registry m_Registry; + std::unique_ptr m_EventBus; SpriteLibrary m_SpriteLibrary; bool m_ShowBoxColliders2D = false;