Merge pull request #29 from SHADE-DP/SP3-18-Events
SP3-18 Event/Messaging System
This commit is contained in:
commit
02b17095d0
|
@ -16,7 +16,17 @@ namespace SHADE
|
||||||
struct SHEvent
|
struct SHEvent
|
||||||
{
|
{
|
||||||
SHEventIdentifier type;
|
SHEventIdentifier type;
|
||||||
SHEventDataPtr dataPtr;
|
|
||||||
SHEventHandle handle;
|
SHEventHandle handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct SHEventSpec : SHEvent
|
||||||
|
{
|
||||||
|
SHEventSpec(SHEventIdentifier t, SHEventHandle e, T* dp)
|
||||||
|
:SHEvent{ t, e }, data{ dp } {}
|
||||||
|
|
||||||
|
std::shared_ptr<const T> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
using SHEventPtr = std::shared_ptr<SHEvent>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
typedef uint32_t SHEventIdentifier;
|
typedef uint32_t SHEventIdentifier;
|
||||||
typedef uint32_t SHEventHandle;
|
typedef uint32_t SHEventHandle;
|
||||||
typedef void* SHEventDataPtr;
|
|
||||||
|
|
||||||
//Add your event identifiers here:
|
//Add your event identifiers here:
|
||||||
constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0};
|
constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0};
|
|
@ -13,7 +13,6 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
std::unordered_map<SHEventIdentifier, ResponseVec> SHEventManager::packageReceiverRegistry;
|
std::unordered_map<SHEventIdentifier, ResponseVec> SHEventManager::packageReceiverRegistry;
|
||||||
std::unordered_map<SHEventHandle, SHEventDataPtr> SHEventManager::dataEventMap;
|
|
||||||
|
|
||||||
SHEventHandle SHEventManager::handleCounter{ 0 };
|
SHEventHandle SHEventManager::handleCounter{ 0 };
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ namespace SHADE
|
||||||
|
|
||||||
* \brief Receives event from the listeners.
|
* \brief Receives event from the listeners.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void SHEventManager::CatchEvent(SHEvent event)
|
void SHEventManager::CatchEvent(SHEventPtr event)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Do something with the event
|
// Do something with the event
|
||||||
|
@ -46,21 +45,16 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType)
|
void SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType)
|
||||||
{
|
{
|
||||||
SHEventDataPtr ptr = new std::byte[sizeof(data)];
|
std::shared_ptr<const T> data = std::make_shared<T>(data);
|
||||||
|
|
||||||
std::memcpy(ptr, &data, sizeof(data));
|
|
||||||
|
|
||||||
CatchEvent(
|
CatchEvent(
|
||||||
{
|
reinterpret_cast<SHEventPtr>
|
||||||
eventType,
|
(
|
||||||
ptr,
|
std::make_shared<SHEventSpec<T>>(eventType, handleCounter++, data)
|
||||||
handleCounter++
|
)
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return reinterpret_cast<T*>(ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -90,9 +84,9 @@ namespace SHADE
|
||||||
* \brief Broadcast event to all receivers that are subscribed to this
|
* \brief Broadcast event to all receivers that are subscribed to this
|
||||||
* listener.
|
* 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)
|
for (auto& receiver : receivers)
|
||||||
{
|
{
|
||||||
receiver->Receive(event);
|
receiver->Receive(event);
|
||||||
|
|
|
@ -24,11 +24,16 @@
|
||||||
3. When ready to send the event, call
|
3. When ready to send the event, call
|
||||||
SHEventManager::BroadcastEvent<ExampleClass>(exampleClass, EVENT_IDENTIFIER);
|
SHEventManager::BroadcastEvent<ExampleClass>(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
|
Headers required: SHEventManager.h
|
||||||
|
|
||||||
On Receiver side:
|
On Receiver side:
|
||||||
1. Create a function with the signature:
|
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
|
2. In the init function of the class, copy the below in and replace the
|
||||||
necessary:
|
necessary:
|
||||||
|
|
||||||
|
@ -42,8 +47,12 @@
|
||||||
|
|
||||||
3. Note: The EventIdentifier should match all that is defined in
|
3. Note: The EventIdentifier should match all that is defined in
|
||||||
SHEventDefines.h so check there. When the receiver catches the event, it
|
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*
|
needs to know the struct that the broadcaster is using to cast the event
|
||||||
properly.
|
ptr as such:
|
||||||
|
|
||||||
|
reinterpret_cast<std::shared_ptr<SHEventSpec<CustomClass>>>(event)
|
||||||
|
|
||||||
|
4. Inside the new ptr should be a shared pointer of const CustomClass type.
|
||||||
|
|
||||||
Headers required: SHEventManager.h, SHEventReceiver.h
|
Headers required: SHEventManager.h, SHEventReceiver.h
|
||||||
|
|
||||||
|
@ -52,13 +61,13 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
using ResponseFunction = std::function<SHEventHandle(SHEvent)>;
|
//using ResponseFunction = std::function<SHEventHandle(SHEventPtr)>;
|
||||||
using ReceiverPtr = std::shared_ptr<SHEventReceiver>;
|
using ReceiverPtr = std::shared_ptr<SHEventReceiver>;
|
||||||
using ResponseVec = std::vector<ReceiverPtr>;
|
using ResponseVec = std::vector<ReceiverPtr>;
|
||||||
using StaticResponseVec = std::vector<ResponseFunction>;
|
|
||||||
|
|
||||||
using EventManagerListener = std::function<void(SHEvent)>;
|
using EventManagerListener = std::function<void(SHEvent)>;
|
||||||
|
|
||||||
|
|
||||||
class SHEventManager
|
class SHEventManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -69,7 +78,7 @@ namespace SHADE
|
||||||
|
|
||||||
* \brief Receives event from the listeners.
|
* \brief Receives event from the listeners.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void CatchEvent(SHEvent);
|
static void CatchEvent(SHEventPtr);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \param ResponseFunction - function pointer from receiver to be passed
|
* \param ResponseFunction - function pointer from receiver to be passed
|
||||||
|
@ -83,13 +92,12 @@ namespace SHADE
|
||||||
static void SubscribeTo(SHEventIdentifier, ReceiverPtr);
|
static void SubscribeTo(SHEventIdentifier, ReceiverPtr);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static T* BroadcastEvent(T data, SHEventIdentifier eventType);
|
static void BroadcastEvent(T data, SHEventIdentifier eventType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Registry for broadcasters and subscribers
|
// Registry for broadcasters and subscribers
|
||||||
static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
|
static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
|
||||||
static std::unordered_map<SHEventHandle, SHEventDataPtr> dataEventMap;
|
|
||||||
|
|
||||||
static SHEventHandle handleCounter;
|
static SHEventHandle handleCounter;
|
||||||
|
|
||||||
|
@ -100,7 +108,7 @@ namespace SHADE
|
||||||
* \brief Broadcast event to all receivers that are subscribed to this
|
* \brief Broadcast event to all receivers that are subscribed to this
|
||||||
* listener.
|
* listener.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void Broadcast(SHEvent const&);
|
static void Broadcast(SHEventPtr event);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \param ReceiverPtr - Pointer to receiver
|
* \param ReceiverPtr - Pointer to receiver
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
public:
|
public:
|
||||||
virtual void Receive(SHEvent) = 0;
|
virtual void Receive(SHEventPtr) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -16,16 +16,16 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
T* object;
|
T* object;
|
||||||
SHEventHandle(T::*callback)(SHEvent);
|
SHEventHandle(T::*callback)(SHEventPtr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventDataPtr))
|
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventPtr))
|
||||||
:SHEventReceiver(), object{ obj }, callback{ cb }
|
:SHEventReceiver(), object{ obj }, callback{ cb }
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Receive(SHEvent evt) override
|
void Receive(SHEventPtr evt) override
|
||||||
{
|
{
|
||||||
(object->*callback)(evt);
|
(object->*callback)(evt);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue