ADD: Quit when Quit button is pressed

This commit is contained in:
sebastian 2026-08-06 17:31:14 +02:00
parent de7cbdc73c
commit fe9ecb1ecc
18 changed files with 110 additions and 12 deletions

View File

@ -265,6 +265,9 @@ add_library(Engine STATIC
engine/src/renderer/GuiRenderer.h engine/src/renderer/GuiRenderer.h
engine/src/renderer/ui/GUITexture.cpp engine/src/renderer/ui/GUITexture.cpp
engine/src/renderer/ui/GUITexture.h 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_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) target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image OpenAL::OpenAL NetworkCore)

View File

@ -15,7 +15,16 @@ namespace engine {
m_inputContextStack(), m_inputContextStack(),
m_keyboard(*m_window), m_keyboard(*m_window),
m_mouse(*m_window), m_mouse(*m_window),
m_sceneManager(m_inputContextStack) { m_sceneManager(m_inputContextStack),
m_applicationEventBus(std::make_shared<EventBus<ApplicationEvents>>()) {
m_applicationEventBus->subscribe([this](ApplicationEvents& event) {
std::visit([this](auto&& e) {
using T = std::decay_t<decltype(e)>;
if constexpr (std::is_same_v<T, QuitRequested>) {
m_window->requestWindowClose();
}
}, event);
});
} }
Application::~Application() = default; Application::~Application() = default;

View File

@ -11,6 +11,7 @@
#include "Window.h" #include "Window.h"
#include "audio/AudioDevice.h" #include "audio/AudioDevice.h"
#include "events/ApplicationEvents.h"
#include "inputsOutputs/context/InputContextStack.h" #include "inputsOutputs/context/InputContextStack.h"
#include "inputsOutputs/inputs/Keyboard.h" #include "inputsOutputs/inputs/Keyboard.h"
#include "inputsOutputs/inputs/Mouse.h" #include "inputsOutputs/inputs/Mouse.h"
@ -25,6 +26,7 @@ namespace engine {
virtual ~Application(); virtual ~Application();
void run(); void run();
void requestClose();
protected: protected:
virtual void onUpdate(float deltaTime) {} virtual void onUpdate(float deltaTime) {}
@ -34,6 +36,7 @@ namespace engine {
Keyboard& getKeyboard() { return m_keyboard; } Keyboard& getKeyboard() { return m_keyboard; }
Mouse& getMouse() { return m_mouse; } Mouse& getMouse() { return m_mouse; }
std::shared_ptr<EventBus<ApplicationEvents>> m_applicationEventBus;
private: private:
EngineConfig m_config; EngineConfig m_config;
std::unique_ptr<Window> m_window; std::unique_ptr<Window> m_window;

View File

@ -84,4 +84,8 @@ namespace engine {
glfwGetFramebufferSize(m_handle, &width, &height); glfwGetFramebufferSize(m_handle, &width, &height);
return height; return height;
} }
void Window::requestWindowClose() {
glfwSetWindowShouldClose(m_handle, true);
}
} }

View File

