...
This commit is contained in:
parent
64a3544bd8
commit
02afd65d6f
@ -317,7 +317,7 @@ protected:
|
||||
std::vector<std::string_view> _stateID{};
|
||||
std::vector<std::string_view> _eventID{};
|
||||
|
||||
std::mutex _transitionMutex{};
|
||||
std::recursive_mutex _transitionMutex{};
|
||||
|
||||
|
||||
static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to)
|
||||
@ -385,18 +385,23 @@ public:
|
||||
[states, currentState, this]<size_t... Is>(std::index_sequence<Is...>) {
|
||||
((_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>[this] =
|
||||
[states, currentState, this]<traits::fsm_event_c EvT>(EvT& event) {
|
||||
std::lock_guard lock(_transitionMutex);
|
||||
// to avoid effects of possible compiler optimizations
|
||||
// (here one needs to be sure that inside the lambda 'event' is used by reference)
|
||||
const auto p_event = &event;
|
||||
|
||||
std::visit(
|
||||
[&event, states, currentState, this]<traits::fsm_state_c curr_state_t>(curr_state_t*) {
|
||||
[p_event, states, currentState, this]<traits::fsm_state_c curr_state_t>(curr_state_t*) {
|
||||
using to_state_t = curr_state_t::transition_t::template find_state_by_event_t<EvT>;
|
||||
|
||||
if constexpr (!std::is_void_v<to_state_t>) {
|
||||
std::lock_guard lock(_transitionMutex);
|
||||
|
||||
// exit from current
|
||||
if constexpr (requires(curr_state_t inst) {
|
||||
{ inst.exit(std::declval<EvT&>()) };
|
||||
}) {
|
||||
std::get<curr_state_t>(*states).exit(event);
|
||||
// std::get<curr_state_t>(*states).exit(event);
|
||||
std::get<curr_state_t>(*states).exit(*p_event);
|
||||
} else if constexpr (requires(curr_state_t inst) {
|
||||
{ inst.exit() };
|
||||
}) {
|
||||
@ -407,7 +412,8 @@ public:
|
||||
if constexpr (requires(EvT inst) {
|
||||
{ inst.onTransit() };
|
||||
}) {
|
||||
event.onTransit();
|
||||
// event.onTransit();
|
||||
p_event->onTransit();
|
||||
}
|
||||
|
||||
*currentState = &std::get<to_state_t>(*states);
|
||||
@ -417,7 +423,8 @@ public:
|
||||
if constexpr (requires(to_state_t inst) {
|
||||
{ inst.enter(std::declval<EvT&>()) };
|
||||
}) {
|
||||
std::get<to_state_t>(*states).enter(event);
|
||||
// std::get<to_state_t>(*states).enter(event);
|
||||
std::get<to_state_t>(*states).enter(*p_event);
|
||||
} else if constexpr (requires(to_state_t inst) {
|
||||
{ inst.enter() };
|
||||
}) {
|
||||
@ -450,6 +457,17 @@ public:
|
||||
|
||||
(_eventID.emplace_back(std::tuple_element_t<Is, all_events_t>::ID), ...);
|
||||
}(std::make_index_sequence<std::tuple_size_v<all_events_t>>());
|
||||
|
||||
// call enter() method (if it exists) of the initial state
|
||||
std::visit(
|
||||
[]<traits::fsm_state_c curr_state_t>(curr_state_t* cstate) {
|
||||
if constexpr (requires(curr_state_t inst) {
|
||||
{ inst.enter() };
|
||||
}) {
|
||||
cstate->enter();
|
||||
}
|
||||
},
|
||||
*currentState);
|
||||
}
|
||||
|
||||
MccFiniteStateMachine(const MccFiniteStateMachine& other)
|
||||
|
||||
@ -155,13 +155,17 @@ public:
|
||||
|
||||
template <fsm::traits::fsm_state_c InitStateT, traits::mcc_input_char_range LogMarkT = std::string_view>
|
||||
MccMount(InitStateT,
|
||||
const LogMarkT& logger_mark = "[MOUNT]",
|
||||
std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"))
|
||||
std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"),
|
||||
const LogMarkT& logger_mark = "[MOUNT]")
|
||||
: fsm::MccFiniteStateMachine(InitStateT{}), utils::MccSpdlogLogger(logger)
|
||||
{
|
||||
addMarkToPatternIdx(logger_mark);
|
||||
|
||||
logDebug("Create MccMount class instance: thread = {}", getThreadId());
|
||||
|
||||
auto ids = this->stateIDs();
|
||||
auto r = ids | std::views::join_with(',');
|
||||
logDebug("{}", std::string(r.begin(), r.end()));
|
||||
}
|
||||
|
||||
|
||||
@ -173,7 +177,10 @@ public:
|
||||
|
||||
/* public methods */
|
||||
|
||||
void initMount() {}
|
||||
void initMount()
|
||||
{
|
||||
this->logInfo("STATE: {}", this->currentStateID());
|
||||
}
|
||||
|
||||
void stopMount() {}
|
||||
|
||||
|
||||
@ -318,7 +318,7 @@ struct MccMountStateInit : MccMountStateBase<MountT> {
|
||||
{
|
||||
this->enterLog(event);
|
||||
|
||||
auto mount = event.mount();
|
||||
MountT& mount = event.mount();
|
||||
mount.initMount();
|
||||
|
||||
// switch to IDLE state
|
||||
@ -403,13 +403,13 @@ struct MccMountStateIDLE : MccMountStateBase<MountT> {
|
||||
std::pair<MccMountEventStop<MountT>, MccMountStateIDLE<MountT>>,
|
||||
std::pair<MccMountEventShutdown<MountT>, MccMountStateShutdown<MountT>>>;
|
||||
|
||||
template <std::derived_from<MccMountStateBase<MountT>> EvT>
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void exit(EvT& event)
|
||||
{
|
||||
this->exitLog(event);
|
||||
}
|
||||
|
||||
template <std::derived_from<MccMountStateBase<MountT>> EvT>
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void enter(EvT& event)
|
||||
{
|
||||
this->enterLog(event);
|
||||
|
||||
@ -39,53 +39,47 @@ public:
|
||||
|
||||
// check if given position (x,y) in the zone
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
bool inZone(this auto&& self,
|
||||
const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
bool inZone(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return std::forward<decltype(self)>(self).inZoneImpl(x, y, utc);
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns a time duration to reach the zone
|
||||
// 0 - if already within
|
||||
// Inf - if it never reaches the zone
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_duration_t timeTo(this auto&& self,
|
||||
const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
pz_duration_t timeTo(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return std::forward<decltype(self)>(self).timeToImpl(x, y, utc);
|
||||
return pz_duration_t{std::numeric_limits<double>::infinity()};
|
||||
}
|
||||
|
||||
// returns a time duration to exit from the zone
|
||||
// 0 - if given position (x,y) is out of the zone
|
||||
// Inf - if (x,y) is always within the zone
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_duration_t timeFrom(this auto&& self,
|
||||
const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
pz_duration_t timeFrom(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return std::forward<decltype(self)>(self).timeFromImpl(x, y, utc);
|
||||
return pz_duration_t{0.0};
|
||||
}
|
||||
|
||||
|
||||
// all-in-one request (call three methods above)
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_request_t request(const XT& x,
|
||||
pz_request_t request(this auto&& self,
|
||||
const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
pz_request_t res{.in_zone = false, .time_to = pz_duration_t{0.0}, .time_from{0.0}};
|
||||
|
||||
res.in_zone = inZone(x, y, utc);
|
||||
res.in_zone = std::forward<self_t>(self).inZone(x, y, utc);
|
||||
|
||||
if (res.in_zone) {
|
||||
res.time_from = timeFrom(x, y, utc);
|
||||
res.time_from = std::forward<self_t>(self).timeFrom(x, y, utc);
|
||||
} else {
|
||||
res.time_to = timeFrom(x, y, utc);
|
||||
res.time_to = std::forward<self_t>(self).timeTo(x, y, utc);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -95,30 +89,10 @@ protected:
|
||||
MccProhibitedZone(std::string_view name) : _name(name) {}
|
||||
|
||||
std::string_view _name;
|
||||
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
bool inZoneImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_duration_t timeToImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return pz_duration_t{std::numeric_limits<double>::infinity()};
|
||||
}
|
||||
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_duration_t timeFromImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return pz_duration_t{0.0};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* SOME PROHIBITED ZONE IMPLEMENTATIONS */
|
||||
|
||||
|
||||
@ -145,11 +119,8 @@ public:
|
||||
_altLimit.normalize<MccAngle::NORM_KIND_90_90>();
|
||||
}
|
||||
|
||||
private:
|
||||
MccAngle _altLimit;
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
bool inZoneImpl(const XT& x, const YT& y, traits::mcc_systime_c auto const& utc)
|
||||
bool inZone(const XT& x, const YT& y, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
{
|
||||
static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash<XT, YT>();
|
||||
|
||||
@ -160,7 +131,7 @@ private:
|
||||
return y >= _altLimit;
|
||||
}
|
||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZZD) { // trivial case
|
||||
return inZoneImpl(x, MccAngleALT(std::numbers::pi / 2 - (double)y), utc);
|
||||
return inZone(x, MccAngleALT(std::numbers::pi / 2 - (double)y), utc);
|
||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||
// implementation ...
|
||||
return false;
|
||||
@ -176,17 +147,25 @@ private:
|
||||
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_duration_t timeToImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
pz_duration_t timeTo(const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
{
|
||||
return pz_duration_t{std::numeric_limits<double>::infinity()};
|
||||
}
|
||||
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_duration_t timeFromImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
pz_duration_t timeFrom(const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
{
|
||||
return pz_duration_t{0.0};
|
||||
}
|
||||
|
||||
private:
|
||||
MccAngle _altLimit;
|
||||
};
|
||||
|
||||
|
||||
} // namespace mcc
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
|
||||
#include "../mcc_mount.h"
|
||||
#include "../mcc_mount_events_states.h"
|
||||
|
||||
@ -7,9 +9,12 @@ int tests_mount(int, char**)
|
||||
|
||||
using mount_t = MccMount<MccMountConfig<MccMountType::CROSSAXIS_TYPE>, MccMountTelemetry>;
|
||||
|
||||
mount_t mount(MccMountStateIDLE<mount_t>{});
|
||||
auto logger = spdlog::stdout_color_mt("MOUNT");
|
||||
logger->set_level(spdlog::level::debug);
|
||||
|
||||
mount_t mount(MccMountStateIDLE<mount_t>{}, logger);
|
||||
|
||||
mount.dispatchEvent(MccMountEventInit<mount_t>{mount});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user