...
This commit is contained in:
parent
9e70ace4b7
commit
911f82eb4d
@ -111,5 +111,6 @@ if (WITH_TESTS)
|
|||||||
add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp)
|
add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp)
|
||||||
|
|
||||||
set(ASTROM_TEST_APP astrom_test)
|
set(ASTROM_TEST_APP astrom_test)
|
||||||
add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp)
|
add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp
|
||||||
|
mcc_traits.h)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "comm_server_endpoint.h"
|
#include "mcc_traits.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
namespace mcc
|
namespace mcc
|
||||||
|
|||||||
@ -8,35 +8,11 @@
|
|||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "mcc_traits.h"
|
||||||
|
|
||||||
namespace mcc
|
namespace mcc
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace traits
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename R>
|
|
||||||
concept mcc_char_view = std::ranges::view<R> && std::same_as<std::ranges::range_value_t<R>, char>;
|
|
||||||
|
|
||||||
|
|
||||||
// input range of char/const char
|
|
||||||
template <typename R, typename CharT = char>
|
|
||||||
concept mcc_input_char_range =
|
|
||||||
std::ranges::input_range<R> && std::is_same_v<std::remove_cv_t<std::ranges::range_value_t<R>>, CharT>;
|
|
||||||
|
|
||||||
|
|
||||||
// output range of char/const char
|
|
||||||
template <typename R, typename CharT = char>
|
|
||||||
concept mcc_output_char_range =
|
|
||||||
std::ranges::output_range<R, CharT> && std::same_as<std::remove_cv_t<std::ranges::range_value_t<R>>, CharT>;
|
|
||||||
|
|
||||||
|
|
||||||
template <typename R>
|
|
||||||
concept mcc_view_or_output_char_range = mcc_char_view<R> || mcc_output_char_range<R>;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace traits
|
|
||||||
|
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
180
cxx/mcc_spdlog.h
Normal file
180
cxx/mcc_spdlog.h
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <spdlog/logger.h>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "mcc_traits.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace mcc::utils
|
||||||
|
{
|
||||||
|
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
|
/* SPDLOG-library based advanced single/multithreaded logger */
|
||||||
|
|
||||||
|
class MccSpdlogLogger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// [year-month-day time.millisecs][log-level]: log-message
|
||||||
|
constexpr static std::array LOGGER_DEFAULT_FORMAT = {"[%Y-%m-%d %T.%e]"sv, "[%l]"sv, ": "sv, "%v"sv};
|
||||||
|
|
||||||
|
typedef spdlog::level::level_enum loglevel_t;
|
||||||
|
|
||||||
|
template <traits::mcc_range_of_input_char_range R = decltype(LOGGER_DEFAULT_FORMAT)>
|
||||||
|
MccSpdlogLogger(std::shared_ptr<spdlog::logger> logger, const R& pattern_range = LOGGER_DEFAULT_FORMAT)
|
||||||
|
: _loggerSPtr(logger), _currentLogPatternRange(), _currentLogPattern()
|
||||||
|
{
|
||||||
|
if (std::distance(pattern_range.begin(), pattern_range.end())) {
|
||||||
|
std::ranges::copy(
|
||||||
|
pattern_range | std::views::transform([](const auto& el) { return std::string(el.begin(), el.end()); }),
|
||||||
|
std::back_inserter(_currentLogPatternRange));
|
||||||
|
} else {
|
||||||
|
std::ranges::copy(LOGGER_DEFAULT_FORMAT | std::views::transform([](const auto& el) {
|
||||||
|
return std::string(el.begin(), el.end());
|
||||||
|
}),
|
||||||
|
std::back_inserter(_currentLogPatternRange));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ranges::copy(std::views::join(_currentLogPatternRange), std::back_inserter(_currentLogPattern));
|
||||||
|
|
||||||
|
_loggerSPtr->set_pattern(_currentLogPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~MccSpdlogLogger() = default;
|
||||||
|
|
||||||
|
|
||||||
|
void setLogLevel(loglevel_t log_level)
|
||||||
|
{
|
||||||
|
_loggerSPtr->set_level(log_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
loglevel_t getLogLevel() const
|
||||||
|
{
|
||||||
|
return _loggerSPtr->level();
|
||||||
|
}
|
||||||
|
|
||||||
|
void logMessage(loglevel_t level, const std::string& msg)
|
||||||
|
{
|
||||||
|
_loggerSPtr->log(level, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// specialized for given level methods
|
||||||
|
|
||||||
|
void logCritical(const std::string& msg)
|
||||||
|
{
|
||||||
|
logMessage(spdlog::level::critical, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logError(const std::string& msg)
|
||||||
|
{
|
||||||
|
logMessage(spdlog::level::err, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logWarn(const std::string& msg)
|
||||||
|
{
|
||||||
|
logMessage(spdlog::level::warn, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logInfo(const std::string& msg)
|
||||||
|
{
|
||||||
|
logMessage(spdlog::level::info, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logDebug(const std::string& msg)
|
||||||
|
{
|
||||||
|
logMessage(spdlog::level::debug, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logTrace(const std::string& msg)
|
||||||
|
{
|
||||||
|
logMessage(spdlog::level::trace, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_formattable... ArgTs>
|
||||||
|
void logMessage(spdlog::level::level_enum level, spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
_loggerSPtr->log(level, fmt, std::forward<ArgTs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_formattable... ArgTs>
|
||||||
|
void logCritical(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
_loggerSPtr->log(spdlog::level::critical, fmt, std::forward<ArgTs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... ArgTs>
|
||||||
|
void logError(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
_loggerSPtr->log(spdlog::level::err, fmt, std::forward<ArgTs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_formattable... ArgTs>
|
||||||
|
void logWarn(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
_loggerSPtr->log(spdlog::level::warn, fmt, std::forward<ArgTs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_formattable... ArgTs>
|
||||||
|
void logInfo(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
_loggerSPtr->log(spdlog::level::info, fmt, std::forward<ArgTs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_formattable... ArgTs>
|
||||||
|
void logDebug(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
_loggerSPtr->log(spdlog::level::debug, fmt, std::forward<ArgTs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_formattable... ArgTs>
|
||||||
|
void logTrace(spdlog::format_string_t<ArgTs...> fmt, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
_loggerSPtr->log(spdlog::level::trace, fmt, std::forward<ArgTs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::list<std::string> _currentLogPatternRange;
|
||||||
|
std::string _currentLogPattern;
|
||||||
|
std::shared_ptr<spdlog::logger> _loggerSPtr;
|
||||||
|
|
||||||
|
|
||||||
|
// helper method
|
||||||
|
|
||||||
|
// 'after_idx' is 0-based index!
|
||||||
|
void addMarkToPatternIdx(const traits::mcc_input_char_range auto& mark, size_t after_idx = 1)
|
||||||
|
requires(!std::is_pointer_v<std::decay_t<decltype(mark)>>)
|
||||||
|
{
|
||||||
|
if (!std::distance(mark.begin(), mark.end())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = _currentLogPatternRange.begin();
|
||||||
|
size_t idx = 0;
|
||||||
|
while (it != _currentLogPatternRange.end()) {
|
||||||
|
++it;
|
||||||
|
if (idx == after_idx)
|
||||||
|
break;
|
||||||
|
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentLogPatternRange.emplace(it, mark.begin(), mark.end());
|
||||||
|
|
||||||
|
_currentLogPattern.clear();
|
||||||
|
std::ranges::copy(std::views::join(_currentLogPatternRange), std::back_inserter(_currentLogPattern));
|
||||||
|
|
||||||
|
_loggerSPtr->set_pattern(_currentLogPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addMarkToPatternIdx(const char* mark, size_t after_idx = 1)
|
||||||
|
{
|
||||||
|
addMarkToPatternIdx(std::string_view{mark});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace mcc::utils
|
||||||
42
cxx/mcc_traits.h
Normal file
42
cxx/mcc_traits.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
namespace mcc::traits
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
concept mcc_char_view = std::ranges::view<R> && std::same_as<std::ranges::range_value_t<R>, char>;
|
||||||
|
|
||||||
|
|
||||||
|
// input range of char/const char
|
||||||
|
template <typename R, typename CharT = char>
|
||||||
|
concept mcc_input_char_range =
|
||||||
|
std::ranges::input_range<R> && std::is_same_v<std::remove_cv_t<std::ranges::range_value_t<R>>, CharT>;
|
||||||
|
|
||||||
|
|
||||||
|
// output range of char/const char
|
||||||
|
template <typename R, typename CharT = char>
|
||||||
|
concept mcc_output_char_range =
|
||||||
|
std::ranges::output_range<R, CharT> && std::same_as<std::remove_cv_t<std::ranges::range_value_t<R>>, CharT>;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
concept mcc_view_or_output_char_range = mcc_char_view<R> || mcc_output_char_range<R>;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
concept mcc_range_of_input_char_range =
|
||||||
|
std::ranges::range<R> && traits::mcc_input_char_range<std::ranges::range_value_t<R>>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/72430369/how-to-check-that-a-type-is-formattable-using-type-traits-concepts)
|
||||||
|
template <typename T>
|
||||||
|
concept mcc_formattable =
|
||||||
|
requires(T v, std::format_context ctx) { std::formatter<std::remove_cvref_t<T>>().format(v, ctx); };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace mcc::traits
|
||||||
21
cxx/mount.h
21
cxx/mount.h
@ -36,6 +36,18 @@ concept mcc_mount_state_c = requires(T t, const T t_const) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// meteo parameters (to compute refraction)
|
||||||
|
struct MccMountMeteo {
|
||||||
|
typedef double temp_t; // Temperature in C
|
||||||
|
typedef double humid_t; // humidity in %
|
||||||
|
typedef double press_t; // atmospheric presure in hPa=mB
|
||||||
|
|
||||||
|
temp_t temperature;
|
||||||
|
humid_t humidity;
|
||||||
|
press_t pressure;
|
||||||
|
};
|
||||||
|
|
||||||
|
// mount current position and related quantities
|
||||||
class MccMountPosition
|
class MccMountPosition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -166,6 +178,13 @@ public:
|
|||||||
return _currentMountOrient.load();
|
return _currentMountOrient.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setMeteo(std::derived_from<MccMountMeteo> auto const& meteo)
|
||||||
|
{
|
||||||
|
_currentMeteo.store(meteo);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mount_config_t _mountCurrentConfig;
|
mount_config_t _mountCurrentConfig;
|
||||||
|
|
||||||
@ -174,6 +193,8 @@ protected:
|
|||||||
|
|
||||||
std::atomic<mount_orient_t> _currentMountOrient;
|
std::atomic<mount_orient_t> _currentMountOrient;
|
||||||
|
|
||||||
|
std::atomic<MccMountMeteo> _currentMeteo;
|
||||||
|
|
||||||
void updateMountState()
|
void updateMountState()
|
||||||
{
|
{
|
||||||
mount_orient_t orient;
|
mount_orient_t orient;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user