admin管理员组文章数量:1335724
c++11
消息总线
对象间只通过消息来联系,不通过直接的依赖或者关联。消息总线将复杂的关系简化,降低复杂度。
消息总线关键技术
1)通用的消息定义
让所有额对象都通过消息来联系,定义一种通用的消息格式
2)消息的注册
让所有对象都可以注册感兴趣的消息
3)消息分发
通过消息总线分发消息,让所有的接受者都能接收到并处理消息
通用消息的定义
消息的构成=消息的主题+泛型函数
消息主题:用于对消息接受者进行分组,只有对主题感兴趣的接受者,才可以收到消息
泛型函数:用于消息的接收者,所有具备该函数的对象都可以接收消息,std::function<R(Args...)>
消息注册
告诉总线,该对象对某种消息感兴趣,希望接收到某种主题和类型的消息。总线内部维护了一个消息列表,需要发送消息时,遍历这个列表,查找是否有合适的消息和消息接收者,找到合适的接收者后再广播消息。
1.lambda表达式转换为std::function
2.保存注册的消息
消息分发
主题对象希望接收者对象收到消息时,会通过消息总线发送消息,消息的本质是std::function,在发送消息前先创建消息,创建后再发送,消息总线会查找内部的容器,看看那些对象对这个消息感兴趣,只有注册了这个消息的对象才能收到消息。
消息总线的设计思想
function_traits:
#pragma once
#include<functional>
#include<tuple>
template<typename T>
struct function_traits;
template<typename Ret,typename... Args>
struct function_traits<Ret(Args...)>
{
public:
enum {arity=sizeof...(Args) };
typedef Ret function_type(Args...);
typedef Ret return_type;
using stl_function_type = std::function<function_type>;
typedef Ret(*pointer)(Args...);
template<size_t I>
struct args {
static_assert(I < arity, "index is out of range");
using type = typename std::tuple_element < I, std::tuple<Args...>>::type;
};
};
template<typename Ret, typename... Args>
struct function_traits<Ret(*)(Args...)>:function_traits<Ret(Args...)>
{
};
template<typename Ret, typename... Args>
struct function_traits<std::function<Ret(Args...)>> :function_traits<Ret(Args...)>
{
};
#define FUNCTION_TRAITS(...)\
template<typename ReturnType, typename ClassType, typename ... Args>\
struct function_traits<ReturnType(ClassType::*)(Args...)>:function_traits<ReturnType(Args...)>{ };\
FUNCTION_TRAITS()
/*
FUNCTION_TRAITS(const)
FUNCTION_TRAITS(volatile)
FUNCTION_TRAITS(const volatile)*/
/*
template<typename Callable>
struct function_traits :function_traits<decltype(&(Callable::(operator())))> {};*/
/*
template<typename Function>
typename function_traits<Function>::stl_function_type to_function(const Function & lambda) {
return static_cast<typename function_traits<Function>::stl_function_type>(lambda);
}*/
template<typename Function>
typename function_traits<Function>::stl_function_type to_function(Function && la) {
return static_cast<typename function_traits<Function>::stl_function_type>(std::forward<Function>(la));
}
/*
template<typename Function>
typename function_traits<Function>::pointer to_function(const Function & lambda) {
return static_cast<typename function_traits<Function>::pointer>((lambda));
}*/
messagebus:
#pragma once
#include"function_traits.h"
#include"any.h"
#include<string>
#include<map>
class MessageBus {
public:
template<typename F>
void Attach(F&& f, const std::string& strTopic = "") {
auto func = to_function(std::forward<F>(f));
Add(strTopic, std::move(func));
}
template<typename R>
void sendReq(const std::string& strTopic = "") {
using function_type = std::function<R()>;
std::string strMsgType = strTopic + typeid(function_type).name();
auto Range = m_map.equal_range(strMsgType);
for (Iterator it = Range.first; it!= Range.second; it++) {
auto f = it->second.AnyCast<function_type>();
f();
}
}
template<typename R,typename ... Args>
void sendReq(Args ... args,const std::string& strTopic = "") {
using function_type = std::function<R(Args...)>;
std::string strMsgType = strTopic + typeid(function_type).name();
auto Range = m_map.equal_range(strMsgType);
for (Iterator it = Range.first; it !=Range.second; it++) {
auto f = it->second.AnyCast<function_type>();
f(std::forward<Args>(args)...);
}
}
template<typename R, typename ... Args>
void Remove(Args ... args, const std::string& strTopic = "") {
using function_type = std::function<R(args)>;
std::string strMsgType = strTopic + typeid(function_type).name();
auto Range = m_map.equal_range(strMsgType);
m_map.erase(Range.first,Range.second);
}
private:
template<typename F>
void Add(const std::string& strTopic, F&& f) {
const std::string strMsgType = strTopic + typeid(f).name();
std::pair<std::string, Any> p(strMsgType, std::forward<F>(f));
m_map.insert(std::move(p));
}
std::multimap<std::string, Any> m_map;
typedef std::multimap<std::string, Any>::iterator Iterator;
};
本文标签: C11
版权声明:本文标题:c++11 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/biancheng/1704035417a616882.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论