diff --git a/extern/SDL b/extern/SDL index e027b85..f686492 160000 --- a/extern/SDL +++ b/extern/SDL @@ -1 +1 @@ -Subproject commit e027b85cc457556071cbb2f3f1bcf8803c1bc001 +Subproject commit f6864924f76e1a0b4abaefc76ae2ed22b1a8916e diff --git a/include/EventListener.h b/include/EventListener.h new file mode 100644 index 0000000..6e124ab --- /dev/null +++ b/include/EventListener.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include + +class EventListener { +public: + virtual SDL_AppResult handleEvent(SDL_EventType type, SDL_Event* event) = 0; + EventListener() {}; + virtual ~EventListener() {}; +}; \ No newline at end of file diff --git a/include/EventManager.h b/include/EventManager.h new file mode 100644 index 0000000..04daeb6 --- /dev/null +++ b/include/EventManager.h @@ -0,0 +1,18 @@ +#pragma once + +#include "EventListener.h" + +#include +#include +#include + +#include "SDL3/SDL_events.h" +#include "SDL3/SDL_init.h" + +class EventManager { +public: + void registerListener(EventListener* listener, std::initializer_list eventTypes); + SDL_AppResult handleEvent(SDL_Event* event); +private: + std::map> eventListeners = std::map>(); +}; \ No newline at end of file diff --git a/include/GameInternal.h b/include/GameInternal.h index 3850b43..aedfff4 100644 --- a/include/GameInternal.h +++ b/include/GameInternal.h @@ -7,7 +7,10 @@ #include #include +#include "EventManager.h" #include "Manager.h" +#include "SDL3/SDL_events.h" +#include "SDL3/SDL_init.h" #include "Vector2D.h" #include "Entity.h" #include "RenderManager.h" @@ -31,6 +34,7 @@ public: SDL_AppResult init(); void handleEvents(); + SDL_AppResult handleEvent(SDL_Event* event); void update(Uint64 frameTime); void render(); void clean(); @@ -47,6 +51,7 @@ public: Manager manager; RenderManager renderManager; + EventManager eventManager; Map* map; // game specific, might not be needed for all types of games ConfigLoader* config; diff --git a/include/VEGO_Event.h b/include/VEGO_Event.h new file mode 100644 index 0000000..b74e1a2 --- /dev/null +++ b/include/VEGO_Event.h @@ -0,0 +1,5 @@ +#pragma once + +enum VEGO_Event { + VEGO_Event_Interaction = SDL_EVENT_USER +}; \ No newline at end of file diff --git a/src/EventManager.cpp b/src/EventManager.cpp new file mode 100644 index 0000000..93e760b --- /dev/null +++ b/src/EventManager.cpp @@ -0,0 +1,33 @@ +#include "EventManager.h" +#include "EventListener.h" +#include "SDL3/SDL_events.h" +#include "SDL3/SDL_init.h" +#include +#include +#include + +void EventManager::registerListener(EventListener* listener, std::initializer_list eventTypes) +{ + std::ranges::for_each(eventTypes.begin(), eventTypes.end(), [this, &listener](const SDL_EventType& eventType) { + if (!this->eventListeners.contains(eventType)) { + this->eventListeners.insert({eventType, std::vector()}); + } + this->eventListeners.at(eventType).emplace_back(listener); + }); +} + +SDL_AppResult EventManager::handleEvent(SDL_Event* event) +{ + SDL_EventType type = (SDL_EventType) event->type; + if (this->eventListeners.contains(type)) { + auto results = this->eventListeners.at(type) | std::views::transform( + [&event](EventListener* listener) { + return listener->handleEvent((SDL_EventType) event->type, event); + }); + if (std::ranges::contains(results, SDL_APP_FAILURE)) + return SDL_APP_FAILURE; + if (std::ranges::contains(results, SDL_APP_SUCCESS)) + return SDL_APP_SUCCESS; + } + return SDL_APP_CONTINUE; +} \ No newline at end of file diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 77becb6..8e8d605 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -4,6 +4,7 @@ #include "AssetManager.h" #include "RenderManager.h" #include +#include "SDL3/SDL_events.h" #include "SDL3/SDL_init.h" #include "SoundManager.h" #include "Entity.h" @@ -14,6 +15,7 @@ #include "GameFactory.h" #include +#include #include "ConfigLoader.h" @@ -44,6 +46,9 @@ SDL_AppResult GameInternal::init() GameInternal::soundManager = new SoundManager(); GameInternal::collisionHandler = new CollisionHandler(manager); // why does this use a referrence, but AssetManager a pointer? + /// \TODO: from c++26 you (should be able to) can loop through all values of an enum + SDL_RegisterEvents(VEGO_Event_Interaction); + int flags = 0; if (finalConfig.at("fullscreen")) { @@ -126,6 +131,10 @@ void GameInternal::handleEvents() } } +SDL_AppResult GameInternal::handleEvent(SDL_Event* event) { + return this->eventManager.handleEvent(event); +} + void GameInternal::update(Uint64 frameTime) { manager.refresh(); diff --git a/src/_Init.cpp b/src/_Init.cpp index d108b73..b32a1ea 100644 --- a/src/_Init.cpp +++ b/src/_Init.cpp @@ -40,7 +40,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) { } SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { - return SDL_APP_CONTINUE; + return vego::game->handleEvent(event); } void SDL_AppQuit(void *appstate, SDL_AppResult result) {