Merge pull request #32 from SHADE-DP/SP3-18-Events

SP3-18 Event/Messaging System
This commit is contained in:
XiaoQiDigipen 2022-09-19 17:09:21 +08:00 committed by GitHub
commit de08955467
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 137 deletions

View File

@ -22,7 +22,7 @@
#include "../SHECSMacros.h"
#include "ECS_Base/Events/SHEntityCreationEvent.h"
#include "ECS_Base/Events/SHEntityDestroyedEvent.h"
#include "Events/SHEventManager.h"
#include "Events/SHEventManager.hpp"
#include "SH_API.h"
namespace SHADE

View File

@ -22,11 +22,11 @@ namespace SHADE
template<typename T>
struct SHEventSpec : SHEvent
{
SHEventSpec(SHEventIdentifier t, SHEventHandle e, T* dp)
SHEventSpec(SHEventIdentifier t, SHEventHandle e, std::shared_ptr<const T> dp)
:SHEvent{ t, e }, data{ dp } {}
std::shared_ptr<const T> data;
};
using SHEventPtr = std::shared_ptr<SHEvent>;
using SHEventPtr = std::shared_ptr<const SHEvent>;
}

View File

@ -1,101 +0,0 @@
/******************************************************************************
* \file SHEventManager.cpp
* \author Loh Xiao Qi
* \brief Function Implmentations for SHEventManager
*
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
* or disclosure of this file or its contents without the prior
* written consent of Digipen Institute of Technology is prohibited
******************************************************************************/
#include "SHpch.h"
#include "SHEventManager.h"
namespace SHADE
{
std::unordered_map<SHEventIdentifier, ResponseVec> SHEventManager::packageReceiverRegistry;
SHEventHandle SHEventManager::handleCounter{ 0 };
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Templated type for every type of event
* \brief Receives event from the listeners.
****************************************************************************/
void SHEventManager::CatchEvent(SHEventPtr event)
{
// Do something with the event
Broadcast(event);
}
/****************************************************************************
* \param ResponseFunction - function pointer from receiver to be passed
* into event manager to be called when events are broadcasted.
* \param SHEventIdentifier - package type that corresponding subscriber is
* subscribing to.
* \brief Links a function pointer from a subscriber to a particular
* package type
****************************************************************************/
void SHEventManager::SubscribeTo(SHEventIdentifier pkgType, ReceiverPtr receiver)
{
RegisterReceiverToType(pkgType, receiver);
}
template<typename T>
void SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType)
{
std::shared_ptr<const T> data = std::make_shared<T>(data);
CatchEvent(
reinterpret_cast<SHEventPtr>
(
std::make_shared<SHEventSpec<T>>(eventType, handleCounter++, data)
)
);
}
/****************************************************************************
* \param ReceiverPtr - Pointer to receiver
* \param ListenerConstPtr - Const pointer to listener that receiver is
* subscribing to.
* \brief Registers receiver as a subscriber to listener in the registry.
****************************************************************************/
void SHEventManager::RegisterReceiverToType(
SHEventIdentifier pkgType, ReceiverPtr receiver)
{
if (packageReceiverRegistry.contains(pkgType))
{
packageReceiverRegistry[pkgType].emplace_back(receiver);
}
else
{
packageReceiverRegistry.emplace(pkgType, std::vector{ receiver });
}
}
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Event data
* \brief Broadcast event to all receivers that are subscribed to this
* listener.
****************************************************************************/
void SHEventManager::Broadcast(SHEventPtr event)
{
ResponseVec& receivers{ packageReceiverRegistry[event->type] };
for (auto& receiver : receivers)
{
receiver->Receive(event);
}
//auto& funcs{ ackageReceiverRegistry[event.GetType()] };
//for (auto func : funcs)
//{
// func(event.GetData());
//}
}
}

View File

@ -1,5 +1,5 @@
/******************************************************************************
* \file SHEventManager.h
* \file SHEventManager.hpp
* \author Loh Xiao Qi
* \brief Class declaration for event manager.
*
@ -9,10 +9,9 @@
******************************************************************************/
#pragma once
#include "SHpch.h"
#include "SHEvent.h"
#include "SHEventReceiver.h"
#include <unordered_map>
#include <functional>
/******************************************************************************
INSTRUCTIONS FOR USE:
@ -28,7 +27,7 @@
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
Headers required: SHEventManager.hpp
On Receiver side:
1. Create a function with the signature:
@ -54,7 +53,7 @@
4. Inside the new ptr should be a shared pointer of const CustomClass type.
Headers required: SHEventManager.h, SHEventReceiver.h
Headers required: SHEventManager.hpp, SHEventReceiver.h
If you have any questions/suggestions for improvement lmk.
******************************************************************************/
@ -70,6 +69,48 @@ namespace SHADE
class SHEventManager
{
private:
// Registry for broadcasters and subscribers
inline static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
inline static SHEventHandle handleCounter {0};
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Event data
* \brief Broadcast event to all receivers that are subscribed to this
* listener.
****************************************************************************/
static void Broadcast(SHEventPtr event)
{
ResponseVec& receivers{ packageReceiverRegistry[event->type] };
for (auto& receiver : receivers)
{
receiver->Receive(event);
}
}
/****************************************************************************
* \param ReceiverPtr - Pointer to receiver
* \param ListenerConstPtr - Const pointer to listener that receiver is
* subscribing to.
* \brief Registers receiver as a subscriber to listener in the registry.
****************************************************************************/
static void RegisterReceiverToType(SHEventIdentifier pkgType, ReceiverPtr receiver)
{
if (packageReceiverRegistry.find(pkgType) == packageReceiverRegistry.end())
{
packageReceiverRegistry.emplace(pkgType, std::vector{ receiver });
}
else
{
packageReceiverRegistry[pkgType].emplace_back(receiver);
}
}
public:
/****************************************************************************
@ -78,7 +119,13 @@ namespace SHADE
* \brief Receives event from the listeners.
****************************************************************************/
static void CatchEvent(SHEventPtr);
static void CatchEvent(SHEventPtr event)
{
// Do something with the event
Broadcast(event);
}
/****************************************************************************
* \param ResponseFunction - function pointer from receiver to be passed
@ -89,36 +136,20 @@ namespace SHADE
* \brief Links a function pointer from a subscriber to a particular
* package type
****************************************************************************/
static void SubscribeTo(SHEventIdentifier, ReceiverPtr);
static void SubscribeTo(SHEventIdentifier pkgType, ReceiverPtr receiver)
{
RegisterReceiverToType(pkgType, receiver);
}
template<typename T>
static void BroadcastEvent(T data, SHEventIdentifier eventType);
private:
// Registry for broadcasters and subscribers
static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
static SHEventHandle handleCounter;
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Event data
* \brief Broadcast event to all receivers that are subscribed to this
* listener.
****************************************************************************/
static void Broadcast(SHEventPtr event);
/****************************************************************************
* \param ReceiverPtr - Pointer to receiver
* \param ListenerConstPtr - Const pointer to listener that receiver is
* subscribing to.
* \brief Registers receiver as a subscriber to listener in the registry.
****************************************************************************/
static void RegisterReceiverToType(SHEventIdentifier, ReceiverPtr);
static void BroadcastEvent(T data, SHEventIdentifier eventType)
{
std::shared_ptr<const T> ptr = std::make_shared<T>(data);
CatchEvent(
std::make_shared<SHEventSpec<T>>(eventType, handleCounter++, ptr)
);
}
};
}