This commit is contained in:
2025-08-24 04:03:45 +03:00
parent dc87ce0fb9
commit 60cade4d1f
93 changed files with 19500 additions and 55 deletions

View File

@@ -102,14 +102,25 @@ enum class MccTelemetryUpdatePolicy : int { TEMETRY_UPDATE_INNER, TEMETRY_UPDATE
template <MccTelemetryUpdatePolicy UPDATE_POLICY = MccTelemetryUpdatePolicy::TEMETRY_UPDATE_INNER>
class MccTelemetry : public mcc_telemetry_interface_t<std::error_code>
{
protected:
static constexpr uint16_t internalUpdatingIntervalDiv = 5;
public:
static constexpr MccTelemetryUpdatePolicy updatePolicy = UPDATE_POLICY;
static constexpr auto defaultUpdateInterval = std::chrono::milliseconds(100);
static constexpr auto defaultInternalUpdateTimeout = defaultUpdateInterval * 5;
typedef std::error_code error_t;
MccTelemetry(mcc_ccte_c auto* ccte, mcc_PCM_c auto* pcm, mcc_hardware_c auto* hardware)
: _updated(false), _data(), _updateMutex(new std::mutex), _updateCondVar(new std::condition_variable)
: _isDataUpdated(false),
_data(),
_internalUpdating(false),
_currentUpdateInterval(defaultUpdateInterval),
_updateMutex(new std::mutex),
_updateCondVar(new std::condition_variable)
{
_data.target.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS;
@@ -325,8 +336,6 @@ public:
}
_updated = true;
return MccTelemetryErrorCode::ERROR_OK;
};
@@ -366,7 +375,15 @@ public:
}
virtual ~MccTelemetry() = default;
virtual ~MccTelemetry()
{
_internalUpdatingStopSource.request_stop();
if (_internalUpdatingFuture.valid()) {
_internalUpdatingFuture.get();
}
};
template <traits::mcc_time_duration_c DT>
DT telemetryDataUpdateInterval() const
@@ -379,65 +396,100 @@ public:
return telemetryDataUpdateInterval<std::chrono::milliseconds>();
}
error_t updateTelemetryData(traits::mcc_time_duration_c auto const& period)
void setTelemetryDataUpdateInterval(traits::mcc_time_duration_c auto const& interval)
{
// using d_t = typename std::remove_cvref_t<decltype(period)>::rep;
using d_t = std::remove_cvref_t<decltype(interval)>;
// bool is_zero;
if constexpr (std::floating_point<typename d_t::rep>) {
_currentUpdateInterval = utils::isEqual(interval.count(), 0.0) ? defaultUpdateInterval : interval;
} else {
_currentUpdateInterval = interval.count() == 0 ? defaultUpdateInterval : interval;
}
}
// if (std::floating_point<d_t>) {
// is_zero = utils::isEqual(period.count(), d_t::zero());
// } else {
// is_zero = period.count() == d_t::zero();
// }
void startInternalTelemetryDataUpdating()
{
using intv_t = std::remove_cvref_t<decltype(_currentUpdateInterval)>;
// if (is_zero) { // just update once
// return _updateFunc();
// } else {
// // try to update once
// auto ret = _updateFunc();
// if (ret) {
// return ret;
// }
_internalUpdating = true;
// _lastUpdateError = MccTelemetryErrorCode::ERROR_OK;
_internalUpdatingFuture = std::async(
std::launch::async,
[this](std::stop_token stop_token) {
if (stop_token.stop_requested()) {
return MccTelemetryErrorCode::ERROR_OK;
}
// _timerThread = [period, this](std::stop_token st) {
// while (!st.stop_requested()) {
// {
// std::lock_guard thread_lock{*_updateMutex};
_lastUpdateError = updateTelemetryData(defaultInternalUpdateTimeout);
if (_lastUpdateError) {
_internalUpdating = false;
return _lastUpdateError;
}
// _lastUpdateError = _updateFunc();
// _updateCondVar->notify_all();
// if (_lastUpdateError) {
// return;
// }
// }
auto sleep_td = _currentUpdateInterval / internalUpdatingIntervalDiv;
// std::this_thread::sleep_for(period);
// }
// };
for (uint16_t i = 0; i < internalUpdatingIntervalDiv - 1; ++i) {
if (stop_token.stop_requested()) {
return MccTelemetryErrorCode::ERROR_OK;
}
// _timerThread.detach();
std::this_thread::sleep_for(sleep_td);
}
// return MccTelemetryErrorCode::ERROR_OK;
// }
if (stop_token.stop_requested()) {
return MccTelemetryErrorCode::ERROR_OK;
}
if constexpr (std::floating_point<intv_t>) {
std::this_thread::sleep_for(sleep_td);
} else {
auto rem = _currentUpdateInterval % internalUpdatingIntervalDiv;
if (rem.count()) {
std::this_thread::sleep_for(rem);
} else {
std::this_thread::sleep_for(sleep_td);
}
}
},
_internalUpdatingStopSource.get_token());
}
void stopInternalTelemetryDataUpdating()
{
_internalUpdatingStopSource.request_stop();
_internalUpdating = false;
}
bool isInternalTelemetryDataUpdating() const
{
return _internalUpdating;
}
error_t updateTelemetryData(traits::mcc_time_duration_c auto const& timeout)
{
std::lock_guard thread_lock{*_updateMutex};
std::stop_source stop_source;
_isDataUpdated = false;
std::future<error_t> update_ft = std::async(std::launch::async, _updateFunc, stop_source.get_token());
auto status = update_ft.wait_for(period);
auto status = update_ft.wait_for(timeout);
if (status != std::future_status::ready) {
auto ok = stop_source.stop_requested();
return MccTelemetryErrorCode::ERROR_DATA_TIMEOUT;
return _lastUpdateError = MccTelemetryErrorCode::ERROR_DATA_TIMEOUT;
}
_isDataUpdated = true;
_updateCondVar->notify_all();
return update_ft.get();
return _lastUpdateError = update_ft.get();
}
// block the thread and wait for data to be ready (external synchronization)
@@ -449,7 +501,7 @@ public:
std::unique_lock ulock(*_updateMutex);
auto res = _updateCondVar->wait_for(ulock, timeout, [this]() { return _updated; });
auto res = _updateCondVar->wait_for(ulock, timeout, [this]() { return _isDataUpdated; });
if (res == std::cv_status::timeout) {
return MccTelemetryErrorCode::ERROR_DATA_TIMEOUT;
}
@@ -463,7 +515,7 @@ public:
return _lastUpdateError;
}
// update and get data as soon as possible
// just get current data
error_t telemetryData(mcc_telemetry_data_c auto* tdata)
{
if (tdata == nullptr) {
@@ -472,14 +524,6 @@ public:
std::lock_guard thread_lock{*_updateMutex};
// error_t ret = _updateFunc();
// if (!ret) {
// mcc_copy_telemetry_data(_data, tdata);
// }
// return ret;
mcc_copy_telemetry_data(_data, tdata);
return MccTelemetryErrorCode::ERROR_OK;
@@ -495,10 +539,13 @@ public:
protected:
std::atomic_bool _updated;
std::atomic_bool _isDataUpdated;
MccTelemetryData _data;
std::atomic_bool _internalUpdating{false};
std::chrono::nanoseconds _currentUpdateInterval{std::chrono::milliseconds(100)};
std::future<error_t> _internalUpdatingFuture{};
std::stop_source _internalUpdatingStopSource{};
std ::function<error_t(bool, std::stop_token)> _updateTargetFunc{};
std::function<error_t(std::stop_token)> _updateFunc{};