SimsWorld/ComponentBasic/componentbasic.h

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;
}
};