IRSOL
C++ code implementing socket server for interacting with Baumer camera.
message_handler.hpp
Go to the documentation of this file.
1
19#pragma once
20
21#include "irsol/macros.hpp"
22#include "irsol/protocol.hpp"
23#include "irsol/traits.hpp"
24#include "irsol/types.hpp"
25
26#include <string>
27#include <unordered_map>
28#include <utility>
29
30namespace irsol {
31namespace server {
32
33namespace handlers {
34
53{
54 using handling_function_response_t = std::vector<protocol::OutMessage>;
55 using handler_identifier_t = std::string;
56
57 template<typename T>
60
64
65 template<typename T>
66 using message_handler_map_t = std::unordered_map<handler_identifier_t, T>;
67
71
73 variant<assignment_handler_function_t, inquiry_handler_function_t, command_handler_function_t>;
74
75public:
90
102 template<
103 typename T,
104 std::enable_if_t<irsol::traits::is_type_in_variant<T, irsol::protocol::InMessage>::value, int> =
105 0>
106 bool registerHandler(const std::string& identifier, handler_function_t<T> handler)
107 {
108 // Make sure there's no duplicate handlers for the same message kind and identifier
109 if(auto existingHandler = findHandler<T>(identifier); existingHandler) {
110 if constexpr(std::is_same_v<T, protocol::Assignment>) {
112 "Duplicate handler registered for identifier '{}' and Assignment type", identifier);
113 } else if constexpr(std::is_same_v<T, protocol::Inquiry>) {
115 "Duplicate handler registered for identifier '{}' and Inquiry type", identifier);
116 } else if constexpr(std::is_same_v<T, protocol::Command>) {
118 "Duplicate handler registered for identifier '{}' and Command type", identifier);
119 } else {
120 IRSOL_MISSING_TEMPLATE_SPECIALIZATION(T, "registerHandler()");
121 }
122
123 return false;
124 }
125
126 if constexpr(std::is_same_v<T, protocol::Assignment>) {
127 IRSOL_LOG_INFO("Registering handler for 'Assignment(\"{}\")'", identifier);
129 } else if constexpr(std::is_same_v<T, protocol::Inquiry>) {
130 IRSOL_LOG_INFO("Registering handler for 'Inquiry(\"{}\")'", identifier);
131 m_inquiryMessageHandlers[identifier] = handler;
132 } else if constexpr(std::is_same_v<T, protocol::Command>) {
133 IRSOL_LOG_INFO("Registering handler for 'Command(\"{}\")'", identifier);
134 m_commandMessageHandlers[identifier] = handler;
135 } else {
136 IRSOL_MISSING_TEMPLATE_SPECIALIZATION(T, "registerHandler()");
137 }
138 return true;
139 }
140
141private:
147 std::optional<any_handler_function_t> findHandlerForMessage(const protocol::InMessage& msg) const;
148
156 template<
157 typename T,
158 std::enable_if_t<irsol::traits::is_type_in_variant<T, irsol::protocol::InMessage>::value, int> =
159 0>
160 std::optional<handler_function_t<T>> findHandler(const handler_identifier_t& identifier) const
161 {
162 if constexpr(std::is_same_v<T, protocol::Assignment>) {
163 auto it = m_assignmentMessageHandlers.find(identifier);
164 return it == m_assignmentMessageHandlers.end() ? std::nullopt
165 : std::make_optional(it->second);
166 } else if constexpr(std::is_same_v<T, protocol::Inquiry>) {
167 auto it = m_inquiryMessageHandlers.find(identifier);
168 return it == m_inquiryMessageHandlers.end() ? std::nullopt : std::make_optional(it->second);
169 } else if constexpr(std::is_same_v<T, protocol::Command>) {
170 auto it = m_commandMessageHandlers.find(identifier);
171 return it == m_commandMessageHandlers.end() ? std::nullopt : std::make_optional(it->second);
172 } else {
174 }
175 }
176
179
182
185};
186
187} // namespace handlers
188} // namespace server
189} // namespace irsol
Binds incoming protocol messages to the appropriate per-client logic.
std::function< handling_function_response_t(const irsol::types::client_id_t &, T &&)> handler_function_t
handler_function_t< protocol::Assignment && > assignment_handler_function_t
handler_function_t< protocol::Inquiry && > inquiry_handler_function_t
handler_function_t< protocol::Command && > command_handler_function_t
handling_function_response_t handle(const irsol::types::client_id_t &clientId, protocol::InMessage &&message) const
Dispatches an incoming message to the correct user-defined handler.
assignment_message_handler_map_t m_assignmentMessageHandlers
Registered handlers for Assignment messages, keyed by identifier.
std::optional< handler_function_t< T > > findHandler(const handler_identifier_t &identifier) const
Locates a handler of a specific message type and identifier.
bool registerHandler(const std::string &identifier, handler_function_t< T > handler)
Registers a user-defined handler for a specific message type and identifier.
std::optional< any_handler_function_t > findHandlerForMessage(const protocol::InMessage &msg) const
Locates a registered handler (of any message type) for a given message.
inquiry_message_handler_map_t m_inquiryMessageHandlers
Registered handlers for Inquiry messages, keyed by identifier.
command_message_handler_map_t m_commandMessageHandlers
Registered handlers for Command messages, keyed by identifier.
std::variant< assignment_handler_function_t, inquiry_handler_function_t, command_handler_function_t > any_handler_function_t
message_handler_map_t< inquiry_handler_function_t > inquiry_message_handler_map_t
message_handler_map_t< command_handler_function_t > command_message_handler_map_t
message_handler_map_t< assignment_handler_function_t > assignment_message_handler_map_t
std::unordered_map< handler_identifier_t, T > message_handler_map_t
std::vector< protocol::OutMessage > handling_function_response_t
#define IRSOL_LOG_INFO(...)
Logs an info-level message using the default logger.
Definition logging.hpp:92
#define IRSOL_LOG_ERROR(...)
Logs an error-level message using the default logger.
Definition logging.hpp:94
std::variant< Assignment, Inquiry, Command > InMessage
Variant type representing any incoming message.
Definition variants.hpp:86
Common portability and diagnostic macros for the irsol library.
#define IRSOL_MISSING_TEMPLATE_SPECIALIZATION(T, funcNameLiteral)
Emits a compile-time error when no template specialization is available.
Definition macros.hpp:173
constexpr auto makeHandler(std::shared_ptr< Context > ctx, Args &&... args)
Constructs a handler instance of the given type.
Definition factory.hpp:28
std::string client_id_t
Represents a unique client identifier. Typically used to identify connected clients by string IDs.
Definition types.hpp:55
auto msg
Template metaprogramming traits for type introspection in the irsol library.
Core type definitions for networking, time handling, and protocol values used throughout the irsol li...