From 6706f9acf0554994095ad9ca1462a02e0b6c278f Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 17 Sep 2022 22:33:11 +0800 Subject: [PATCH] SP3-108 Created templated derived classes for events to accommodate for automatic type sending ability --- SHADE_Engine/src/Events/SHEvent.h | 12 +++++++++- SHADE_Engine/src/Events/SHEventDefines.h | 1 - SHADE_Engine/src/Events/SHEventManager.cpp | 24 ++++++++------------ SHADE_Engine/src/Events/SHEventManager.h | 26 ++++++++++++++-------- SHADE_Engine/src/Events/SHEventReceiver.h | 8 +++---- 5 files changed, 41 insertions(+), 30 deletions(-) diff --git a/SHADE_Engine/src/Events/SHEvent.h b/SHADE_Engine/src/Events/SHEvent.h index 2ca6648e..217609d3 100644 --- a/SHADE_Engine/src/Events/SHEvent.h +++ b/SHADE_Engine/src/Events/SHEvent.h @@ -16,7 +16,17 @@ namespace SHADE struct SHEvent { SHEventIdentifier type; - SHEventDataPtr dataPtr; SHEventHandle handle; }; + + template + struct SHEventSpec : SHEvent + { + SHEventSpec(SHEventIdentifier t, SHEventHandle e, T* dp) + :SHEvent{ t, e }, data{ dp } {} + + std::shared_ptr data; + }; + + using SHEventPtr = std::shared_ptr; } diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index 76b403bd..db8d7752 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -3,7 +3,6 @@ typedef uint32_t SHEventIdentifier; typedef uint32_t SHEventHandle; -typedef void* SHEventDataPtr; //Add your event identifiers here: constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0}; \ No newline at end of file diff --git a/SHADE_Engine/src/Events/SHEventManager.cpp b/SHADE_Engine/src/Events/SHEventManager.cpp index 1cede2a0..4372cf6d 100644 --- a/SHADE_Engine/src/Events/SHEventManager.cpp +++ b/SHADE_Engine/src/Events/SHEventManager.cpp @@ -13,7 +13,6 @@ namespace SHADE { std::unordered_map SHEventManager::packageReceiverRegistry; - std::unordered_map SHEventManager::dataEventMap; SHEventHandle SHEventManager::handleCounter{ 0 }; @@ -23,7 +22,7 @@ namespace SHADE * \brief Receives event from the listeners. ****************************************************************************/ - void SHEventManager::CatchEvent(SHEvent event) + void SHEventManager::CatchEvent(SHEventPtr event) { // Do something with the event @@ -46,21 +45,16 @@ namespace SHADE } template - T* SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType) + void SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType) { - SHEventDataPtr ptr = new std::byte[sizeof(data)]; - - std::memcpy(ptr, &data, sizeof(data)); + std::shared_ptr data = std::make_shared(data); CatchEvent( - { - eventType, - ptr, - handleCounter++ - } + reinterpret_cast + ( + std::make_shared>(eventType, handleCounter++, data) + ) ); - - return reinterpret_cast(ptr); } /**************************************************************************** @@ -90,9 +84,9 @@ namespace SHADE * \brief Broadcast event to all receivers that are subscribed to this * listener. ****************************************************************************/ - void SHEventManager::Broadcast(SHEvent const& event) + void SHEventManager::Broadcast(SHEventPtr event) { - ResponseVec& receivers{ packageReceiverRegistry[event.type] }; + ResponseVec& receivers{ packageReceiverRegistry[event->type] }; for (auto& receiver : receivers) { receiver->Receive(event); diff --git a/SHADE_Engine/src/Events/SHEventManager.h b/SHADE_Engine/src/Events/SHEventManager.h index f2f19fef..b9ea370c 100644 --- a/SHADE_Engine/src/Events/SHEventManager.h +++ b/SHADE_Engine/src/Events/SHEventManager.h @@ -24,11 +24,16 @@ 3. When ready to send the event, call SHEventManager::BroadcastEvent(exampleClass, EVENT_IDENTIFIER); + NOTE: If your custom struct to contain data requires a deep copy, please + overload the assignment operator accordingly. It is fine to send + a single object of a basic type such as int/float. + Headers required: SHEventManager.h On Receiver side: 1. Create a function with the signature: - SHEventHandle FunctionName(SHEvent); + SHEventHandle FunctionName(SHEventPtr); + 2. In the init function of the class, copy the below in and replace the necessary: @@ -42,8 +47,12 @@ 3. Note: The EventIdentifier should match all that is defined in SHEventDefines.h so check there. When the receiver catches the event, it - needs to know the struct that the broadcaster is using to cast the void* - properly. + needs to know the struct that the broadcaster is using to cast the event + ptr as such: + + reinterpret_cast>>(event) + + 4. Inside the new ptr should be a shared pointer of const CustomClass type. Headers required: SHEventManager.h, SHEventReceiver.h @@ -52,13 +61,13 @@ namespace SHADE { - using ResponseFunction = std::function; + //using ResponseFunction = std::function; using ReceiverPtr = std::shared_ptr; using ResponseVec = std::vector; - using StaticResponseVec = std::vector; using EventManagerListener = std::function; + class SHEventManager { public: @@ -69,7 +78,7 @@ namespace SHADE * \brief Receives event from the listeners. ****************************************************************************/ - static void CatchEvent(SHEvent); + static void CatchEvent(SHEventPtr); /**************************************************************************** * \param ResponseFunction - function pointer from receiver to be passed @@ -83,13 +92,12 @@ namespace SHADE static void SubscribeTo(SHEventIdentifier, ReceiverPtr); template - static T* BroadcastEvent(T data, SHEventIdentifier eventType); + static void BroadcastEvent(T data, SHEventIdentifier eventType); private: // Registry for broadcasters and subscribers static std::unordered_map packageReceiverRegistry; - static std::unordered_map dataEventMap; static SHEventHandle handleCounter; @@ -100,7 +108,7 @@ namespace SHADE * \brief Broadcast event to all receivers that are subscribed to this * listener. ****************************************************************************/ - static void Broadcast(SHEvent const&); + static void Broadcast(SHEventPtr event); /**************************************************************************** * \param ReceiverPtr - Pointer to receiver diff --git a/SHADE_Engine/src/Events/SHEventReceiver.h b/SHADE_Engine/src/Events/SHEventReceiver.h index f968e579..e6e5e757 100644 --- a/SHADE_Engine/src/Events/SHEventReceiver.h +++ b/SHADE_Engine/src/Events/SHEventReceiver.h @@ -8,7 +8,7 @@ namespace SHADE { private: public: - virtual void Receive(SHEvent) = 0; + virtual void Receive(SHEventPtr) = 0; }; template @@ -16,16 +16,16 @@ namespace SHADE { private: T* object; - SHEventHandle(T::*callback)(SHEvent); + SHEventHandle(T::*callback)(SHEventPtr); public: - SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventDataPtr)) + SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventPtr)) :SHEventReceiver(), object{ obj }, callback{ cb } { } - void Receive(SHEvent evt) override + void Receive(SHEventPtr evt) override { (object->*callback)(evt); }