@ -36,6 +36,8 @@ namespace engine {
void setMouse(Mouse* mouse) { m_callbackTarget.mouse = mouse; } void setMouse(Mouse* mouse) { m_callbackTarget.mouse = mouse; }
void setKeyboard(Keyboard* keyboard) { m_callbackTarget.keyboard = keyboard; } void setKeyboard(Keyboard* keyboard) { m_callbackTarget.keyboard = keyboard; }
void requestWindowClose();
private: private:
GLFWwindow* m_handle; GLFWwindow* m_handle;
CallbackTarget m_callbackTarget; CallbackTarget m_callbackTarget;

View File

@ -0,0 +1,13 @@
//
// Created by sebastian on 06.08.26.
//
#ifndef COLORRACE_APPLICATIONEVENTS_H
#define COLORRACE_APPLICATIONEVENTS_H
#include <variant>
struct QuitRequested {};
using ApplicationEvents = std::variant<QuitRequested>;
#endif //COLORRACE_APPLICATIONEVENTS_H

View File

@ -7,6 +7,11 @@
#include <functional> #include <functional>
namespace engine { namespace engine {
class IEventBus {
public:
virtual ~IEventBus() = default;
};
template<typename Event> template<typename Event>
class EventBus { class EventBus {
public: public:

View File

@ -0,0 +1,5 @@
//
// Created by sebastian on 06.08.26.
//
#include "EventChannels.h"

View File

@ -0,0 +1,43 @@
//
// Created by sebastian on 06.08.26.
//
#ifndef COLORRACE_EVENTCHANNELS_H
#define COLORRACE_EVENTCHANNELS_H
#include <memory>
#include <typeindex>
#include "EventBus.h"
namespace engine {
class EventChannels {
public:
template<typename Event>
void subscribe(typename EventBus<Event>::Handler handler) {
getBus<Event>().subscribe(std::move(handler));
}
template<typename Event>
void publish(Event& event) {
getBus<Event>().publish(event);
}
template<typename Event>
EventBus<Event>& getBus() {
auto key = std::type_index(typeid(Event));
auto it = m_buses.find(key);
if (it == m_buses.end()) {
auto bus = std::make_unique<EventBus<Event>>();
auto* ptr = bus.get();
m_buses.emplace(key, std::move(bus));
return *ptr;
}
return static_cast<EventBus<Event>&>(*it->second);
}
private:
std::unordered_map<std::type_index, std::unique_ptr<IEventBus>> m_buses;
};
}
#endif //COLORRACE_EVENTCHANNELS_H

View File

@ -5,6 +5,7 @@
#ifndef COLORRACE_LAYER_H #ifndef COLORRACE_LAYER_H
#define COLORRACE_LAYER_H #define COLORRACE_LAYER_H
#include "core/animation/events/AnimationMarkerEvent.h" #include "core/animation/events/AnimationMarkerEvent.h"
#include "core/events/ApplicationEvents.h"
#include "core/events/EventBus.h" #include "core/events/EventBus.h"
#include "core/inputsOutputs/context/InputContextStack.h" #include "core/inputsOutputs/context/InputContextStack.h"
#include "core/inputsOutputs/inputs/Keyboard.h" #include "core/inputsOutputs/inputs/Keyboard.h"
@ -16,6 +17,7 @@ namespace engine {
class Layer { class Layer {
public: public:
Layer(Keyboard& keyboard, Mouse& mouse, EventBus<animation::AnimationMarkerEvent>& animationEventBus) : m_keyboard(keyboard), m_mouse(mouse), m_animationEventBus(animationEventBus){}; Layer(Keyboard& keyboard, Mouse& mouse, EventBus<animation::AnimationMarkerEvent>& animationEventBus) : m_keyboard(keyboard), m_mouse(mouse), m_animationEventBus(animationEventBus){};
Layer(Keyboard& keyboard, Mouse& mouse, EventBus<animation::AnimationMarkerEvent>& animationEventBus, std::shared_ptr<EventBus<ApplicationEvents>> applicationEventBus) : m_keyboard(keyboard), m_mouse(mouse), m_animationEventBus(animationEventBus), m_applicationEventBus(std::move(applicationEventBus)){};
virtual ~Layer() = default; virtual ~Layer() = default;
void onAttach(InputContextStack& inputStack); void onAttach(InputContextStack& inputStack);
void onDetach(InputContextStack& inputStack); void onDetach(InputContextStack& inputStack);
@ -29,6 +31,8 @@ namespace engine {
Keyboard& getKeyboard() { return m_keyboard; } Keyboard& getKeyboard() { return m_keyboard; }
Mouse& getMouse() { return m_mouse; } Mouse& getMouse() { return m_mouse; }
EventBus<animation::AnimationMarkerEvent>& getAnimationEventBus() { return m_animationEventBus; } EventBus<animation::AnimationMarkerEvent>& getAnimationEventBus() { return m_animationEventBus; }
std::shared_ptr<EventBus<ApplicationEvents>> m_applicationEventBus;
private: private:
std::shared_ptr<InputContext> m_context; std::shared_ptr<InputContext> m_context;
InputContextStack* m_inputStack = nullptr; InputContextStack* m_inputStack = nullptr;

View File

@ -9,6 +9,7 @@
#include "Layer.h" #include "Layer.h"
#include "core/animation/events/AnimationMarkerEvent.h" #include "core/animation/events/AnimationMarkerEvent.h"
#include "core/events/ApplicationEvents.h"
#include "core/events/EventBus.h" #include "core/events/EventBus.h"
#include "loader/assets/AssetManager.h" #include "loader/assets/AssetManager.h"
#include "loader/assets/AssetRequests.h" #include "loader/assets/AssetRequests.h"
@ -23,8 +24,8 @@ namespace engine {
class Scene { class Scene {
public: public:
explicit Scene(engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse): explicit Scene(std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse):
assetManager(std::make_unique<AssetManager>()), m_inputStack(inputStack), m_keyboard(keyboard), m_mouse(mouse) {} assetManager(std::make_unique<AssetManager>()), m_inputStack(inputStack), m_keyboard(keyboard), m_mouse(mouse), m_applicationEventBus(std::move(applicationEventbus)) {}
virtual ~Scene() = default; virtual ~Scene() = default;
virtual void onEnter() {} virtual void onEnter() {}
virtual void onExit() { virtual void onExit() {
@ -51,9 +52,10 @@ namespace engine {
engine::Keyboard& m_keyboard; engine::Keyboard& m_keyboard;
engine::Mouse& m_mouse; engine::Mouse& m_mouse;
std::shared_ptr<engine::EventBus<ApplicationEvents>> m_applicationEventBus;
private: private:
EventBus<animation::AnimationMarkerEvent> m_animationMarkerEventBus; EventBus<animation::AnimationMarkerEvent> m_animationMarkerEventBus;
}; };
} }

View File

@ -34,7 +34,7 @@ public:
return config; return config;
} }
ColorRaceApp() : Application(makeConfig()) { ColorRaceApp() : Application(makeConfig()) {
getSceneManager().switchTo(std::make_unique<MainMenuScene>(getInputContextStack(), getKeyboard(), getMouse())); getSceneManager().switchTo(std::make_unique<MainMenuScene>(m_applicationEventBus, getInputContextStack(), getKeyboard(), getMouse()));
} }
protected: protected:
void onUpdate(float deltaTime) override; void onUpdate(float deltaTime) override;

View File

@ -12,7 +12,7 @@
#include "layer/DebugLayer.h" #include "layer/DebugLayer.h"
#include "renderer/primitives/SphereFactory.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<engine::Camera>()) { GameScene::GameScene(std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(std::move(applicationEventbus), inputStack, keyboard, mouse), m_camera(std::make_unique<engine::Camera>()) {
m_pointLight = std::make_shared<engine::PointLight>(glm::vec3(.0f, 10.f, -5.0f), glm::vec3(1.0f, 1.0f, 1.0f)); m_pointLight = std::make_shared<engine::PointLight>(glm::vec3(.0f, 10.f, -5.0f), glm::vec3(1.0f, 1.0f, 1.0f));
const std::vector<unsigned int> players = {0,1,2,3}; const std::vector<unsigned int> players = {0,1,2,3};
m_gameMode = std::make_shared<ludo::LudoGameMode>(m_eventBus, players); m_gameMode = std::make_shared<ludo::LudoGameMode>(m_eventBus, players);

View File

@ -12,7 +12,7 @@
class GameScene : public engine::Scene { class GameScene : public engine::Scene {
public: public:
GameScene(engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse); GameScene(std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse);
void onEnter() override; void onEnter() override;
void onExit() override; void onExit() override;
std::vector<engine::AssetRequest> getRequiredAssets() const override; std::vector<engine::AssetRequest> getRequiredAssets() const override;

View File

@ -8,7 +8,7 @@
void MainMenuScene::onEnter() { void MainMenuScene::onEnter() {
Scene::onEnter(); Scene::onEnter();
addLayer(std::make_unique<MainMenuUiLayer>(m_keyboard, m_mouse, getAnimationEventBus(), *assetManager)); addLayer(std::make_unique<MainMenuUiLayer>(m_keyboard, m_mouse, getAnimationEventBus(), m_applicationEventBus, *assetManager));
} }
std::vector<engine::AssetRequest> MainMenuScene::getRequiredAssets() const { std::vector<engine::AssetRequest> MainMenuScene::getRequiredAssets() const {

View File

@ -4,12 +4,14 @@
#ifndef COLORRACE_MAINMENUSCENE_H #ifndef COLORRACE_MAINMENUSCENE_H
#define COLORRACE_MAINMENUSCENE_H #define COLORRACE_MAINMENUSCENE_H
#include <utility>
#include "layer/Scene.h" #include "layer/Scene.h"
class MainMenuScene : public engine::Scene { class MainMenuScene : public engine::Scene {
public: public:
MainMenuScene(engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(inputContext, keyboard, mouse) {} MainMenuScene(std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(std::move(applicationEventbus), inputContext, keyboard, mouse) {}
void onEnter() override; void onEnter() override;
std::vector<engine::AssetRequest> getRequiredAssets() const override; std::vector<engine::AssetRequest> getRequiredAssets() const override;
}; };

View File

@ -35,7 +35,8 @@ void MainMenuUiLayer::onRender() {
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Quit", buttonSize)) { if (ImGui::Button("Quit", buttonSize)) {
ApplicationEvents e = QuitRequested{};
m_applicationEventBus->publish(e);
} }
ImGui::End(); ImGui::End();

View File

@ -4,6 +4,8 @@
#ifndef COLORRACE_MAINMENUUILAYER_H #ifndef COLORRACE_MAINMENUUILAYER_H
#define COLORRACE_MAINMENUUILAYER_H #define COLORRACE_MAINMENUUILAYER_H
#include <utility>
#include "layer/Layer.h" #include "layer/Layer.h"
#include "loader/assets/AssetManager.h" #include "loader/assets/AssetManager.h"
#include "renderer/GuiRenderer.h" #include "renderer/GuiRenderer.h"
@ -12,8 +14,8 @@
class MainMenuUiLayer : public engine::Layer { class MainMenuUiLayer : public engine::Layer {
public: public:
MainMenuUiLayer(engine::Keyboard &keyboard, engine::Mouse &mouse, engine::EventBus<engine::animation::AnimationMarkerEvent> &animationEventBus, engine::AssetManager& assetManager) MainMenuUiLayer(engine::Keyboard &keyboard, engine::Mouse &mouse, engine::EventBus<engine::animation::AnimationMarkerEvent> &animationEventBus, std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, engine::AssetManager& assetManager)
: Layer(keyboard, mouse, animationEventBus), m_assetManager(assetManager) { : Layer(keyboard, mouse, animationEventBus, std::move(applicationEventbus)), m_assetManager(assetManager) {
} }
void onRender() override; void onRender() override;