From c7dd8164811dbccf75801caed3427c0be4449659 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Fri, 12 Sep 2025 18:31:15 +0300 Subject: [PATCH] ... --- asibfm700/asibfm700_mount.h | 2 +- mcc/mcc_finite_state_machine.h | 2 +- mcc/mcc_generic_mount.h | 377 +++++++++++++++++++++++++-------- 3 files changed, 294 insertions(+), 87 deletions(-) diff --git a/asibfm700/asibfm700_mount.h b/asibfm700/asibfm700_mount.h index 81bf7b6..5569d67 100644 --- a/asibfm700/asibfm700_mount.h +++ b/asibfm700/asibfm700_mount.h @@ -50,7 +50,7 @@ public: Asibfm700Mount(Asibfm700MountConfig const& config, std::shared_ptr logger, - const auto& pattern_range = LOGGER_DEFAULT_FORMAT); + const auto& pattern_range = mcc::utils::MccSpdlogLogger::LOGGER_DEFAULT_FORMAT); ~Asibfm700Mount(); }; diff --git a/mcc/mcc_finite_state_machine.h b/mcc/mcc_finite_state_machine.h index 0bec64e..c6fbbde 100644 --- a/mcc/mcc_finite_state_machine.h +++ b/mcc/mcc_finite_state_machine.h @@ -52,7 +52,7 @@ struct MccFiniteStateMachineCategory : public std::error_category { const char* name() const noexcept { - return "ADC_GENERIC_DEVICE"; + return "MCC-FSM-ERROR-CATEGORY"; } std::string message(int ec) const diff --git a/mcc/mcc_generic_mount.h b/mcc/mcc_generic_mount.h index d7dba25..80b80d8 100644 --- a/mcc/mcc_generic_mount.h +++ b/mcc/mcc_generic_mount.h @@ -14,6 +14,8 @@ namespace mcc enum class MccGenericMountErrorCode : int { ERROR_OK, ERROR_HW_INIT, ERROR_HW_STOP, ERROR_HW_GETSTATE }; +enum class MccGenericFsmMountErrorCode : int { ERROR_OK, ERROR_INVALID_OPERATION, ERROR_UNKNOWN_EVENT }; + } // namespace mcc @@ -25,6 +27,11 @@ class is_error_code_enum : public true_type { }; +template <> +class is_error_code_enum : public true_type +{ +}; + } // namespace std @@ -75,6 +82,12 @@ public: { } + MccGenericMount(MccGenericMount&&) = default; + MccGenericMount(const MccGenericMount&) = delete; + + MccGenericMount& operator=(MccGenericMount&&) = default; + MccGenericMount& operator=(const MccGenericMount&) = delete; + virtual ~MccGenericMount() = default; error_t stopMount() @@ -114,20 +127,29 @@ public: /* GENERIC FINITE-STATE-MACHINE MOUNT REFERENCE IMPLEMENTATION */ +template +concept mcc_generic_fsm_mount_event_c = + fsm::traits::fsm_event_c && std::constructible_from && requires(T t) { + { t.mount() } -> std::same_as; + }; + + template struct MccGenericFsmMountBaseEvent { + typedef MOUNT_T mount_t; + // static constexpr std::string_view ID{""}; virtual ~MccGenericFsmMountBaseEvent() = default; - MOUNT_T& mount() const + MOUNT_T* mount() const { return _mount; } protected: - MOUNT_T& _mount; + MOUNT_T* _mount; - MccGenericFsmMountBaseEvent(MOUNT_T& mount) : _mount(mount) {} + MccGenericFsmMountBaseEvent(MOUNT_T* mount) : _mount(mount) {} }; @@ -141,7 +163,24 @@ template struct MccGenericFsmMountStopEvent; template -struct MccGenericFsmMountErrorEvent; +struct MccGenericFsmMountErrorEvent : MccGenericFsmMountBaseEvent { + static constexpr std::string_view ID{"GENERIC-MOUNT-ERROR-EVENT"}; + + typedef typename MOUNT_T::error_t mount_error_t; + + MccGenericFsmMountErrorEvent(MOUNT_T* mount, const mount_error_t& err) + : MccGenericFsmMountBaseEvent(mount), _err(err) + { + } + + mount_error_t eventData() const noexcept + { + return _err; + } + +protected: + mount_error_t _err; +}; template struct MccGenericFsmMountSlewEvent; @@ -149,138 +188,306 @@ struct MccGenericFsmMountSlewEvent; template struct MccGenericFsmMountTrackEvent; -template -struct MccGenericFsmMountBaseState { - // static constexpr std::string_view ID{""}; - virtual ~MccGenericFsmMountBaseState() = default; +// template +// struct MccGenericFsmMountBaseState { +// typedef MOUNT_T mount_t; -protected: - MccGenericFsmMountBaseState() = default; +// virtual ~MccGenericFsmMountBaseState() = default; - template - void exitLog(this auto&& self, EvT& event) - { - using self_t = std::remove_cvref_t; +// protected: +// MccGenericFsmMountBaseState() = default; - if constexpr (mcc_generic_log_mount_c && - std::derived_from>) { - event.mount().logDebug(std::format("Exit from '{}' state due to '{}' event ...", self_t::ID, EvT::ID)); - } - } +// template +// void exitLog(this auto&& self, EvT& event) +// { +// using self_t = std::remove_cvref_t; - template - void enterLog(this auto&& self, EvT& event) - { - using self_t = std::remove_cvref_t; +// if constexpr (mcc_generic_log_mount_c && +// std::derived_from>) { +// event.mount()->logDebug(std::format("Exit from '{}' state due to '{}' event ...", self_t::ID, EvT::ID)); +// } +// } - if constexpr (mcc_generic_log_mount_c && - std::derived_from>) { - event.mount().logDebug(std::format("Enter to '{}' state due to '{}' event ...", self_t::ID, EvT::ID)); - } - } -}; +// template +// void enterLog(this auto&& self, EvT& event) +// { +// using self_t = std::remove_cvref_t; -template -struct MccGenericFsmMountStartState; +// if constexpr (mcc_generic_log_mount_c && +// std::derived_from>) { +// event.mount()->logDebug(std::format("Enter to '{}' state due to '{}' event ...", self_t::ID, EvT::ID)); +// } +// } +// }; -template -struct MccGenericFsmMountIdleState; +// template +// struct MccGenericFsmMountStartState; -template -struct MccGenericFsmMountStopState; +// template +// struct MccGenericFsmMountIdleState; -template -struct MccGenericFsmMountErrorState; +// template +// struct MccGenericFsmMountStopState; -template -struct MccGenericFsmMountSlewState; +// template +// struct MccGenericFsmMountErrorState; -template -struct MccGenericFsmMountTrackState; +// template +// struct MccGenericFsmMountSlewState; -template -struct MccGenericFsmMountInitState { - static constexpr std::string_view ID{"GENERIC-MOUNT-INIT-STATE"}; +// template +// struct MccGenericFsmMountTrackState; - using transition_t = fsm::fsm_transition_table_t< - std::pair, MccGenericFsmMountIdleState>, - std::pair, MccGenericFsmMountErrorState>, - std::pair, MccGenericFsmMountInitState>>; +// template +// struct MccGenericFsmMountInitState : MccGenericFsmMountBaseState { +// static constexpr std::string_view ID{"GENERIC-MOUNT-INIT-STATE"}; + +// using transition_t = fsm::fsm_transition_table_t< +// std::pair, MccGenericFsmMountIdleState>, +// std::pair, MccGenericFsmMountErrorState>, +// std::pair, MccGenericFsmMountInitState>>; - void exit(MccGenericFsmMountInitEvent& event) - { - if constexpr (mcc_generic_log_mount_c) { - event.mount().logWarn("It seems a re-entering to the initializing state was asked! Ignore the event!"); - } - } +// void exit(MccGenericFsmMountInitEvent& event) +// { +// if constexpr (mcc_generic_log_mount_c) { +// event.mount()->logWarn("It seems a re-entering to the initializing state was asked! Ignore the event!"); +// } +// } - void enter(MccGenericFsmMountInitEvent& event) - { - if constexpr (mcc_generic_log_mount_c) { - event.mount().logWarn( - "It seems a re-entering to the initializing state was asked! Ignore the event and wait for the mount " - "to initialize!"); - } - } +// void enter(MccGenericFsmMountInitEvent& event) +// { +// if constexpr (mcc_generic_log_mount_c) { +// event.mount()->logWarn( +// "It seems a re-entering to the initializing state was asked! Ignore the event and wait for the mount +// " "to initialize!"); +// } +// } - void exit(fsm::traits::fsm_event_c auto& event) - { - exitLog(event); - } +// void exit(fsm::traits::fsm_event_c auto& event) +// { +// exitLog(event); +// } - void enter(fsm::traits::fsm_event_c auto& event) - { - enterLog(event); - } -}; +// void enter(fsm::traits::fsm_event_c auto& event) +// { +// enterLog(event); +// auto err = event.mount()->initMount(); +// } +// }; template , - fsm::traits::fsm_event_c INIT_EVENT_T = MccGenericFsmMountInitEvent, - fsm::traits::fsm_event_c IDLE_EVENT_T = MccGenericFsmMountIdleEvent, - fsm::traits::fsm_event_c STOP_EVENT_T = MccGenericFsmMountStopEvent, - fsm::traits::fsm_event_c ERROR_EVENT_T = MccGenericFsmMountErrorEvent, - fsm::traits::fsm_event_c SLEW_EVENT_T = MccGenericFsmMountSlewEvent, - fsm::traits::fsm_event_c TRACK_EVENT_T = MccGenericFsmMountTrackEvent> + mcc_generic_fsm_mount_event_c INIT_EVENT_T = MccGenericFsmMountInitEvent, + mcc_generic_fsm_mount_event_c STOP_EVENT_T = MccGenericFsmMountStopEvent, + mcc_generic_fsm_mount_event_c SLEW_EVENT_T = MccGenericFsmMountSlewEvent, + mcc_generic_fsm_mount_event_c TRACK_EVENT_T = MccGenericFsmMountTrackEvent> class MccGenericFsmMount : public MOUNT_T, protected fsm::MccFiniteStateMachine { + // to prevent infinite recursion! + static_assert(!std::derived_from, "!!!!!!!!!"); + public: - using typename MOUNT_T::error_t; + typedef std::error_code error_t; + +protected: + /* default states implementation */ + + + template + struct MccGenericFsmMountBaseState { + virtual ~MccGenericFsmMountBaseState() = default; + + protected: + MccGenericFsmMountBaseState() = default; + + template + void exitLog(this auto&& self, EvT& event) + { + using self_t = std::remove_cvref_t; + + if constexpr (mcc_generic_log_mount_c && + std::derived_from>) { + event.mount()->logDebug(std::format("Exit from '{}' state due to '{}' event ...", self_t::ID, EvT::ID)); + } + } + + template + void enterLog(this auto&& self, EvT& event) + { + using self_t = std::remove_cvref_t; + + if constexpr (mcc_generic_log_mount_c && + std::derived_from>) { + event.mount()->logDebug(std::format("Enter to '{}' state due to '{}' event ...", self_t::ID, EvT::ID)); + } + } + }; + + struct MccGenericFsmMountErrorState; + + struct MccGenericFsmMountStartState; + + template + struct MccGenericFsmMountIdleState; + + template + struct MccGenericFsmMountStopState; + + template + struct MccGenericFsmMountSlewState; + + template + struct MccGenericFsmMountTrackState; + + template + struct MccGenericFsmMountInitState : MccGenericFsmMountBaseState { + static constexpr std::string_view ID{"GENERIC-MOUNT-INIT-STATE"}; + + using transition_t = fsm::fsm_transition_table_t< + std::pair, MccGenericFsmMountIdleState>, + std::pair, MccGenericFsmMountErrorState>, + std::pair, MccGenericFsmMountInitState>>; + + + void exit(MccGenericFsmMountInitEvent& event) + { + if constexpr (mcc_generic_log_mount_c) { + event.mount()->logWarn("It seems a re-entering to the initializing state was asked! Ignore the event!"); + } + } + + void enter(MccGenericFsmMountInitEvent& event) + { + if constexpr (mcc_generic_log_mount_c) { + event.mount()->logWarn( + "It seems a re-entering to the initializing state was asked! Ignore the event and wait for the " + "mount " + "to initialize!"); + } + } + + void exit(fsm::traits::fsm_event_c auto& event) + { + exitLog(event); + } + + void enter(fsm::traits::fsm_event_c auto& event) + { + enterLog(event); + auto err = event.mount()->initMount(); + } + }; + + struct MccGenericFsmMountErrorState // default implementation (just log error) + { + static constexpr std::string_view ID{"GENERIC-MOUNT-ERROR-STATE"}; + + using transition_t = fsm::fsm_transition_table_t< + std::pair, MccGenericFsmMountErrorState>, + std::pair, MccGenericFsmMountIdleState>, + std::pair, MccGenericFsmMountInitState>>; + + void exit(fsm::traits::fsm_event_c auto& event) + { + exitLog(event); + + if constexpr (mcc_generic_log_mount_c) { + event.mount()->logWarn( + std::format("The mount is in the error state!!! One must correct it before transit to any states! " + "Event type is '{}'", + decltype(event)::ID)); + } + } + + void enter(fsm::traits::fsm_event_c auto& event) + { + enterLog(event); + + if constexpr (mcc_generic_log_mount_c) { + auto err = event.eventData(); + event.mount()->logError( + std::format("The mount is in the error state: code = {}, category = {}, message = '{}'", + err.value(), err.category().name(), err.message())); + } + } + }; + + +public: + MccGenericFsmMount(MOUNT_T mount, fsm::traits::fsm_state_c auto start_state) + : MOUNT_T(std::move(mount)), fsm::MccFiniteStateMachine(std::move(start_state)) + { + } // reimplementation of base-class methods to adapt it to FSM-behavior auto initMount() { - this->dispatchEvent(INIT_EVENT_T{*this}); + try { + this->dispatchEvent(INIT_EVENT_T{this}); + } catch (std::system_error const& exc) { + return exc.code(); + } + + return MccGenericFsmMountErrorCode::ERROR_OK; } auto stopMount() { - this->dispatchEvent(STOP_EVENT_T{*this}); + try { + this->dispatchEvent(STOP_EVENT_T{this}); + } catch (std::system_error const& exc) { + return exc.code(); + } + + return MccGenericFsmMountErrorCode::ERROR_OK; } auto slewToTarget() { - this->dispatchEvent(SLEW_EVENT_T{*this}); + try { + this->dispatchEvent(SLEW_EVENT_T{this}); + } catch (std::system_error const& exc) { + return exc.code(); + } + + return MccGenericFsmMountErrorCode::ERROR_OK; } auto stopSlewing() { - this->dispatchEvent(STOP_EVENT_T{*this}); + try { + this->dispatchEvent(STOP_EVENT_T{this}); + } catch (std::system_error const& exc) { + return exc.code(); + } + + return MccGenericFsmMountErrorCode::ERROR_OK; } auto trackTarget() { - this->dispatchEvent(TRACK_EVENT_T{*this}); + try { + this->dispatchEvent(TRACK_EVENT_T{this}); + } catch (std::system_error const& exc) { + return exc.code(); + } + + return MccGenericFsmMountErrorCode::ERROR_OK; } auto stopTracking() { - this->dispatchEvent(STOP_EVENT_T{*this}); + try { + this->dispatchEvent(STOP_EVENT_T{this}); + } catch (std::system_error const& exc) { + return exc.code(); + } + + return MccGenericFsmMountErrorCode::ERROR_OK; }