#ifndef _NOTIFICATION_HANDLER_H_ #define _NOTIFICATION_HANDLER_H_ #include #include #include #include #include #include "common/KBasicException.h" #include "common/KDetailedException.h" #include "messages/Frame.pb.h" #include "ITransportClient.h" #include "IRouterClient.h" namespace Kinova { namespace Api { struct AbstractCallbackFunction { AbstractCallbackFunction() = default; virtual ~AbstractCallbackFunction() = default; virtual Error call(Frame& msgFrameNotif) = 0; }; template struct CallbackFunction : public AbstractCallbackFunction { static constexpr bool isOk = std::is_base_of<::google::protobuf::Message, DataType>::value; static_assert(isOk, "DataType must inherit from ::google::protobuf::Message"); std::function< void (DataType) > m_callbackFct; CallbackFunction(std::function< void(DataType) > callback) : AbstractCallbackFunction() { m_callbackFct = callback; } virtual ~CallbackFunction() override {} virtual Error call(Frame& msgFrameNotif) override { Error error; error.set_error_code(ErrorCodes::ERROR_NONE); DataType decodedMsgNotif; if( !decodedMsgNotif.ParseFromString(msgFrameNotif.payload()) ) { HeaderInfo headerInfo( msgFrameNotif.header() ); error.set_error_code(ERROR_PROTOCOL_CLIENT); error.set_error_sub_code(PAYLOAD_DECODING_ERR); error.set_error_sub_string(string("The data payload could not be deserialized : notification for serviceId=") + to_string(headerInfo.m_serviceInfo.serviceId) + " \n"); } else { // todo ??? thread(m_callbackFct, move(decodedMsgNotif)).detach(); thread(m_callbackFct, decodedMsgNotif).detach(); } return error; } }; // todoErr add the validation information beside the callback typedef std::unordered_map< uint32_t, std::unique_ptr> CallbackMap; class NotificationHandler { CallbackMap m_callbackMap; std::mutex m_mutex; public: NotificationHandler(); ~NotificationHandler(); template void addCallback( uint32_t idKey, std::function callback ) { std::lock_guard w_scoped(m_mutex); std::unique_ptr fct{new CallbackFunction(callback)}; m_callbackMap[idKey] = std::move(fct); } void clearIdKeyCallbacks( uint32_t idKey ); void clearAll(); Error call(Frame& msgFrameNotif); }; } } #endif // _NOTIFICATION_HANDLER_H_