Kylin/Universal/MessageManager.h
2023-07-21 11:21:16 +08:00

93 lines
2.6 KiB
C++

#ifndef MESSAGEMANAGER_H
#define MESSAGEMANAGER_H
#include <functional>
#include <queue>
#include <string>
#include <string_view>
#include <thread>
#include <type_traits>
#include <unordered_map>
#ifdef ANDROID
#include <boost/any.hpp>
#else
#include <any>
#endif
class MessageManager {
#ifdef ANDROID
using ParamEntry = boost::any;
using BadEntryCast = boost::bad_any_cast;
#else
using ParamEntry = std::any;
using BadEntryCast = std::bad_any_cast;
#endif
using AsyncParam = std::pair<std::string, ParamEntry>;
using Executor = std::function<bool(const ParamEntry &)>;
public:
template <typename... Args>
class Message {
public:
explicit constexpr Message(const char *topic) : topic(topic) {
}
std::string_view topic;
};
MessageManager();
~MessageManager();
/**
* @brief std::bind() is not recommended,recommended to use lambda. if you must use std::bind(),do not use
* placeholders!
*
* @tparam Function
* @param topic
* @param f
*/
template <typename Function>
void registerTopic(const std::string_view &topic, Function &&f);
template <typename Function, typename... Args>
void registerTopic(const Message<Args...> &topic, Function &&f);
template <typename Function>
void removeTopic(const std::string_view &topic);
template <typename Function>
size_t topicCount(const std::string_view &topic);
template <typename... Args>
void sendMessage(const std::string_view &topic, Args &&...args);
template <typename Function, typename... Args>
void sendMessage(const std::string_view &topic, Args &&...args);
template <typename... TArgs, typename... Args>
void sendMessage(const Message<TArgs...> &topic, Args &&...args);
template <typename... Args>
void sendAsyncMessage(const std::string_view &topic, Args &&...args);
template <typename Function, typename... Args>
void sendAsyncMessage(const std::string_view &topic, Args &&...args);
template <typename... TArgs, typename... Args>
void sendAsyncMessage(const Message<TArgs...> &topic, Args &&...args);
protected:
MessageManager(const MessageManager &) = delete;
template <typename Function>
static Executor executorWrapper(Function &&f);
void callExecutor(const std::string &signature, std::any &&parameter);
void run();
private:
std::unordered_multimap<std::string, Executor> m_executors;
std::queue<AsyncParam> m_params;
std::thread m_thread;
bool m_exit{false};
};
#include "MessageManager.inl"
#endif // MESSAGEMANAGER_H