From fe9ecb1ecc9dc3273c1f8f9efedee841662a64e6 Mon Sep 17 00:00:00 2001 From: sebastian Date: Thu, 6 Aug 2026 17:31:14 +0200 Subject: [PATCH] ADD: Quit when Quit button is pressed --- CMakeLists.txt | 3 ++ engine/src/core/Application.cpp | 11 +++++- engine/src/core/Application.h | 3 ++ engine/src/core/Window.cpp | 4 ++ engine/src/core/Window.h | 2 + engine/src/core/events/ApplicationEvents.h | 13 +++++++ engine/src/core/events/EventBus.h | 5 +++ engine/src/core/events/EventChannels.cpp | 5 +++ engine/src/core/events/EventChannels.h | 43 +++++++++++++++++++++ engine/src/layer/Layer.h | 4 ++ engine/src/layer/Scene.h | 8 ++-- game/src/ColorRaceApp.h | 2 +- game/src/GameScene.cpp | 2 +- game/src/GameScene.h | 2 +- game/src/mainMenu/MainMenuScene.cpp | 2 +- game/src/mainMenu/MainMenuScene.h | 4 +- game/src/mainMenu/layer/MainMenuUiLayer.cpp | 3 +- game/src/mainMenu/layer/MainMenuUiLayer.h | 6 ++- 18 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 engine/src/core/events/ApplicationEvents.h create mode 100644 engine/src/core/events/EventChannels.cpp create mode 100644 engine/src/core/events/EventChannels.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f0b175..b445e6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -265,6 +265,9 @@ add_library(Engine STATIC engine/src/renderer/GuiRenderer.h engine/src/renderer/ui/GUITexture.cpp engine/src/renderer/ui/GUITexture.h + engine/src/core/events/ApplicationEvents.h + engine/src/core/events/EventChannels.cpp + engine/src/core/events/EventChannels.h ) target_include_directories(Engine PUBLIC engine/src ${dr_libs_SOURCE_DIR}) target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image OpenAL::OpenAL NetworkCore) diff --git a/engine/src/core/Application.cpp b/engine/src/core/Application.cpp index 106596d..318c43a 100644 --- a/engine/src/core/Application.cpp +++ b/engine/src/core/Application.cpp @@ -15,7 +15,16 @@ namespace engine { m_inputContextStack(), m_keyboard(*m_window), m_mouse(*m_window), - m_sceneManager(m_inputContextStack) { + m_sceneManager(m_inputContextStack), + m_applicationEventBus(std::make_shared>()) { + m_applicationEventBus->subscribe([this](ApplicationEvents& event) { + std::visit([this](auto&& e) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + m_window->requestWindowClose(); + } + }, event); + }); } Application::~Application() = default; diff --git a/engine/src/core/Application.h b/engine/src/core/Application.h index 61ff6fb..f3cb195 100644 --- a/engine/src/core/Application.h +++ b/engine/src/core/Application.h @@ -11,6 +11,7 @@ #include "Window.h" #include "audio/AudioDevice.h" +#include "events/ApplicationEvents.h" #include "inputsOutputs/context/InputContextStack.h" #include "inputsOutputs/inputs/Keyboard.h" #include "inputsOutputs/inputs/Mouse.h" @@ -25,6 +26,7 @@ namespace engine { virtual ~Application(); void run(); + void requestClose(); protected: virtual void onUpdate(float deltaTime) {} @@ -34,6 +36,7 @@ namespace engine { Keyboard& getKeyboard() { return m_keyboard; } Mouse& getMouse() { return m_mouse; } + std::shared_ptr> m_applicationEventBus; private: EngineConfig m_config; std::unique_ptr m_window; diff --git a/engine/src/core/Window.cpp b/engine/src/core/Window.cpp index 82e984f..28542cb 100644 --- a/engine/src/core/Window.cpp +++ b/engine/src/core/Window.cpp @@ -84,4 +84,8 @@ namespace engine { glfwGetFramebufferSize(m_handle, &width, &height); return height; } + + void Window::requestWindowClose() { + glfwSetWindowShouldClose(m_handle, true); + } } diff --git a/engine/src/core/Window.h b/engine/src/core/Window.h index 71d32dd..ecbb29b 100644 --- a/engine/src/core/Window.h +++ b/engine/src/core/Window.h @@ -36,6 +36,8 @@ namespace engine { void setMouse(Mouse* mouse) { m_callbackTarget.mouse = mouse; } void setKeyboard(Keyboard* keyboard) { m_callbackTarget.keyboard = keyboard; } + + void requestWindowClose(); private: GLFWwindow* m_handle; CallbackTarget m_callbackTarget; diff --git a/engine/src/core/events/ApplicationEvents.h b/engine/src/core/events/ApplicationEvents.h new file mode 100644 index 0000000..4b24b95 --- /dev/null +++ b/engine/src/core/events/ApplicationEvents.h @@ -0,0 +1,13 @@ +// +// Created by sebastian on 06.08.26. +// + +#ifndef COLORRACE_APPLICATIONEVENTS_H +#define COLORRACE_APPLICATIONEVENTS_H +#include + +struct QuitRequested {}; + + +using ApplicationEvents = std::variant; +#endif //COLORRACE_APPLICATIONEVENTS_H diff --git a/engine/src/core/events/EventBus.h b/engine/src/core/events/EventBus.h index 0e00444..0da47c4 100644 --- a/engine/src/core/events/EventBus.h +++ b/engine/src/core/events/EventBus.h @@ -7,6 +7,11 @@ #include namespace engine { + class IEventBus { + public: + virtual ~IEventBus() = default; + }; + template class EventBus { public: diff --git a/engine/src/core/events/EventChannels.cpp b/engine/src/core/events/EventChannels.cpp new file mode 100644 index 0000000..89edd32 --- /dev/null +++ b/engine/src/core/events/EventChannels.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 06.08.26. +// + +#include "EventChannels.h" diff --git a/engine/src/core/events/EventChannels.h b/engine/src/core/events/EventChannels.h new file mode 100644 index 0000000..737ac35 --- /dev/null +++ b/engine/src/core/events/EventChannels.h @@ -0,0 +1,43 @@ +// +// Created by sebastian on 06.08.26. +// + +#ifndef COLORRACE_EVENTCHANNELS_H +#define COLORRACE_EVENTCHANNELS_H +#include +#include + +#include "EventBus.h" + + +namespace engine { + class EventChannels { + public: + template + void subscribe(typename EventBus::Handler handler) { + getBus().subscribe(std::move(handler)); + } + + template + void publish(Event& event) { + getBus().publish(event); + } + + template + EventBus& getBus() { + auto key = std::type_index(typeid(Event)); + auto it = m_buses.find(key); + if (it == m_buses.end()) { + auto bus = std::make_unique>(); + auto* ptr = bus.get(); + m_buses.emplace(key, std::move(bus)); + return *ptr; + } + return static_cast&>(*it->second); + } + private: + std::unordered_map> m_buses; + }; +} + +#endif //COLORRACE_EVENTCHANNELS_H diff --git a/engine/src/layer/Layer.h b/engine/src/layer/Layer.h index fdc08a5..90d8f3e 100644 --- a/engine/src/layer/Layer.h +++ b/engine/src/layer/Layer.h @@ -5,6 +5,7 @@ #ifndef COLORRACE_LAYER_H #define COLORRACE_LAYER_H #include "core/animation/events/AnimationMarkerEvent.h" +#include "core/events/ApplicationEvents.h" #include "core/events/EventBus.h" #include "core/inputsOutputs/context/InputContextStack.h" #include "core/inputsOutputs/inputs/Keyboard.h" @@ -16,6 +17,7 @@ namespace engine { class Layer { public: Layer(Keyboard& keyboard, Mouse& mouse, EventBus& animationEventBus) : m_keyboard(keyboard), m_mouse(mouse), m_animationEventBus(animationEventBus){}; + Layer(Keyboard& keyboard, Mouse& mouse, EventBus& animationEventBus, std::shared_ptr> applicationEventBus) : m_keyboard(keyboard), m_mouse(mouse), m_animationEventBus(animationEventBus), m_applicationEventBus(std::move(applicationEventBus)){}; virtual ~Layer() = default; void onAttach(InputContextStack& inputStack); void onDetach(InputContextStack& inputStack); @@ -29,6 +31,8 @@ namespace engine { Keyboard& getKeyboard() { return m_keyboard; } Mouse& getMouse() { return m_mouse; } EventBus& getAnimationEventBus() { return m_animationEventBus; } + + std::shared_ptr> m_applicationEventBus; private: std::shared_ptr m_context; InputContextStack* m_inputStack = nullptr; diff --git a/engine/src/layer/Scene.h b/engine/src/layer/Scene.h index 237d8b5..c48559f 100644 --- a/engine/src/layer/Scene.h +++ b/engine/src/layer/Scene.h @@ -9,6 +9,7 @@ #include "Layer.h" #include "core/animation/events/AnimationMarkerEvent.h" +#include "core/events/ApplicationEvents.h" #include "core/events/EventBus.h" #include "loader/assets/AssetManager.h" #include "loader/assets/AssetRequests.h" @@ -23,8 +24,8 @@ namespace engine { class Scene { public: - explicit Scene(engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse): - assetManager(std::make_unique()), m_inputStack(inputStack), m_keyboard(keyboard), m_mouse(mouse) {} + explicit Scene(std::shared_ptr> applicationEventbus, engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse): + assetManager(std::make_unique()), m_inputStack(inputStack), m_keyboard(keyboard), m_mouse(mouse), m_applicationEventBus(std::move(applicationEventbus)) {} virtual ~Scene() = default; virtual void onEnter() {} virtual void onExit() { @@ -51,9 +52,10 @@ namespace engine { engine::Keyboard& m_keyboard; engine::Mouse& m_mouse; - + std::shared_ptr> m_applicationEventBus; private: EventBus m_animationMarkerEventBus; + }; } diff --git a/game/src/ColorRaceApp.h b/game/src/ColorRaceApp.h index c3e1b66..e8f5845 100644 --- a/game/src/ColorRaceApp.h +++ b/game/src/ColorRaceApp.h @@ -34,7 +34,7 @@ public: return config; } ColorRaceApp() : Application(makeConfig()) { - getSceneManager().switchTo(std::make_unique(getInputContextStack(), getKeyboard(), getMouse())); + getSceneManager().switchTo(std::make_unique(m_applicationEventBus, getInputContextStack(), getKeyboard(), getMouse())); } protected: void onUpdate(float deltaTime) override; diff --git a/game/src/GameScene.cpp b/game/src/GameScene.cpp index 75061f5..7e64e37 100644 --- a/game/src/GameScene.cpp +++ b/game/src/GameScene.cpp @@ -12,7 +12,7 @@ #include "layer/DebugLayer.h" #include "renderer/primitives/SphereFactory.h" -GameScene::GameScene(engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(inputStack, keyboard, mouse), m_camera(std::make_unique()) { +GameScene::GameScene(std::shared_ptr> applicationEventbus, engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(std::move(applicationEventbus), inputStack, keyboard, mouse), m_camera(std::make_unique()) { m_pointLight = std::make_shared(glm::vec3(.0f, 10.f, -5.0f), glm::vec3(1.0f, 1.0f, 1.0f)); const std::vector players = {0,1,2,3}; m_gameMode = std::make_shared(m_eventBus, players); diff --git a/game/src/GameScene.h b/game/src/GameScene.h index 6c16062..e03c05b 100644 --- a/game/src/GameScene.h +++ b/game/src/GameScene.h @@ -12,7 +12,7 @@ class GameScene : public engine::Scene { public: - GameScene(engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse); + GameScene(std::shared_ptr> applicationEventbus, engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse); void onEnter() override; void onExit() override; std::vector getRequiredAssets() const override; diff --git a/game/src/mainMenu/MainMenuScene.cpp b/game/src/mainMenu/MainMenuScene.cpp index 563b79d..33c344b 100644 --- a/game/src/mainMenu/MainMenuScene.cpp +++ b/game/src/mainMenu/MainMenuScene.cpp @@ -8,7 +8,7 @@ void MainMenuScene::onEnter() { Scene::onEnter(); - addLayer(std::make_unique(m_keyboard, m_mouse, getAnimationEventBus(), *assetManager)); + addLayer(std::make_unique(m_keyboard, m_mouse, getAnimationEventBus(), m_applicationEventBus, *assetManager)); } std::vector MainMenuScene::getRequiredAssets() const { diff --git a/game/src/mainMenu/MainMenuScene.h b/game/src/mainMenu/MainMenuScene.h index dd149d0..be58bc2 100644 --- a/game/src/mainMenu/MainMenuScene.h +++ b/game/src/mainMenu/MainMenuScene.h @@ -4,12 +4,14 @@ #ifndef COLORRACE_MAINMENUSCENE_H #define COLORRACE_MAINMENUSCENE_H +#include + #include "layer/Scene.h" class MainMenuScene : public engine::Scene { public: - MainMenuScene(engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(inputContext, keyboard, mouse) {} + MainMenuScene(std::shared_ptr> applicationEventbus, engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(std::move(applicationEventbus), inputContext, keyboard, mouse) {} void onEnter() override; std::vector getRequiredAssets() const override; }; diff --git a/game/src/mainMenu/layer/MainMenuUiLayer.cpp b/game/src/mainMenu/layer/MainMenuUiLayer.cpp index fb089cd..4e733f1 100644 --- a/game/src/mainMenu/layer/MainMenuUiLayer.cpp +++ b/game/src/mainMenu/layer/MainMenuUiLayer.cpp @@ -35,7 +35,8 @@ void MainMenuUiLayer::onRender() { ImGui::Spacing(); if (ImGui::Button("Quit", buttonSize)) { - + ApplicationEvents e = QuitRequested{}; + m_applicationEventBus->publish(e); } ImGui::End(); diff --git a/game/src/mainMenu/layer/MainMenuUiLayer.h b/game/src/mainMenu/layer/MainMenuUiLayer.h index 7ccd42e..f9d83c4 100644 --- a/game/src/mainMenu/layer/MainMenuUiLayer.h +++ b/game/src/mainMenu/layer/MainMenuUiLayer.h @@ -4,6 +4,8 @@ #ifndef COLORRACE_MAINMENUUILAYER_H #define COLORRACE_MAINMENUUILAYER_H +#include + #include "layer/Layer.h" #include "loader/assets/AssetManager.h" #include "renderer/GuiRenderer.h" @@ -12,8 +14,8 @@ class MainMenuUiLayer : public engine::Layer { public: - MainMenuUiLayer(engine::Keyboard &keyboard, engine::Mouse &mouse, engine::EventBus &animationEventBus, engine::AssetManager& assetManager) - : Layer(keyboard, mouse, animationEventBus), m_assetManager(assetManager) { + MainMenuUiLayer(engine::Keyboard &keyboard, engine::Mouse &mouse, engine::EventBus &animationEventBus, std::shared_ptr> applicationEventbus, engine::AssetManager& assetManager) + : Layer(keyboard, mouse, animationEventBus, std::move(applicationEventbus)), m_assetManager(assetManager) { } void onRender() override;