20#include "cc_tools_qt/ToolsField.h"
21#include "cc_tools_qt/ToolsFrame.h"
22#include "cc_tools_qt/ToolsMessage.h"
23#include "cc_tools_qt/ToolsProtMsgInterface.h"
24#include "cc_tools_qt/details/ToolsFieldCreator.h"
26#include "comms/util/Tuple.h"
43template <
typename TBase,
template<
typename...>
class TProtMsg,
typename TActualMsg>
52 using ProtInterface =
typename TBase::ProtInterface;
54 using ProtOptions =
typename TBase::ProtOptions;
57 using ProtMsg = TProtMsg<ProtInterface, ProtOptions>;
59 using FieldsList =
typename Base::FieldsList;
85 m_msg(std::move(other.m_msg))
102 m_msg = std::move(other.m_msg);
123 ProtMsg::hasCustomName(),
128 return nameInternal(Tag());
136 return m_msg.doRefresh();
144 ProtMsg::hasStaticMsgId(),
149 return numericIdInternal(Tag());
155 auto& actObj =
static_cast<TActualMsg&
>(*this);
156 actObj = TActualMsg();
162 auto* castedOther =
dynamic_cast<const TActualMsg*
>(&other);
163 if (castedOther ==
nullptr) {
167 assert(other.
idAsString() == Base::idAsString());
168 auto& actObj =
static_cast<TActualMsg&
>(*this);
169 actObj = *castedOther;
178 return m_msg.doValid();
187 data.reserve(m_msg.doLength());
188 auto iter = std::back_inserter(data);
189 [[maybe_unused]]
auto es = m_msg.doWrite(iter, data.max_size());
190 assert(es == comms::ErrorStatus::Success);
199 auto iter = data.data();
200 auto es = m_msg.doRead(iter, data.size());
201 return es == comms::ErrorStatus::Success;
204 virtual typename Base::Ptr cloneImpl()
const override
206 return typename Base::Ptr(
new TActualMsg(
static_cast<const TActualMsg&
>(*
this)));
209 virtual void assignProtMessageImpl(
void* protMsg)
override
211 auto* protMsgBase =
reinterpret_cast<ProtInterface*
>(protMsg);
212 auto* actProtMsg =
static_cast<ProtMsg*
>(protMsgBase);
213 m_msg = std::move(*actProtMsg);
216 virtual DataSeq encodeFramedImpl(ToolsFrame& frame)
const override
218 return frame.writeProtMsg(&m_msg);
221 virtual FieldsList transportFieldsImpl()
override
226 ProtMsg::hasTransportFields(),
231 updateTransportFieldsInternal(fields, Tag());
235 virtual FieldsList payloadFieldsImpl()
override
238 fields.reserve(std::tuple_size<typename ProtMsg::AllFields>::value);
239 comms::util::tupleForEach(m_msg.fields(), details::ToolsFieldCreator(fields));
246 struct HasNameTag {};
248 struct HasTransportFields {};
249 struct NoTransportFields {};
251 qlonglong numericIdInternal(HasIdTag)
const
253 static const bool IsNumeric =
254 std::is_enum<typename ProtMsg::MsgIdType>::value ||
255 std::is_integral<typename ProtMsg::MsgIdType>::value;
257 static_assert(IsNumeric,
"Only numeric message IDs are supported");
258 return static_cast<qlonglong
>(m_msg.doGetId());
261 qlonglong numericIdInternal(NoIdTag)
const
263 [[maybe_unused]]
static constexpr bool Must_not_be_called =
false;
264 assert(Must_not_be_called);
265 return static_cast<qlonglong
>(0);
268 const char* nameInternal(HasNameTag)
const
270 static_assert(comms::isMessageBase<ProtMsg>(),
"ProtMsg is expected to be proper message");
271 static_assert(ProtMsg::hasCustomName(),
"ProtMsg is expected to define message name");
273 return m_msg.doName();
276 const char* nameInternal(NoNameTag)
const
279 static const char* NoName =
"NO-NAME";
283 void updateTransportFieldsInternal(FieldsList& fields, HasTransportFields)
285 fields.reserve(std::tuple_size<typename ProtMsg::TransportFields>::value);
286 comms::util::tupleForEach(m_msg.transportFields(), details::ToolsFieldCreator(fields));
289 void updateTransportFieldsInternal([[maybe_unused]] FieldsList& fields, NoTransportFields)