This commit is contained in:
2026-02-04 18:29:08 +03:00
parent 5b4456d6ef
commit 593a914d8d
5 changed files with 587 additions and 40 deletions

View File

@@ -147,6 +147,11 @@ concept mcc_fp_type_like_c =
/* GEOMETRICAL ANGLE REPRESENTATION CLASS CONCEPT */ /* GEOMETRICAL ANGLE REPRESENTATION CLASS CONCEPT */
/* REQUIREMENT: in the MCC-library it is assumed that an arithmetic representation of angles are measured in the
radians!!! This means that possible conversion operator 'SOME_USER_ANGLE_CLASS::operator double()'
must return an angle in radians!
*/
template <typename T> template <typename T>
concept mcc_angle_c = mcc_fp_type_like_c<T> && requires(T v, double vd) { concept mcc_angle_c = mcc_fp_type_like_c<T> && requires(T v, double vd) {
// mandatory arithmetic operations // mandatory arithmetic operations
@@ -783,6 +788,13 @@ struct mcc_telemetry_interface_t {
{ {
return std::forward<SelfT>(self).setTarget(pt); return std::forward<SelfT>(self).setTarget(pt);
} }
// get entered target position
template <std::derived_from<mcc_telemetry_interface_t> SelfT>
RetT setTarget(this SelfT&& self, mcc_skypoint_c auto* pt)
{
return std::forward<SelfT>(self).getTarget(pt);
}
}; };
template <typename T> template <typename T>

View File

@@ -26,6 +26,8 @@ constexpr double MCC_TWO_PI = std::numbers::pi * 2.0;
static constexpr double MCC_SIDERAL_TO_UT1_RATIO = 1.002737909350795; // sideral/UT1 static constexpr double MCC_SIDERAL_TO_UT1_RATIO = 1.002737909350795; // sideral/UT1
static constexpr double MCC_J2000_MJD = 51544.5;
// a value to represent of infinite time duration according to type of duration representation // a value to represent of infinite time duration according to type of duration representation
template <traits::mcc_time_duration_c DT> template <traits::mcc_time_duration_c DT>

447
mcc_ser.h Normal file
View File

@@ -0,0 +1,447 @@
#pragma once
#include "mcc_coordinate.h"
#include "mcc_serialization_common.h"
namespace mcc::impl
{
enum class MccSerializerErrorCode : int {
ERROR_OK,
ERROR_UNDERLYING_SERIALIZER,
ERROR_INVALID_EPOCH,
ERROR_COORD_TRANSFORM
};
} // namespace mcc::impl
namespace std
{
template <>
class is_error_code_enum<mcc::impl::MccSerializerErrorCode> : public true_type
{
};
} // namespace std
namespace mcc::impl
{
// error category
struct MccSerializerCategory : public std::error_category {
MccSerializerCategory() : std::error_category() {}
const char* name() const noexcept
{
return "MCC-SERIALIZER-ERR-CATEGORY";
}
std::string message(int ec) const
{
MccSerializerErrorCode err = static_cast<MccSerializerErrorCode>(ec);
switch (err) {
case MccSerializerErrorCode::ERROR_OK:
return "OK";
case MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER:
return "error returned by underlying serializer";
case MccSerializerErrorCode::ERROR_INVALID_EPOCH:
return "invalid coordinate epoch";
case MccSerializerErrorCode::ERROR_COORD_TRANSFORM:
return "coordinates transformation error";
default:
return "UNKNOWN";
}
}
static const MccSerializerCategory& get()
{
static const MccSerializerCategory constInst;
return constInst;
}
};
inline std::error_code make_error_code(MccSerializerErrorCode ec)
{
return std::error_code(static_cast<int>(ec), MccSerializerCategory::get());
}
/* BASE SERIALIZER CLASS (FOR IMPLEMENTATIONS BELOW) */
struct MccSerializerBase : mcc_serializer_interface_t<MccError> {
virtual ~MccSerializerBase() = default;
using typename mcc_serializer_interface_t<MccError>::error_t;
protected:
MccSerializerBase() = default;
enum CoordType { CO_LON, CO_LAT };
static void addElemDelimiter(traits::mcc_output_char_range auto& output,
mcc_serialization_params_c auto const& params)
{
std::format_to(std::back_inserter(output), "{}", params.elem_delim);
}
static void addSeqDelimiter(traits::mcc_output_char_range auto& output,
mcc_serialization_params_c auto const& params)
{
std::format_to(std::back_inserter(output), "{}", params.seq_delim);
}
// set serialized angle format according to coordinates pair format and type of
// serializing mcc_coord_pair_c::pairKind
template <MccCoordPairKind PAIRKIND, CoordType TYPE = MccSerializerBase::CO_LON>
static void angleFormatFromCoordPairType(mcc_serialization_params_c auto& pars)
{
if (pars.coordpair_format == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_DEGREES) {
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_DEGREES;
} else { // format to sexagesimal form according to celestial coordinate type
if constexpr (TYPE == MccSerializerBase::CO_LON) {
if (pars.coordpair_format == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGDEG) {
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS;
} else if (pars.coordpair_format == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG) {
if constexpr (PAIRKIND == MccCoordPairKind::COORDS_KIND_AZZD ||
PAIRKIND == MccCoordPairKind::COORDS_KIND_AZALT ||
PAIRKIND == MccCoordPairKind::COORDS_KIND_XY ||
PAIRKIND == MccCoordPairKind::COORDS_KIND_GENERIC) { // azimuth is in degrees
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS;
} else { // RA or HA
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS;
}
} else {
// !!!!!!!!!!!!!!!!!!
}
} else { // Y-coordinates (co-latitude one, DEC, ALT, ZD, generic X) is always in degrees for celestial
// point
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS;
}
}
}
template <typename VT, typename R>
requires(std::ranges::input_range<R> && std::same_as<VT, std::ranges::range_value_t<R>>)
static error_t serializeRange(mcc_serializer_c auto& sr,
R const& r,
traits::mcc_output_char_range auto& output,
mcc_serialization_params_c auto const& params)
{
size_t i = 0, N = std::ranges::size(r);
for (auto const& el : r) {
auto err = sr(output, el, params);
if (err) {
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
if (++i < N) {
MccSerializerBase::addSeqDelimiter(output, params);
}
}
return MccSerializerErrorCode::ERROR_OK;
}
};
/* MAIN (FALLBACK) TEMPLATED IMPLEMENTATION */
template <typename VT>
struct MccSerializer : MccSerializerBase {
constexpr static std::string_view serializerName{"MCC-FALLBACK-SERIALIZER"};
template <typename ParamsT = std::nullptr_t>
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
{
if constexpr (std::formattable<VT, char>) {
} else if constexpr (std::convertible_to<VT, std::string>) {
auto err = MccSerializer<std::string>{}(output, static_cast<std::string>(value), params);
if (err) {
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
} else if constexpr (std::ranges::range<VT>) {
using value_t = std::remove_cv_t<std::ranges::range_value_t<VT>>;
// special range (character sequence)
if constexpr (std::same_as<value_t, char>) {
std::string str;
std::ranges::copy(value, std::back_inserter(str));
auto err = MccSerializer<std::string>{}(output, str, params);
if (err) {
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
} else {
MccSerializer<value_t> sr;
return MccSerializerBase::serializeRange<value_t>(sr, value, output, params);
}
} else {
static_assert(false, "UNSUPPORTED TYPE!!!");
}
return MccSerializerErrorCode::ERROR_OK;
}
};
/* SPECIALIZATION FOR THE SOME CONCEPTS */
/* std::chrono::sys_time variants and its sequence */
template <typename VT>
requires traits::mcc_systime_c<VT>
struct MccSerializer<VT> : MccSerializerBase {
virtual ~MccSerializer() = default;
constexpr static std::string_view serializerName{"MCC-SYSTIME-SERIALIZER"};
template <typename ParamsT = std::nullptr_t>
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
{
std::vformat_to(std::back_inserter(output), params.systime_format, std::make_format_args(value));
return MccSerializerErrorCode::ERROR_OK;
}
};
template <typename VT>
requires(!std::is_arithmetic_v<VT> && mcc_angle_c<VT>)
struct MccSerializer<VT> : MccSerializerBase {
constexpr static std::string_view serializerName{"MCC-ANGLE-SERIALIZER"};
template <typename ParamsT = std::nullptr_t>
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
{
double v = (double)value; // radians (see mcc_angle_c concept)
std::string sgm;
switch (params.angle_format) {
case MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_DEGREES:
v *= MCC_RADS_TO_DEGRESS;
return MccSerializer<double>{}(output, v, params);
case MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS:
if (params.norm_sxgm) {
sgm = utils::rad2sxg<true>(v, false, params.angle_prec.deg_prec);
} else {
sgm = utils::rad2sxg<false>(v, false, params.angle_prec.deg_prec);
}
break;
case MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS:
if (params.norm_sxgm) {
sgm = utils::rad2sxg<true>(v, true, params.angle_prec.hour_prec);
} else {
sgm = utils::rad2sxg<false>(v, true, params.angle_prec.hour_prec);
}
break;
default:
break;
}
auto err = MccSerializer<std::string>{}(output, sgm, params);
if (err) {
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
return MccSerializerErrorCode::ERROR_OK;
};
};
template <mcc_coord_epoch_c VT>
struct MccSerializer<VT> : MccSerializerBase {
constexpr static std::string_view serializerName{"MCC-COORD-EPOCH-SERIALIZER"};
template <typename ParamsT = std::nullptr_t>
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
{
double jd;
switch (params.timepoint_format) {
case MccTimePointFormat::MCC_TIMEPOINT_FORMAT_DATE: {
auto tp = value.UTC();
auto err = MccSerializer<decltype(tp)>{}(output, tp, params);
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
case MccTimePointFormat::MCC_TIMEPOINT_FORMAT_JEPOCH: {
auto ep = value.JEpoch();
auto err = MccSerializer<decltype(ep)>{}(output, ep, params);
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
case MccTimePointFormat::MCC_TIMEPOINT_FORMAT_JD:
jd = value.MJD() + MCC_J2000_MJD;
break;
case MccTimePointFormat::MCC_TIMEPOINT_FORMAT_MJD:
jd = value.MJD();
break;
}
auto err = MccSerializer<double>{}(output, jd, params);
if (err) {
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
return MccSerializerErrorCode::ERROR_OK;
}
};
template <mcc_coord_pair_c VT>
struct MccSerializer<VT> : MccSerializerBase {
constexpr static std::string_view serializerName{"MCC-COORD-PAIR-SERIALIZER"};
template <typename ParamsT = std::nullptr_t>
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
{
std::conditional_t<std::is_null_pointer_v<ParamsT>, std::nullptr_t, mcc_serialization_params_t> pars =
std::is_null_pointer_v<ParamsT> ? nullptr : params;
pars.norm_sxgm = true;
pars.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
// X-coordinate
MccSerializerBase::angleFormatFromCoordPairType<VT::pairKind, MccSerializerBase::CO_LON>(pars);
auto err = MccSerializer<MccAngle>{}(output, value.x(), params);
if (err) {
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
MccSerializerBase::addElemDelimiter(output, params);
pars.norm_sxgm = false; // do not normalize co-latitude angle
// Y-coordinate
MccSerializerBase::angleFormatFromCoordPairType<VT::pairKind, MccSerializerBase::CO_LAT>(pars);
err = MccSerializer<MccAngle>{}(output, value.y(), params);
if (err) {
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
MccSerializerBase::addElemDelimiter(output, params);
// epoch
auto ep = value.epoch();
auto ep_err = MccSerializer<decltype(ep)>{}(output, ep, params);
if (ep_err) {
return mcc_deduced_err(ep_err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
MccSerializerBase::addElemDelimiter(output, params);
// pair kind
return mcc_deduced_err(MccSerializer<std::string_view>{}(output, MccCoordPairKindToStr(VT::pairKind), params),
MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
return MccSerializerErrorCode::ERROR_OK;
}
};
template <mcc_skypoint_c VT>
struct MccSerializer<VT> : MccSerializerBase {
constexpr static std::string_view serializerName{"MCC-SKYPOINT-SERIALIZER"};
template <typename ParamsT = std::nullptr_t>
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
{
auto serialize_cpair = [&]<typename T>(T& cp) {
auto ccte_err = value.to(cp);
if (ccte_err) {
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
}
auto err = MccSerializer<T>{}(output, cp, params);
if (err) {
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
}
return MccSerializerErrorCode::ERROR_OK;
};
switch (value.pairKind()) {
case MccCoordPairKind::COORDS_KIND_RADEC_ICRS: {
MccSkyRADEC_ICRS cp;
return serialize_cpair(cp);
}
case MccCoordPairKind::COORDS_KIND_RADEC_OBS: {
MccSkyRADEC_OBS cp;
return serialize_cpair(cp);
}
case MccCoordPairKind::COORDS_KIND_RADEC_APP: {
MccSkyRADEC_APP cp;
return serialize_cpair(cp);
}
case MccCoordPairKind::COORDS_KIND_HADEC_OBS: {
MccSkyHADEC_OBS cp;
return serialize_cpair(cp);
}
case MccCoordPairKind::COORDS_KIND_HADEC_APP: {
MccSkyHADEC_APP cp;
return serialize_cpair(cp);
}
case MccCoordPairKind::COORDS_KIND_AZZD: {
MccSkyAZZD cp;
return serialize_cpair(cp);
}
case MccCoordPairKind::COORDS_KIND_AZALT: {
MccSkyAZALT cp;
return serialize_cpair(cp);
}
case MccCoordPairKind::COORDS_KIND_XY: {
MccGenXY cp;
return serialize_cpair(cp);
}
case MccCoordPairKind::COORDS_KIND_GENERIC: {
MccGenXY cp;
return serialize_cpair(cp);
}
default:
// !!!!!!!!!!!!
}
}
};
template <mcc_telemetry_data_c VT>
struct MccSerializer<VT> : MccSerializerBase {
constexpr static std::string_view serializerName{"MCC-TELEMETRY-DATA-SERIALIZER"};
template <typename ParamsT = std::nullptr_t>
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
{
// FORMAT: RA_OBS_MOUNT, DEC_OBS_MOUNT, RA_APP_MOUNT, DEC_APP_MOUNT, HA_APP_MOUNT, AZ_MOUNT, ZD_MOUNT,
// REFR_CORR_MOUNT, LAST, ENC_X, ENC_Y, PCM_X, PCM_Y, RA_APP_TAG, DEC_APP_TAG, AZ_TAG, ZD_TAG, TIMEPOINT
// NOTE: One must assume that the returned RA coordinates are in format of underlying celestial coordinate
// transformation engine used in the mcc_skypoint_c class implementation. E.g. ERFA-library uses the
// CIO-based representation of RA
std::conditional_t<std::is_null_pointer_v<ParamsT>, std::nullptr_t, mcc_serialization_params_t> pars =
std::is_null_pointer_v<ParamsT> ? nullptr : params;
pars.norm_sxgm = true;
pars.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
// RA_OBS_MOUNT
MccSerializerBase::angleFormatFromCoordPairType<VT::pairKind, MccSerializerBase::CO_LON>(pars);
}
};
} // namespace mcc::impl

View File

@@ -17,6 +17,51 @@
namespace mcc namespace mcc
{ {
/* celestial angle serialization */
enum class MccSerializedAngleFormat {
MCC_SERIALIZED_FORMAT_DEGREES, // degrees as floating-point number
MCC_SERIALIZED_FORMAT_SXGM_HOURS, // sexagesimal representation: hours:mins:secs
MCC_SERIALIZED_FORMAT_SXGM_DEGS, // sexagesimal representation: degs:arcmins:arcsecs
MCC_SERIALIZED_FORMAT_UNKNOWN
};
static constexpr std::string_view MCC_SERIALIZED_ANG_FORMAT_DEGREES_STR = "SRANG-FORMAT-DEGREES";
static constexpr std::string_view MCC_SERIALIZED_ANG_FORMAT_SXGM_HOURS_STR = "SRANG-FORMAT-SXGM_HOURDEG";
static constexpr std::string_view MCC_SERIALIZED_ANG_FORMAT_SXGM_DEGS_STR = "SRANG-FORMAT-SXGM_DEGDEG";
static constexpr std::string_view MccSerializedAngleFormatToStr(MccSerializedAngleFormat fmt)
{
return fmt == MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_DEGREES ? MCC_SERIALIZED_ANG_FORMAT_DEGREES_STR
: fmt == MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS
? MCC_SERIALIZED_ANG_FORMAT_SXGM_HOURS_STR
: fmt == MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS ? MCC_SERIALIZED_ANG_FORMAT_SXGM_DEGS_STR
: MCC_SERIALIZED_ANG_FORMAT_DEGREES_STR;
}
template <traits::mcc_input_char_range R>
static constexpr MccSerializedAngleFormat MccSerializedAngleFormatStrToValue(R&& str)
{
if constexpr (std::is_array_v<std::decay_t<R>>) {
return MccSerializedAngleFormatStrToValue(std::string_view{str});
}
const auto hash = mcc::utils::FNV1aHash(std::forward<R>(str));
return hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_ANG_FORMAT_DEGREES_STR)
? MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_DEGREES
: hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_ANG_FORMAT_SXGM_HOURS_STR)
? MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS
: hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_ANG_FORMAT_SXGM_DEGS_STR)
? MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS
: MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_UNKNOWN;
}
/* coordinates pair serialization */
enum class MccSerializedCoordPairFormat { enum class MccSerializedCoordPairFormat {
MCC_SERIALIZED_FORMAT_DEGREES, // both angles are in degrees as floating-point number MCC_SERIALIZED_FORMAT_DEGREES, // both angles are in degrees as floating-point number
MCC_SERIALIZED_FORMAT_SXGM_HOURDEG, // X is in hour and Y is in degree sexagesimal representation MCC_SERIALIZED_FORMAT_SXGM_HOURDEG, // X is in hour and Y is in degree sexagesimal representation
@@ -24,19 +69,19 @@ enum class MccSerializedCoordPairFormat {
MCC_SERIALIZED_FORMAT_UNKNOWN MCC_SERIALIZED_FORMAT_UNKNOWN
}; };
static constexpr std::string_view MCC_SERIALIZED_FORMAT_DEGREES_STR = "SRCP-FORMAT-DEGREES"; static constexpr std::string_view MCC_SERIALIZED_CP_FORMAT_DEGREES_STR = "SRCP-FORMAT-DEGREES";
static constexpr std::string_view MCC_SERIALIZED_FORMAT_SXGM_HOURDEG_STR = "SRCP-FORMAT-SXGM_HOURDEG"; static constexpr std::string_view MCC_SERIALIZED_CP_FORMAT_SXGM_HOURDEG_STR = "SRCP-FORMAT-SXGM_HOURDEG";
static constexpr std::string_view MCC_SERIALIZED_FORMAT_SXGM_DEGDEG_STR = "SRCP-FORMAT-SXGM_DEGDEG"; static constexpr std::string_view MCC_SERIALIZED_CP_FORMAT_SXGM_DEGDEG_STR = "SRCP-FORMAT-SXGM_DEGDEG";
static constexpr std::string_view MccSerializedCoordPairFormatToStr(MccSerializedCoordPairFormat fmt) static constexpr std::string_view MccSerializedCoordPairFormatToStr(MccSerializedCoordPairFormat fmt)
{ {
return fmt == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_DEGREES ? MCC_SERIALIZED_FORMAT_DEGREES_STR return fmt == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_DEGREES ? MCC_SERIALIZED_CP_FORMAT_DEGREES_STR
: fmt == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG : fmt == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG
? MCC_SERIALIZED_FORMAT_SXGM_HOURDEG_STR ? MCC_SERIALIZED_CP_FORMAT_SXGM_HOURDEG_STR
: fmt == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGDEG : fmt == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGDEG
? MCC_SERIALIZED_FORMAT_SXGM_DEGDEG_STR ? MCC_SERIALIZED_CP_FORMAT_SXGM_DEGDEG_STR
: MCC_SERIALIZED_FORMAT_DEGREES_STR; : MCC_SERIALIZED_CP_FORMAT_DEGREES_STR;
} }
template <traits::mcc_input_char_range R> template <traits::mcc_input_char_range R>
@@ -48,17 +93,19 @@ static constexpr MccSerializedCoordPairFormat MccSerializedCoordPairFormatStrToV
const auto hash = mcc::utils::FNV1aHash(std::forward<R>(str)); const auto hash = mcc::utils::FNV1aHash(std::forward<R>(str));
return hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_FORMAT_DEGREES_STR) return hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_CP_FORMAT_DEGREES_STR)
? MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_DEGREES ? MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_DEGREES
: hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_FORMAT_SXGM_HOURDEG_STR) : hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_CP_FORMAT_SXGM_HOURDEG_STR)
? MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG ? MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG
: hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_FORMAT_SXGM_DEGDEG_STR) : hash == mcc::utils::FNV1aHash(MCC_SERIALIZED_CP_FORMAT_SXGM_DEGDEG_STR)
? MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGDEG ? MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGDEG
: MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_UNKNOWN; : MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_UNKNOWN;
} }
struct MccSerializedCoordPairFormatPrec { /* precision of representation of serialized celestial angle/coordinates pair */
struct MccSerializedAngleFormatPrec {
uint8_t hour_prec = 2; // number of decimal places in hour seconds (sexagesimal format) uint8_t hour_prec = 2; // number of decimal places in hour seconds (sexagesimal format)
uint8_t deg_prec = 1; // number of decimal places in arcseconds (sexagesimal format) uint8_t deg_prec = 1; // number of decimal places in arcseconds (sexagesimal format)
// slightly better than 0.1 arcsecond precision // slightly better than 0.1 arcsecond precision
@@ -120,10 +167,14 @@ concept mcc_serialization_params_c = requires(T t) {
requires traits::mcc_output_char_range<decltype(t.seq_delim)>; requires traits::mcc_output_char_range<decltype(t.seq_delim)>;
requires traits::mcc_output_char_range<decltype(t.elem_delim)>; requires traits::mcc_output_char_range<decltype(t.elem_delim)>;
requires std::same_as<decltype(t.angle_format), MccSerializedAngleFormat>;
requires std::same_as<decltype(t.angle_prec), MccSerializedAngleFormatPrec>;
requires std::same_as<decltype(t.coordpair_format), MccSerializedCoordPairFormat>; requires std::same_as<decltype(t.coordpair_format), MccSerializedCoordPairFormat>;
requires std::same_as<decltype(t.coordpair_prec), MccSerializedCoordPairFormatPrec>;
requires std::same_as<decltype(t.timepoint_format), MccTimePointFormat>; requires std::same_as<decltype(t.timepoint_format), MccTimePointFormat>;
// a format string for mcc_systime_c types (std;:chrono::sys_time)
requires std::same_as<decltype(t.systime_format), std::string_view>;
// if true - normalize angle in sexagesimal format (to control rounding) // if true - normalize angle in sexagesimal format (to control rounding)
// (to avoid something like "24:00:00.0" for sexagesimal 'hours:minutes:seconds' format) // (to avoid something like "24:00:00.0" for sexagesimal 'hours:minutes:seconds' format)
requires std::convertible_to<decltype(t.norm_sxgm), bool>; requires std::convertible_to<decltype(t.norm_sxgm), bool>;
@@ -148,6 +199,12 @@ struct mcc_serializer_interface_t {
return std::forward<SelfT>(self)(output, value); return std::forward<SelfT>(self)(output, value);
} }
template <std::derived_from<mcc_serializer_interface_t> SelfT, traits::mcc_output_char_range R, typename ValueT>
RetT operator()(this SelfT&& self, R& output, ValueT const& value, mcc_serialization_params_c auto const& params)
{
return std::forward<SelfT>(self)(output, value, params);
}
protected: protected:
mcc_serializer_interface_t() = default; mcc_serializer_interface_t() = default;
}; };
@@ -159,12 +216,12 @@ concept mcc_serializer_c =
// static const variable with name of the serializer // static const variable with name of the serializer
requires std::formattable<decltype(T::serializerName), char> && std::is_const_v<decltype(T::serializerName)>; requires std::formattable<decltype(T::serializerName), char> && std::is_const_v<decltype(T::serializerName)>;
// must define a type "params_t" // // must define a type "params_t"
requires mcc_serialization_params_c<typename T::params_t>; // requires mcc_serialization_params_c<typename T::params_t>;
{ t.setParams(std::declval<typename T::params_t const&>()) }; // { t.setParams(std::declval<typename T::params_t const&>()) };
{ t_const.getParams() } -> std::same_as<typename T::params_t>; // { t_const.getParams() } -> std::same_as<typename T::params_t>;
}; };
@@ -181,6 +238,12 @@ struct mcc_deserializer_interface_t {
return std::forward<SelfT>(self)(input, value); return std::forward<SelfT>(self)(input, value);
} }
template <std::derived_from<mcc_deserializer_interface_t> SelfT, traits::mcc_input_char_range R, typename ValueT>
RetT operator()(this SelfT&& self, R const& input, ValueT& value, mcc_serialization_params_c auto& params)
{
return std::forward<SelfT>(self)(input, value, params);
}
protected: protected:
mcc_deserializer_interface_t() = default; mcc_deserializer_interface_t() = default;
}; };
@@ -193,12 +256,12 @@ concept mcc_deserializer_c =
requires std::formattable<decltype(T::deserializerName), char> && requires std::formattable<decltype(T::deserializerName), char> &&
std::is_const_v<decltype(T::deserializerName)>; std::is_const_v<decltype(T::deserializerName)>;
// must define a type "params_t" // // must define a type "params_t"
requires mcc_serialization_params_c<typename T::params_t>; // requires mcc_serialization_params_c<typename T::params_t>;
{ t.setParams(std::declval<typename T::params_t const&>()) }; // { t.setParams(std::declval<typename T::params_t const&>()) };
{ t_const.getParams() } -> std::same_as<typename T::params_t>; // { t_const.getParams() } -> std::same_as<typename T::params_t>;
}; };
@@ -213,19 +276,24 @@ struct mcc_serialization_params_t {
std::string seq_delim{MCC_SERIALIZING_DEFAULT_SEQ_DELIMITER}; std::string seq_delim{MCC_SERIALIZING_DEFAULT_SEQ_DELIMITER};
std::string elem_delim{MCC_SERIALIZING_DEFAULT_ELEM_DELIMITER}; std::string elem_delim{MCC_SERIALIZING_DEFAULT_ELEM_DELIMITER};
MccSerializedAngleFormat angle_format{MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_DEGREES};
MccSerializedAngleFormatPrec angle_prec{MccSerializedAngleFormatPrec{.hour_prec = 2, .deg_prec = 1, .decimals = 6}};
MccSerializedCoordPairFormat coordpair_format{MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG}; MccSerializedCoordPairFormat coordpair_format{MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG};
MccSerializedCoordPairFormatPrec coordpair_prec{
MccSerializedCoordPairFormatPrec{.hour_prec = 2, .deg_prec = 1, .decimals = 6}};
MccTimePointFormat timepoint_format{MccTimePointFormat::MCC_TIMEPOINT_FORMAT_DATE}; MccTimePointFormat timepoint_format{MccTimePointFormat::MCC_TIMEPOINT_FORMAT_DATE};
std::string_view systime_format{"{:%FT%T}"};
bool norm_sxgm{false}; bool norm_sxgm{false};
bool sxgm_hms{false}; bool sxgm_hms{false};
}; };
static_assert(mcc_serialization_params_c<mcc_serialization_params_t>, "!!!");
namespace details namespace details
{ {
@@ -244,7 +312,7 @@ struct _params_manipulator_t {
_params.seq_delim = pars.seq_delim; _params.seq_delim = pars.seq_delim;
_params.elem_delim = pars.elem_delim; _params.elem_delim = pars.elem_delim;
_params.coordpair_format = pars.coordpair_format; _params.coordpair_format = pars.coordpair_format;
_params.coordpair_prec = pars.coordpair_prec; _params.angle_prec = pars.angle_prec;
_params.timepoint_format = pars.timepoint_format; _params.timepoint_format = pars.timepoint_format;
_params.norm_sxgm = pars.norm_sxgm; _params.norm_sxgm = pars.norm_sxgm;
_params.sxgm_hms = pars.sxgm_hms; _params.sxgm_hms = pars.sxgm_hms;
@@ -260,7 +328,7 @@ struct _params_manipulator_t {
pars.seq_delim = _params.seq_delim; pars.seq_delim = _params.seq_delim;
pars.elem_delim = _params.elem_delim; pars.elem_delim = _params.elem_delim;
pars.coordpair_format = _params.coordpair_format; pars.coordpair_format = _params.coordpair_format;
pars.coordpair_prec = _params.coordpair_prec; pars.angle_prec = _params.angle_prec;
pars.timepoint_format = _params.timepoint_format; pars.timepoint_format = _params.timepoint_format;
pars.norm_sxgm = _params.norm_sxgm; pars.norm_sxgm = _params.norm_sxgm;
pars.sxgm_hms = _params.sxgm_hms; pars.sxgm_hms = _params.sxgm_hms;
@@ -283,30 +351,40 @@ protected:
} // namespace details } // namespace details
template <mcc_serialization_params_c ParamsT>
struct MccSerializerBase : mcc_serializer_interface_t<MccError>, details::_params_manipulator_t<ParamsT> {
virtual ~MccSerializerBase() = default;
using typename mcc_serializer_interface_t<MccError>::error_t; struct MccDeserializerBase : mcc_deserializer_interface_t<MccError> {
using typename details::_params_manipulator_t<ParamsT>::params_t;
protected:
MccSerializerBase() = default;
};
template <mcc_serialization_params_c ParamsT>
struct MccDeserializerBase : mcc_deserializer_interface_t<MccError>, details::_params_manipulator_t<ParamsT> {
virtual ~MccDeserializerBase() = default; virtual ~MccDeserializerBase() = default;
using typename mcc_deserializer_interface_t<MccError>::error_t; using typename mcc_deserializer_interface_t<MccError>::error_t;
using typename details::_params_manipulator_t<ParamsT>::params_t;
protected: protected:
MccDeserializerBase() = default; MccDeserializerBase() = default;
}; };
// template <mcc_serialization_params_c ParamsT>
// struct MccSerializerBase : mcc_serializer_interface_t<MccError>, details::_params_manipulator_t<ParamsT> {
// virtual ~MccSerializerBase() = default;
// using typename mcc_serializer_interface_t<MccError>::error_t;
// using typename details::_params_manipulator_t<ParamsT>::params_t;
// protected:
// MccSerializerBase() = default;
// };
// template <mcc_serialization_params_c ParamsT>
// struct MccDeserializerBase : mcc_deserializer_interface_t<MccError>, details::_params_manipulator_t<ParamsT> {
// virtual ~MccDeserializerBase() = default;
// using typename mcc_deserializer_interface_t<MccError>::error_t;
// using typename details::_params_manipulator_t<ParamsT>::params_t;
// protected:
// MccDeserializerBase() = default;
// };
} // namespace impl } // namespace impl
} // namespace mcc } // namespace mcc

View File

@@ -286,6 +286,14 @@ public:
} }
error_t getTarget(mcc_skypoint_c auto* sp)
{
sp = _enteredTargetPos;
return MccTelemetryErrorCode::ERROR_OK;
}
// //
// blocks the current thread until telemetry data is received. // blocks the current thread until telemetry data is received.
// the maximum blocking time is equal to the set timeout (see setTelemetryDataTimeout method) // the maximum blocking time is equal to the set timeout (see setTelemetryDataTimeout method)