204 lines
5.7 KiB
C++
204 lines
5.7 KiB
C++
#pragma once
|
|
|
|
#include "componentbasic_global.h"
|
|
#include <simsbasic.h>
|
|
#include <QHash>
|
|
|
|
/// <summary>
|
|
/// 消息响应处理单元基类
|
|
/// </summary>
|
|
/// <typeparam name="MsgA">输入类型</typeparam>
|
|
/// <typeparam name="MsgB">输出类型</typeparam>
|
|
template<typename MsgA, typename MsgB> class WsRespond {
|
|
public:
|
|
using SelfType = WsRespond<MsgA, MsgB>;
|
|
|
|
virtual ~WsRespond() = default;
|
|
/// <summary>
|
|
/// Respond的类型签名
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
static WsRespondSignatureType signature()
|
|
{
|
|
return std::make_pair<QString, QString>(MsgA().topicString(), MsgB().topicString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 子类中实际处理函数
|
|
/// </summary>
|
|
/// <param name="in"></param>
|
|
/// <param name="out"></param>
|
|
virtual void execute(std::shared_ptr<const MsgA> in, QList<std::shared_ptr<MsgB>>& out) = 0;
|
|
/// <summary>
|
|
/// WsRespond构造函数
|
|
/// </summary>
|
|
/// <param name="map">注册函数</param>
|
|
explicit WsRespond(QHash<WsRespondSignatureType, WsRespondEntry>& map) {
|
|
WsRespondEntry ins = [=](std::shared_ptr<const WsMessage> in, QList<std::shared_ptr<WsMessage>>& out) {
|
|
QList<std::shared_ptr<MsgB>> o_ptrs;
|
|
this->execute(std::static_pointer_cast<const MsgA>(in), o_ptrs);
|
|
std::transform(o_ptrs.begin(), o_ptrs.end(), std::back_inserter(out),
|
|
[](std::shared_ptr<MsgB> v) {
|
|
return std::static_pointer_cast<WsMessage>(v);
|
|
});
|
|
};
|
|
map[SelfType::signature()] = ins;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
template <typename... RespSigs> struct _RespondRoute;
|
|
/// <summary>
|
|
/// 响应路由数据基类
|
|
/// </summary>
|
|
template <> struct COMPONENTBASIC_EXPORT _RespondRoute<> {
|
|
QHash<WsRespondSignatureType, WsRespondEntry> _execute_map;
|
|
_RespondRoute() = default;
|
|
};
|
|
/// <summary>
|
|
/// 消息响应路由综合基类
|
|
/// </summary>
|
|
/// <typeparam name="RespSig">类型</typeparam>
|
|
/// <typeparam name="...RespSigs">其余类型列表</typeparam>
|
|
template <typename RespSig, typename... RespSigs>
|
|
struct _RespondRoute<RespSig, RespSigs...> : public _RespondRoute<RespSigs...>, public RespSig {
|
|
_RespondRoute() : _RespondRoute<RespSigs...>(), RespSig(_RespondRoute<>::_execute_map) {}
|
|
};
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 消息响应列表
|
|
/// </summary>
|
|
/// <typeparam name="...Resp"></typeparam>
|
|
template <typename... Resp>
|
|
struct RespondRoute : virtual public WsComponent, public _RespondRoute<Resp...> {
|
|
RespondRoute() : _RespondRoute<Resp...>() {}
|
|
|
|
// 通过 WsComponent 继承
|
|
virtual QList<WsRespondSignatureType> respondSignatures() const
|
|
{
|
|
return _RespondRoute<>::_execute_map.keys();
|
|
}
|
|
virtual QList<WsRespondEntry> getRespondWithSignature(const WsRespondSignatureType& t) const
|
|
{
|
|
QList<WsRespondEntry> list;
|
|
if (_RespondRoute<>::_execute_map.contains(t))
|
|
list << _RespondRoute<>::_execute_map[t];
|
|
return list;
|
|
}
|
|
virtual QList<WsRespondEntry> getRespondWithInType(const QString& msg_type) const
|
|
{
|
|
QList<WsRespondEntry> list;
|
|
for (auto key : _RespondRoute<>::_execute_map.keys()) {
|
|
if (key.first == msg_type)
|
|
list.append(_RespondRoute<>::_execute_map[key]);
|
|
}
|
|
return list;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ===========================================================
|
|
/// <summary>
|
|
/// Request发送接口
|
|
/// </summary>
|
|
/// <typeparam name="MsgA"></typeparam>
|
|
/// <typeparam name="MsgB"></typeparam>
|
|
template<typename MsgA, typename MsgB> class WsRequest {
|
|
public:
|
|
using SelfType = WsRequest<MsgA, MsgB>;
|
|
|
|
virtual ~WsRequest() = default;
|
|
/// <summary>
|
|
/// Request的类型签名
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
static WsRequestSignatureType signature()
|
|
{
|
|
return std::make_pair<QString, QString>(MsgA().topicString(), MsgB().topicString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 子类中实际处理函数
|
|
/// </summary>
|
|
/// <param name="in"></param>
|
|
/// <param name="out"></param>
|
|
static void request(std::weak_ptr<WsEntity> e, std::shared_ptr<const MsgA> in, QList<std::shared_ptr<MsgB>>& out) {
|
|
auto entries = e.lock()->getRespondWithSignature(SelfType::signature());
|
|
|
|
QList<std::shared_ptr<WsMessage>> o_list;
|
|
for (auto func_it : entries) {
|
|
func_it(in, o_list);
|
|
}
|
|
for (auto msg : o_list) {
|
|
auto conv = std::dynamic_pointer_cast<MsgB>(msg);
|
|
if (conv) out << conv;
|
|
}
|
|
}
|
|
|
|
static QList<std::shared_ptr<MsgB>> impl(std::weak_ptr<WsEntity> e, std::shared_ptr<const MsgA> in) {
|
|
QList<std::shared_ptr<MsgB>> out;
|
|
WsRequest<MsgA, MsgB>::request(e, in, out);
|
|
return out;
|
|
}
|
|
|
|
/// <summary>
|
|
/// WsRequest构造函数
|
|
/// </summary>
|
|
/// <param name="request_list">Request类型列表</param>
|
|
explicit WsRequest(QList<WsRequestSignatureType>& request_list) {
|
|
request_list << SelfType::signature();
|
|
}
|
|
};
|
|
|
|
|
|
|
|
template<typename... ReqsSigs> struct _RequestRoute;
|
|
/// <summary>
|
|
/// 请求发送数据基类
|
|
/// </summary>
|
|
template<> struct COMPONENTBASIC_EXPORT _RequestRoute<> {
|
|
QList<WsRequestSignatureType> _request_list;
|
|
_RequestRoute() = default;
|
|
|
|
QList<std::shared_ptr<WsMessage>> query(std::weak_ptr<WsEntity> e, std::shared_ptr<const WsMessage> in) {
|
|
auto binde = e.lock();
|
|
auto entries = binde->getRespondWithInType(in->topicString());
|
|
|
|
QList<std::shared_ptr<WsMessage>> out;
|
|
for (auto func_it : entries) {
|
|
func_it(in, out);
|
|
}
|
|
return out;
|
|
}
|
|
};
|
|
/// <summary>
|
|
/// 消息发送综合基类
|
|
/// </summary>
|
|
/// <typeparam name="ReqsSig"></typeparam>
|
|
/// <typeparam name="...ReqsSigs"></typeparam>
|
|
template<typename ReqsSig, typename... ReqsSigs>
|
|
struct _RequestRoute<ReqsSig, ReqsSigs...> : public _RequestRoute<ReqsSigs...>, public ReqsSig {
|
|
_RequestRoute() : _RequestRoute<ReqsSigs...>(), ReqsSig(_RequestRoute<>::_request_list) {}
|
|
};
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 消息发送注册基类
|
|
/// </summary>
|
|
/// <typeparam name="...Reqs"></typeparam>
|
|
template<typename... Reqs>
|
|
struct RequestRoute : virtual public WsComponent, public _RequestRoute<Reqs...> {
|
|
RequestRoute() : _RequestRoute<Reqs...>() {}
|
|
virtual QList<WsRequestSignatureType> requestSignatures() const {
|
|
return _RequestRoute<>::_request_list;
|
|
}
|
|
};
|
|
|