2025-05-25 04:43:37 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "componentbasic_global.h"
|
|
|
|
|
#include <simsbasic.h>
|
2025-06-10 04:52:59 +00:00
|
|
|
|
#include <QHash>
|
2025-05-25 04:43:37 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-06-28 17:38:37 +00:00
|
|
|
|
/// <20><>Ϣ<EFBFBD><CFA2>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>
|
2025-05-25 04:43:37 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="MsgA"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
|
|
|
|
/// <typeparam name="MsgB"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
|
|
|
|
|
template<typename MsgA, typename MsgB> class WsRespond {
|
|
|
|
|
public:
|
|
|
|
|
using SelfType = WsRespond<MsgA, MsgB>;
|
|
|
|
|
|
|
|
|
|
virtual ~WsRespond() = default;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Respond<6E><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ<EFBFBD><C7A9>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static WsRespondSignatureType signature()
|
|
|
|
|
{
|
|
|
|
|
return std::make_pair<QString, QString>(MsgA().topicString(), MsgB().topicString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʴ<EFBFBD><CAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="in"></param>
|
2025-05-31 04:18:43 +00:00
|
|
|
|
/// <param name="out"></param>
|
2025-06-28 17:38:37 +00:00
|
|
|
|
virtual void execute(std::shared_ptr<const MsgA> in, QList<std::shared_ptr<MsgB>>& out) = 0;
|
2025-05-25 04:43:37 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// WsRespond<6E><64><EFBFBD>캯<EFBFBD><ECBAAF>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="map">ע<>ắ<EFBFBD><E1BAAF></param>
|
|
|
|
|
explicit WsRespond(QHash<WsRespondSignatureType, WsRespondEntry>& map) {
|
2025-06-28 17:38:37 +00:00
|
|
|
|
WsRespondEntry ins = [=](std::shared_ptr<const WsMessage> in, QList<std::shared_ptr<WsMessage>>& out) {
|
2025-06-08 04:12:15 +00:00
|
|
|
|
QList<std::shared_ptr<MsgB>> o_ptrs;
|
2025-06-28 17:38:37 +00:00
|
|
|
|
this->execute(std::static_pointer_cast<const MsgA>(in), o_ptrs);
|
2025-06-08 04:12:15 +00:00
|
|
|
|
std::transform(o_ptrs.begin(), o_ptrs.end(), std::back_inserter(out),
|
2025-06-28 17:38:37 +00:00
|
|
|
|
[](std::shared_ptr<MsgB> v) {
|
|
|
|
|
return std::static_pointer_cast<WsMessage>(v);
|
|
|
|
|
});
|
2025-05-25 04:43:37 +00:00
|
|
|
|
};
|
|
|
|
|
map[SelfType::signature()] = ins;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-06-28 17:38:37 +00:00
|
|
|
|
template <typename... RespSigs> struct _RespondRoute;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><>Ӧ·<D3A6><C2B7><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>
|
|
|
|
|
/// </summary>
|
|
|
|
|
template <> struct COMPONENTBASIC_EXPORT _RespondRoute<> {
|
|
|
|
|
QHash<WsRespondSignatureType, WsRespondEntry> _execute_map;
|
|
|
|
|
_RespondRoute() = default;
|
2025-05-25 04:43:37 +00:00
|
|
|
|
};
|
2025-06-28 17:38:37 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><>Ϣ<EFBFBD><CFA2>Ӧ·<D3A6><C2B7><EFBFBD>ۺϻ<DBBA><CFBB><EFBFBD>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="RespSig"><3E><><EFBFBD><EFBFBD></typeparam>
|
|
|
|
|
/// <typeparam name="...RespSigs"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD></typeparam>
|
|
|
|
|
template <typename RespSig, typename... RespSigs>
|
|
|
|
|
struct _RespondRoute<RespSig, RespSigs...> : public _RespondRoute<RespSigs...>, public RespSig {
|
|
|
|
|
_RespondRoute() : _RespondRoute<RespSigs...>(), RespSig(_RespondRoute<>::_execute_map) {}
|
2025-05-25 04:43:37 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2025-06-28 17:38:37 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><>Ϣ<EFBFBD><CFA2>Ӧ<EFBFBD>б<EFBFBD>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="...Resp"></typeparam>
|
|
|
|
|
template <typename... Resp>
|
2025-07-10 00:04:21 +00:00
|
|
|
|
struct RespondRoute : virtual public WsSpecializedSystem, public _RespondRoute<Resp...> {
|
2025-06-28 17:38:37 +00:00
|
|
|
|
RespondRoute() : _RespondRoute<Resp...>() {}
|
2025-05-25 04:43:37 +00:00
|
|
|
|
|
|
|
|
|
// ͨ<><CDA8> WsComponent <20>̳<EFBFBD>
|
2025-06-28 17:38:37 +00:00
|
|
|
|
virtual QList<WsRespondSignatureType> respondSignatures() const
|
2025-05-25 04:43:37 +00:00
|
|
|
|
{
|
2025-06-28 17:38:37 +00:00
|
|
|
|
return _RespondRoute<>::_execute_map.keys();
|
2025-05-25 04:43:37 +00:00
|
|
|
|
}
|
2025-06-28 17:38:37 +00:00
|
|
|
|
virtual QList<WsRespondEntry> getRespondWithSignature(const WsRespondSignatureType& t) const
|
2025-05-25 04:43:37 +00:00
|
|
|
|
{
|
2025-05-31 04:18:43 +00:00
|
|
|
|
QList<WsRespondEntry> list;
|
2025-06-28 17:38:37 +00:00
|
|
|
|
if (_RespondRoute<>::_execute_map.contains(t))
|
|
|
|
|
list << _RespondRoute<>::_execute_map[t];
|
2025-05-31 04:18:43 +00:00
|
|
|
|
return list;
|
2025-05-25 04:43:37 +00:00
|
|
|
|
}
|
2025-06-28 17:38:37 +00:00
|
|
|
|
virtual QList<WsRespondEntry> getRespondWithInType(const QString& msg_type) const
|
2025-05-25 04:43:37 +00:00
|
|
|
|
{
|
|
|
|
|
QList<WsRespondEntry> list;
|
2025-06-28 17:38:37 +00:00
|
|
|
|
for (auto key : _RespondRoute<>::_execute_map.keys()) {
|
2025-05-25 04:43:37 +00:00
|
|
|
|
if (key.first == msg_type)
|
2025-06-28 17:38:37 +00:00
|
|
|
|
list.append(_RespondRoute<>::_execute_map[key]);
|
2025-05-25 04:43:37 +00:00
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-06-28 17:38:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ===========================================================
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Request<73><74><EFBFBD>ͽӿ<CDBD>
|
|
|
|
|
/// </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<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ<EFBFBD><C7A9>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static WsRequestSignatureType signature()
|
|
|
|
|
{
|
|
|
|
|
return std::make_pair<QString, QString>(MsgA().topicString(), MsgB().topicString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʴ<EFBFBD><CAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
/// </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<73><74><EFBFBD>캯<EFBFBD><ECBAAF>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="request_list">Request<73><74><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD></param>
|
|
|
|
|
explicit WsRequest(QList<WsRequestSignatureType>& request_list) {
|
|
|
|
|
request_list << SelfType::signature();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename... ReqsSigs> struct _RequestRoute;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>
|
|
|
|
|
/// </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>
|
|
|
|
|
/// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>ۺϻ<DBBA><CFBB><EFBFBD>
|
|
|
|
|
/// </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>
|
|
|
|
|
/// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="...Reqs"></typeparam>
|
|
|
|
|
template<typename... Reqs>
|
2025-07-10 00:04:21 +00:00
|
|
|
|
struct RequestRoute : virtual public WsSpecializedSystem, public _RequestRoute<Reqs...> {
|
2025-06-28 17:38:37 +00:00
|
|
|
|
RequestRoute() : _RequestRoute<Reqs...>() {}
|
|
|
|
|
virtual QList<WsRequestSignatureType> requestSignatures() const {
|
|
|
|
|
return _RequestRoute<>::_request_list;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|