SimsWorld/ComponentBasic/componentbasic.h

92 lines
2.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<Immediate> map, 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<Immediate> map, std::shared_ptr<const WsMessage> in, QList<std::shared_ptr<WsMessage>>& out) {
QList<std::shared_ptr<MsgB>> o_ptrs;
this->execute(map, 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... ProcSigs>struct _ProcRoute_;
template <> struct COMPONENTBASIC_EXPORT _ProcRoute_<>
{
QHash<WsRespondSignatureType, WsRespondEntry> _execute_map;
_ProcRoute_() = default;
};
template <typename ProcSig, typename... ProcSigs>
struct _ProcRoute_<ProcSig, ProcSigs...> : public _ProcRoute_<ProcSigs...>, public ProcSig
{
_ProcRoute_() : _ProcRoute_<ProcSigs...>(), ProcSig(_ProcRoute_<>::_execute_map) {}
};
template <typename... Procs>
struct ProcList : public _ProcRoute_<Procs...>, public WsComponent
{
using SuperType = ProcList<Procs...>;
ProcList() : _ProcRoute_<Procs...>() {}
// 通过 WsComponent 继承
QList<WsRespondSignatureType> signatureTypes() const override
{
return _ProcRoute_<>::_execute_map.keys();
}
QList<WsRespondEntry> getEntryWithSignature(const WsRespondSignatureType& t) const override
{
QList<WsRespondEntry> list;
for (auto key : _ProcRoute_<>::_execute_map.keys()) {
if (key == t)
list.append(_ProcRoute_<>::_execute_map[key]);
}
return list;
}
QList<WsRespondEntry> getEntrysWithInType(const QString& msg_type) const override
{
QList<WsRespondEntry> list;
for (auto key : _ProcRoute_<>::_execute_map.keys()) {
if (key.first == msg_type)
list.append(_ProcRoute_<>::_execute_map[key]);
}
return list;
}
};