diff --git a/mcc/mcc_generic_mount.h b/mcc/mcc_generic_mount.h index 80b80d8..cd58005 100644 --- a/mcc/mcc_generic_mount.h +++ b/mcc/mcc_generic_mount.h @@ -127,175 +127,83 @@ 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 - { - return _mount; - } - -protected: - MOUNT_T* _mount; - - MccGenericFsmMountBaseEvent(MOUNT_T* mount) : _mount(mount) {} -}; - - -template -struct MccGenericFsmMountInitEvent; - -template -struct MccGenericFsmMountIdleEvent; - -template -struct MccGenericFsmMountStopEvent; - -template -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; - -template -struct MccGenericFsmMountTrackEvent; - -// template -// struct MccGenericFsmMountBaseState { -// typedef MOUNT_T mount_t; - -// 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)); -// } -// } -// }; - -// template -// struct MccGenericFsmMountStartState; - -// template -// struct MccGenericFsmMountIdleState; - -// template -// struct MccGenericFsmMountStopState; - -// template -// struct MccGenericFsmMountErrorState; - -// 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(); -// } -// }; - - - -template , - 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: typedef std::error_code error_t; + using fsm::MccFiniteStateMachine::currentStateID; + protected: + /* default events implementation */ + + struct MccGenericFsmMountBaseEvent { + virtual ~MccGenericFsmMountBaseEvent() = default; + + MccGenericFsmMount* mount() const + { + return _mount; + } + + protected: + MccGenericFsmMount* _mount; + + MccGenericFsmMountBaseEvent(MccGenericFsmMount* mount) : _mount(mount) {} + }; + + + struct MccGenericFsmMountInitEvent : MccGenericFsmMountBaseEvent { + static constexpr std::string_view ID{"GENERIC-MOUNT-INIT-EVENT"}; + + MccGenericFsmMountInitEvent(MccGenericFsmMount* mount) : MccGenericFsmMountBaseEvent(mount) {} + }; + + struct MccGenericFsmMountIdleEvent : MccGenericFsmMountBaseEvent { + static constexpr std::string_view ID{"GENERIC-MOUNT-IDLE-EVENT"}; + + MccGenericFsmMountIdleEvent(MccGenericFsmMount* mount) : MccGenericFsmMountBaseEvent(mount) {} + }; + + struct MccGenericFsmMountStopEvent : MccGenericFsmMountBaseEvent { + static constexpr std::string_view ID{"GENERIC-MOUNT-STOP-EVENT"}; + + MccGenericFsmMountStopEvent(MccGenericFsmMount* mount) : MccGenericFsmMountBaseEvent(mount) {} + }; + + struct MccGenericFsmMountErrorEvent : MccGenericFsmMountBaseEvent { + static constexpr std::string_view ID{"GENERIC-MOUNT-ERROR-EVENT"}; + + MccGenericFsmMountErrorEvent(MccGenericFsmMount* mount, const MccGenericFsmMount::error_t& err) + : MccGenericFsmMountBaseEvent(mount), _err(err) + { + } + + MccGenericFsmMount::error_t eventData() const noexcept + { + return _err; + } + + protected: + MccGenericFsmMount::error_t _err; + }; + + struct MccGenericFsmMountSlewEvent : MccGenericFsmMountBaseEvent { + static constexpr std::string_view ID{"GENERIC-MOUNT-SLEW-EVENT"}; + + MccGenericFsmMountSlewEvent(MccGenericFsmMount* mount) : MccGenericFsmMountBaseEvent(mount) {} + }; + + struct MccGenericFsmMountTrackEvent : MccGenericFsmMountBaseEvent { + static constexpr std::string_view ID{"GENERIC-MOUNT-TRACK-EVENT"}; + + MccGenericFsmMountTrackEvent(MccGenericFsmMount* mount) : MccGenericFsmMountBaseEvent(mount) {} + }; + + /* default states implementation */ - - template struct MccGenericFsmMountBaseState { virtual ~MccGenericFsmMountBaseState() = default; @@ -307,8 +215,7 @@ protected: { using self_t = std::remove_cvref_t; - if constexpr (mcc_generic_log_mount_c && - std::derived_from>) { + 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)); } } @@ -318,19 +225,16 @@ protected: { using self_t = std::remove_cvref_t; - if constexpr (mcc_generic_log_mount_c && - std::derived_from>) { + 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; + struct MccGenericFsmMountErrorState; // default error-state class implementation (forward declaration) template - struct MccGenericFsmMountIdleState; + struct MccGenericFsmMountInitState; template struct MccGenericFsmMountStopState; @@ -341,24 +245,61 @@ protected: template struct MccGenericFsmMountTrackState; + template - struct MccGenericFsmMountInitState : MccGenericFsmMountBaseState { + struct MccGenericFsmMountStartState + : MccGenericFsmMountBaseState // initial state after mount-class creation (uninitialized state) + { + static constexpr std::string_view ID{"GENERIC-MOUNT-START-STATE"}; + + // only initialization is allowed here + using transition_t = fsm::fsm_transition_table_t< + std::pair>>; + }; + + template + struct MccGenericFsmMountIdleState + : MccGenericFsmMountBaseState // IDLE state: mount is stopped, wait for client commands + { + static constexpr std::string_view ID{"GENERIC-MOUNT-IDLDE-STATE"}; + + using transition_t = fsm::fsm_transition_table_t< + std::pair>, + std::pair, + std::pair>, + std::pair>, + std::pair>, + std::pair>>; + + void exit(fsm::traits::fsm_event_c auto& event) + { + exitLog(event); + } + + void enter(fsm::traits::fsm_event_c auto& event) + { + enterLog(event); + } + }; + + 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>>; + std::pair>, + std::pair, + std::pair>; - void exit(MccGenericFsmMountInitEvent& 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) + void enter(MccGenericFsmMountInitEvent& event) { if constexpr (mcc_generic_log_mount_c) { event.mount()->logWarn( @@ -376,18 +317,81 @@ protected: void enter(fsm::traits::fsm_event_c auto& event) { enterLog(event); - auto err = event.mount()->initMount(); + + auto* mount_ptr = event.mount(); + + // call base-class initMount method! + auto err = static_cast(mount_ptr)->initMount(); + if (err) { + mount_ptr->dispatchEvent(MccGenericFsmMountErrorEvent{mount_ptr}); + return; + } + + // after initialization switch to IDLE state + mount_ptr->dispatchEvent(MccGenericFsmMountIdleEvent{mount_ptr}); } }; - struct MccGenericFsmMountErrorState // default implementation (just log error) + + template + struct MccGenericFsmMountStopState : MccGenericFsmMountBaseState { + static constexpr std::string_view ID{"GENERIC-MOUNT-STOP-STATE"}; + + using transition_t = fsm::fsm_transition_table_t< + std::pair>, + std::pair, + std::pair>; + + + void exit(MccGenericFsmMountStopEvent& event) + { + if constexpr (mcc_generic_log_mount_c) { + event.mount()->logWarn("It seems a re-entering to the stop state was asked! Ignore the event!"); + } + } + + void enter(MccGenericFsmMountStopEvent& event) + { + if constexpr (mcc_generic_log_mount_c) { + event.mount()->logWarn( + "It seems a re-entering to the stop state was asked! Ignore the event and wait for the mount to " + "stop!"); + } + } + + void exit(fsm::traits::fsm_event_c auto& event) + { + exitLog(event); + } + + void enter(fsm::traits::fsm_event_c auto& event) + { + enterLog(event); + + auto* mount_ptr = event.mount(); + + // call base-class stopMount method! + auto err = static_cast(mount_ptr)->stopMount(); + if (err) { + mount_ptr->dispatchEvent(MccGenericFsmMountErrorEvent{mount_ptr}); + return; + } + + // after stopping switch to IDLE state + mount_ptr->dispatchEvent(MccGenericFsmMountIdleEvent{mount_ptr}); + } + }; + + + struct MccGenericFsmMountErrorState : MccGenericFsmMountBaseState // default error-state class 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>>; + std::pair, + std::pair>, + std::pair>>; void exit(fsm::traits::fsm_event_c auto& event) { @@ -416,7 +420,9 @@ protected: public: - MccGenericFsmMount(MOUNT_T mount, fsm::traits::fsm_state_c auto start_state) + MccGenericFsmMount( + MOUNT_T mount, + fsm::traits::fsm_state_c auto start_state = MccGenericFsmMountStartState{}) : MOUNT_T(std::move(mount)), fsm::MccFiniteStateMachine(std::move(start_state)) { } @@ -426,7 +432,7 @@ public: auto initMount() { try { - this->dispatchEvent(INIT_EVENT_T{this}); + this->dispatchEvent(MccGenericFsmMountInitEvent{this}); } catch (std::system_error const& exc) { return exc.code(); } @@ -437,7 +443,7 @@ public: auto stopMount() { try { - this->dispatchEvent(STOP_EVENT_T{this}); + this->dispatchEvent(MccGenericFsmMountStopEvent{this}); } catch (std::system_error const& exc) { return exc.code(); } @@ -448,7 +454,7 @@ public: auto slewToTarget() { try { - this->dispatchEvent(SLEW_EVENT_T{this}); + this->dispatchEvent(MccGenericFsmMountSlewEvent{this}); } catch (std::system_error const& exc) { return exc.code(); } @@ -459,7 +465,7 @@ public: auto stopSlewing() { try { - this->dispatchEvent(STOP_EVENT_T{this}); + this->dispatchEvent(MccGenericFsmMountStopEvent{this}); } catch (std::system_error const& exc) { return exc.code(); } @@ -470,7 +476,7 @@ public: auto trackTarget() { try { - this->dispatchEvent(TRACK_EVENT_T{this}); + this->dispatchEvent(MccGenericFsmMountTrackEvent{this}); } catch (std::system_error const& exc) { return exc.code(); } @@ -482,7 +488,7 @@ public: auto stopTracking() { try { - this->dispatchEvent(STOP_EVENT_T{this}); + this->dispatchEvent(MccGenericFsmMountStopEvent{this}); } catch (std::system_error const& exc) { return exc.code(); }