21#include "cc_tools_qt/ToolsField.h"
22#include "cc_tools_qt/ToolsFrameCommon.h"
23#include "cc_tools_qt/ToolsMessage.h"
24#include "cc_tools_qt/ToolsProtMsgInterface.h"
25#include "cc_tools_qt/details/ToolsFieldCreator.h"
27#include "comms/util/Tuple.h"
44template <
typename TBase,
template<
typename...>
class TProtMsg,
typename TActualMsg>
53 using ProtInterface =
typename TBase::ProtInterface;
55 using ProtOptions =
typename TBase::ProtOptions;
58 using ProtMsg = TProtMsg<ProtInterface, ProtOptions>;
60 using FieldsList =
typename Base::FieldsList;
86 m_msg(std::move(other.m_msg))
103 m_msg = std::move(other.m_msg);
124 ProtMsg::hasCustomName(),
129 return nameInternal(Tag());
137 return m_msg.doRefresh();
145 ProtMsg::hasStaticMsgId(),
150 return numericIdInternal(Tag());
156 auto& actObj =
static_cast<TActualMsg&
>(*this);
157 actObj = TActualMsg();
163 auto* castedOther =
dynamic_cast<const TActualMsg*
>(&other);
164 if (castedOther ==
nullptr) {
168 assert(other.
idAsString() == Base::idAsString());
169 auto& actObj =
static_cast<TActualMsg&
>(*this);
170 actObj = *castedOther;
179 return m_msg.doValid();
188 data.reserve(m_msg.doLength());
189 auto iter = std::back_inserter(data);
190 [[maybe_unused]]
auto es = m_msg.doWrite(iter, data.max_size());
191 assert(es == comms::ErrorStatus::Success);
200 auto iter = data.data();
201 auto es = m_msg.doRead(iter, data.size());
202 return es == comms::ErrorStatus::Success;
205 virtual typename Base::Ptr cloneImpl()
const override
207 return typename Base::Ptr(
new TActualMsg(
static_cast<const TActualMsg&
>(*
this)));
210 virtual void assignProtMessageImpl(
void* protMsg)
override
212 auto* protMsgBase =
reinterpret_cast<ProtInterface*
>(protMsg);
213 auto* actProtMsg =
static_cast<ProtMsg*
>(protMsgBase);
214 m_msg = std::move(*actProtMsg);
217 virtual DataSeq encodeFramedImpl(ToolsFrame& frame)
const override
219 auto& castedFrame =
static_cast<ToolsFrameCommon<TBase>&
>(frame);
220 return castedFrame.writeProtMsg(m_msg);
223 virtual FieldsList transportFieldsImpl()
override
228 ProtMsg::hasTransportFields(),
233 updateTransportFieldsInternal(fields, Tag());
237 virtual FieldsList payloadFieldsImpl()
override
240 fields.reserve(std::tuple_size<typename ProtMsg::AllFields>::value);
241 comms::util::tupleForEach(m_msg.fields(), details::ToolsFieldCreator(fields));
248 struct HasNameTag {};
250 struct HasTransportFields {};
251 struct NoTransportFields {};
253 qlonglong numericIdInternal(HasIdTag)
const
255 static const bool IsNumeric =
256 std::is_enum<typename ProtMsg::MsgIdType>::value ||
257 std::is_integral<typename ProtMsg::MsgIdType>::value;
259 static_assert(IsNumeric,
"Only numeric message IDs are supported");
260 return static_cast<qlonglong
>(m_msg.doGetId());
263 qlonglong numericIdInternal(NoIdTag)
const
265 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
266 assert(Must_not_be_called);
267 return static_cast<qlonglong
>(0);
270 const char* nameInternal(HasNameTag)
const
272 static_assert(comms::isMessageBase<ProtMsg>(),
"ProtMsg is expected to be proper message");
273 static_assert(ProtMsg::hasCustomName(),
"ProtMsg is expected to define message name");
275 return m_msg.doName();
278 const char* nameInternal(NoNameTag)
const
281 static const char* NoName =
"NO-NAME";
285 void updateTransportFieldsInternal(FieldsList& fields, HasTransportFields)
287 fields.reserve(std::tuple_size<typename ProtMsg::TransportFields>::value);
288 comms::util::tupleForEach(m_msg.transportFields(), details::ToolsFieldCreator(fields));
291 void updateTransportFieldsInternal([[maybe_unused]] FieldsList& fields, NoTransportFields)