From a194774925650d857e059a58e0446649c7fbc415 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Tue, 25 Feb 2025 20:29:59 +0100 Subject: [PATCH] add MessageDispatcher --- include/sp/default/DefaultPacketDispatcher.h | 15 ++++++ include/sp/protocol/MessageDispatcher.h | 54 +++++++++++++++++++ .../message/MessageDispatcherImpl.inl | 34 ++++++++++++ test/test_packets.cpp | 13 +++-- 4 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 include/sp/default/DefaultPacketDispatcher.h create mode 100644 include/sp/protocol/MessageDispatcher.h create mode 100644 include/sp/protocol/message/MessageDispatcherImpl.inl diff --git a/include/sp/default/DefaultPacketDispatcher.h b/include/sp/default/DefaultPacketDispatcher.h new file mode 100644 index 0000000..aeb7fd5 --- /dev/null +++ b/include/sp/default/DefaultPacketDispatcher.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include +#include + +namespace sp { + +using PacketDispatcher = MessageDispatcher< + PacketMessage::ParsedOptions::MsgIdType, + PacketMessage, + PacketMessage::ParsedOptions::HandlerType::HandlerT + >; + +} // namespace sp diff --git a/include/sp/protocol/MessageDispatcher.h b/include/sp/protocol/MessageDispatcher.h new file mode 100644 index 0000000..eb346e6 --- /dev/null +++ b/include/sp/protocol/MessageDispatcher.h @@ -0,0 +1,54 @@ +#pragma once + +/** + * \file MessageDispatcher.h + * \brief File containing the sp::MessageDispatcher class + */ + +#include + +namespace sp { + +/** + * \class MessageDispatcher + * \brief Class used to dispatch messages + */ +template +class MessageDispatcher { + private: + std::map>> m_Handlers; + + public: + /** + * \brief Constructor + */ + MessageDispatcher() {} + + /** + * \brief Dispatch a packet + * \param packet The packet to dispatch + */ + void Dispatch(const MessageBase& a_Message); + + /** + * \brief Register a packet handler + * \param type The packet type + * \param handler The packet handler + */ + void RegisterHandler(MessageIdType a_MessageType, const std::shared_ptr& a_Handler); + /** + * \brief Unregister a packet handler + * \param type The packet type + * \param handler The packet handler + */ + void UnregisterHandler(MessageIdType a_MessageType, const std::shared_ptr& a_Handler); + /** + * \brief Unregister a packet handler + * \param handler The packet handler + */ + void UnregisterHandler(const std::shared_ptr& a_Handler); +}; + +#include + +} // namespace blitz diff --git a/include/sp/protocol/message/MessageDispatcherImpl.inl b/include/sp/protocol/message/MessageDispatcherImpl.inl new file mode 100644 index 0000000..3531452 --- /dev/null +++ b/include/sp/protocol/message/MessageDispatcherImpl.inl @@ -0,0 +1,34 @@ +#pragma once + +template +void MessageDispatcher::RegisterHandler(MessageIdType a_MessageType, const std::shared_ptr& a_Handler) { + auto found = std::find(m_Handlers[a_MessageType].begin(), m_Handlers[a_MessageType].end(), a_Handler); + if (found == m_Handlers[a_MessageType].end()) + m_Handlers[a_MessageType].push_back(a_Handler); +} + +template +void MessageDispatcher::UnregisterHandler(MessageIdType a_MessageType, const std::shared_ptr& a_Handler) { + auto found = std::find(m_Handlers[a_MessageType].begin(), m_Handlers[a_MessageType].end(), a_Handler); + if (found != m_Handlers[a_MessageType].end()) + m_Handlers[a_MessageType].erase(found); +} + +template +void MessageDispatcher::UnregisterHandler(const std::shared_ptr& a_Handler) { + for (auto& pair : m_Handlers) { + if (pair.second.empty()) + continue; + + MessageIdType type = pair.first; + + m_Handlers[type].erase(std::remove(m_Handlers[type].begin(), m_Handlers[type].end(), a_Handler), m_Handlers[type].end()); + } +} + +template +void MessageDispatcher::Dispatch(const MessageBase& a_Message) { + MessageIdType type = a_Message.GetId(); + for (auto& handler : m_Handlers[type]) + a_Message.Dispatch(*handler); +} diff --git a/test/test_packets.cpp b/test/test_packets.cpp index e07fe73..3af7410 100644 --- a/test/test_packets.cpp +++ b/test/test_packets.cpp @@ -4,6 +4,7 @@ #include #include +#include class KeepAliveHandler : public sp::PacketHandler { void Handle(const KeepAlivePacket& packet) { @@ -24,8 +25,8 @@ int main() { sp::PacketMessage* msg = upgradeTower.get(); - KeepAliveHandler handler; - msg->Dispatch(handler); + auto handler = std::make_shared(); + msg->Dispatch(*handler); sp::DataBuffer buffer; msg->Write(buffer); @@ -45,7 +46,13 @@ int main() { return 1; } std::cout << (unsigned)packet->GetId() << std::endl; - packet->Dispatch(handler); + packet->Dispatch(*handler); + + sp::PacketDispatcher dispatcher; + dispatcher.RegisterHandler(PacketId::KeepAlive, handler); + dispatcher.Dispatch(*packet); + dispatcher.UnregisterHandler(PacketId::KeepAlive, handler); + dispatcher.UnregisterHandler(handler); return 0; } \ No newline at end of file