diff --git a/development/ffsm2/detail/config.hpp b/development/ffsm2/detail/config.hpp new file mode 100644 index 0000000..283fb52 --- /dev/null +++ b/development/ffsm2/detail/config.hpp @@ -0,0 +1,161 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload +> +struct G_ final { + static constexpr FeatureTag FEATURE_TAG = NFeatureTag; + + using Context = TContext; + using Activation = TActivation; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using LoggerInterface = LoggerInterfaceT; +#endif + + static constexpr Short SUBSTITUTION_LIMIT = NSubstitutionLimit; + +#if FFSM2_PLANS_AVAILABLE() + static constexpr Long TASK_CAPACITY = NTaskCapacity; +#endif + + using Payload = TPayload; + using Transition = TransitionT; + +#if FFSM2_PLANS_AVAILABLE() + using Task = TaskT; +#endif + + /// @brief Set Context type + /// @tparam T Context type for data shared between states and/or data interface between FSM and external code + template + using ContextT = G_; + + /// @brief Select manual activation strategy + using ManualActivation = G_; + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + + /// @brief Set Substitution limit + /// @tparam N Maximum number times 'guard()' methods can substitute their states for others + template + using SubstitutionLimitN = G_; + +#if FFSM2_PLANS_AVAILABLE() + + /// @brief Set Task capacity + /// @tparam N Maximum number of tasks across all plans + template + using TaskCapacityN = G_; + +#endif + + /// @brief Set Transition Payload type + /// @tparam T Utility type for 'TUtility State::utility() const' method + template + using PayloadT = G_; +}; + +//////////////////////////////////////////////////////////////////////////////// + +template +struct M_; + +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload +> +struct M_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + > final +{ + using Cfg = G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + >; + + static constexpr FeatureTag FEATURE_TAG = NFeatureTag; + + using Context = TContext; + + using Payload = TPayload; + using Transition = TransitionT; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using LoggerInterface = typename Cfg::LoggerInterface; +#endif + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // COMMON + + /// @brief Root + /// @tparam THead Head state + /// @tparam TSubStates Sub-states + template + using Root = RF_>; + + /// @brief Headless root + /// @tparam TSubStates Sub-states + template < typename... TSubStates> + using PeerRoot = RF_>; + + // COMMON + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif +}; + +//////////////////////////////////////////////////////////////////////////////// + +} + +/// @brief Type configuration for MachineT<> +using Config = detail::G_< + FFSM2_FEATURE_TAG + , EmptyContext + , Automatic + , 4 + FFSM2_IF_PLANS(, INVALID_LONG) + , void + >; + +/// @brief 'Template namespace' for FSM classes +/// @tparam TConfig 'ConfigT<>' type configuration for MachineT<> +/// @see ConfigT<> +template +using MachineT = detail::M_; + +/// @brief 'Template namespace' for FSM classes parametrized with default types +using Machine = MachineT<>; + +//////////////////////////////////////////////////////////////////////////////// + +} diff --git a/development/ffsm2/detail/containers/array.hpp b/development/ffsm2/detail/containers/array.hpp index 00bacd3..b5b4124 100644 --- a/development/ffsm2/detail/containers/array.hpp +++ b/development/ffsm2/detail/containers/array.hpp @@ -81,13 +81,13 @@ struct StaticArrayT final { //////////////////////////////////////////////////////////////////////////////// template -class ArrayT final { +class DynamicArrayT final { template friend class IteratorT; public: - using Iterator = IteratorT< ArrayT>; - using CIterator = IteratorT; + using Iterator = IteratorT< DynamicArrayT>; + using CIterator = IteratorT; using Item = T; using Index = UCapacity; @@ -113,12 +113,12 @@ class ArrayT final { FFSM2_CONSTEXPR(11) bool empty() const noexcept { return _count == 0; } // SPECIFIC - FFSM2_CONSTEXPR(14) ArrayT& operator += (const Item & item) noexcept; - FFSM2_CONSTEXPR(14) ArrayT& operator += ( Item&& item) noexcept; + FFSM2_CONSTEXPR(14) DynamicArrayT& operator += (const Item & item) noexcept; + FFSM2_CONSTEXPR(14) DynamicArrayT& operator += ( Item&& item) noexcept; // SPECIFIC template - FFSM2_CONSTEXPR(14) ArrayT& operator += (const ArrayT& other) noexcept; + FFSM2_CONSTEXPR(14) DynamicArrayT& operator += (const DynamicArrayT& other) noexcept; FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator(*this, first()); } FFSM2_CONSTEXPR(11) CIterator begin() const noexcept { return CIterator(*this, first()); } @@ -141,7 +141,7 @@ class ArrayT final { //------------------------------------------------------------------------------ template -class ArrayT final { +class DynamicArrayT final { public: using Item = T; using Index = UCapacity<0>; diff --git a/development/ffsm2/detail/containers/array.inl b/development/ffsm2/detail/containers/array.inl index 0d1a815..4b90f84 100644 --- a/development/ffsm2/detail/containers/array.inl +++ b/development/ffsm2/detail/containers/array.inl @@ -3,11 +3,11 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// -template +template template FFSM2_CONSTEXPR(14) T& -StaticArrayT::operator[] (const N index) noexcept { +StaticArrayT::operator[] (const N index) noexcept { FFSM2_ASSERT(0 <= index && index < CAPACITY); return _items[static_cast(index)]; @@ -15,11 +15,11 @@ StaticArrayT::operator[] (const N index) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) const T& -StaticArrayT::operator[] (const N index) const noexcept { +StaticArrayT::operator[] (const N index) const noexcept { FFSM2_ASSERT(0 <= index && index < CAPACITY); return _items[static_cast(index)]; @@ -27,20 +27,20 @@ StaticArrayT::operator[] (const N index) const noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -StaticArrayT::fill(const Item filler) noexcept { +StaticArrayT::fill(const Item filler) noexcept { for (Item& item : _items) item = filler; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) bool -StaticArrayT::empty() const noexcept { +StaticArrayT::empty() const noexcept { for (const Item& item : _items) if (item != filler()) return false; @@ -50,11 +50,11 @@ StaticArrayT::empty() const noexcept { //////////////////////////////////////////////////////////////////////////////// -template +template template FFSM2_CONSTEXPR(14) -typename ArrayT::Index -ArrayT::emplace(const TArgs&... args) noexcept { +typename DynamicArrayT::Index +DynamicArrayT::emplace(const TArgs&... args) noexcept { FFSM2_ASSERT(_count < CAPACITY); new (&_items[_count]) Item{args...}; @@ -64,11 +64,11 @@ ArrayT::emplace(const TArgs&... args) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) -typename ArrayT::Index -ArrayT::emplace(TArgs&&... args) noexcept { +typename DynamicArrayT::Index +DynamicArrayT::emplace(TArgs&&... args) noexcept { FFSM2_ASSERT(_count < CAPACITY); new (&_items[_count]) Item{forward(args)...}; @@ -78,24 +78,24 @@ ArrayT::emplace(TArgs&&... args) noexcept { //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) -typename ArrayT::Item& -ArrayT::operator[] (const N index) noexcept { - FFSM2_ASSERT(0 <= index && index < CAPACITY); +typename DynamicArrayT::Item& +DynamicArrayT::operator[] (const N index) noexcept { + FFSM2_ASSERT(0 <= index && index < _count); return _items[static_cast(index)]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) -const typename ArrayT::Item& -ArrayT::operator[] (const N index) const noexcept { - FFSM2_ASSERT(0 <= index && index < CAPACITY); +const typename DynamicArrayT::Item& +DynamicArrayT::operator[] (const N index) const noexcept { + FFSM2_ASSERT(0 <= index && index < _count); return _items[static_cast(index)]; } @@ -103,10 +103,10 @@ ArrayT::operator[] (const N index) const noexcept { //------------------------------------------------------------------------------ // SPECIFIC -template +template FFSM2_CONSTEXPR(14) -ArrayT& -ArrayT::operator += (const Item& item) noexcept { +DynamicArrayT& +DynamicArrayT::operator += (const Item& item) noexcept { emplace(item); return *this; @@ -114,10 +114,10 @@ ArrayT::operator += (const Item& item) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) -ArrayT& -ArrayT::operator += (Item&& item) noexcept { +DynamicArrayT& +DynamicArrayT::operator += (Item&& item) noexcept { emplace(move(item)); return *this; @@ -126,11 +126,11 @@ ArrayT::operator += (Item&& item) noexcept { // SPECIFIC // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) -ArrayT& -ArrayT::operator += (const ArrayT& other) noexcept { +DynamicArrayT& +DynamicArrayT::operator += (const DynamicArrayT& other) noexcept { for (const auto& item : other) emplace(item); diff --git a/development/ffsm2/detail/containers/bit_array.hpp b/development/ffsm2/detail/containers/bit_array.hpp index 8ba8999..e47274a 100644 --- a/development/ffsm2/detail/containers/bit_array.hpp +++ b/development/ffsm2/detail/containers/bit_array.hpp @@ -8,7 +8,7 @@ namespace detail { template class BitArrayT final { public: - using Index = UCapacity; + using Index = UCapacity; static constexpr Index CAPACITY = NCapacity; static constexpr Index UNIT_COUNT = contain(CAPACITY, 8); diff --git a/development/ffsm2/detail/containers/bit_array.inl b/development/ffsm2/detail/containers/bit_array.inl index 6094042..cbbe897 100644 --- a/development/ffsm2/detail/containers/bit_array.inl +++ b/development/ffsm2/detail/containers/bit_array.inl @@ -17,30 +17,30 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// // COMMON -template +template FFSM2_CONSTEXPR(14) void -BitArrayT::set() noexcept { +BitArrayT::set() noexcept { for (uint8_t& unit : _storage) unit = UINT8_MAX; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -BitArrayT::clear() noexcept { +BitArrayT::clear() noexcept { for (uint8_t& unit : _storage) unit = uint8_t{0}; } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) bool -BitArrayT::empty() const noexcept { +BitArrayT::empty() const noexcept { for (const uint8_t& unit : _storage) if (unit != uint8_t{0}) return false; @@ -53,11 +53,11 @@ BitArrayT::empty() const noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) bool -BitArrayT::get(const TIndex index) const noexcept { +BitArrayT::get(const TIndex index) const noexcept { FFSM2_ASSERT(index < CAPACITY); const Index unit = static_cast(index) / 8; @@ -69,11 +69,11 @@ BitArrayT::get(const TIndex index) const noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) void -BitArrayT::set(const TIndex index) noexcept { +BitArrayT::set(const TIndex index) noexcept { FFSM2_ASSERT(index < CAPACITY); const Index unit = static_cast(index) / 8; @@ -85,11 +85,11 @@ BitArrayT::set(const TIndex index) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) void -BitArrayT::clear(const TIndex index) noexcept { +BitArrayT::clear(const TIndex index) noexcept { FFSM2_ASSERT(index < CAPACITY); const Index unit = static_cast(index) / 8; @@ -101,10 +101,10 @@ BitArrayT::clear(const TIndex index) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) bool -BitArrayT::operator & (const BitArray& other) const noexcept { +BitArrayT::operator & (const BitArray& other) const noexcept { for (Index i = 0; i < UNIT_COUNT; ++i) if ((_storage[i] & other._storage[i]) == 0) return false; @@ -114,10 +114,10 @@ BitArrayT::operator & (const BitArray& other) const noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -BitArrayT::operator &= (const BitArray& other) noexcept { +BitArrayT::operator &= (const BitArray& other) noexcept { for (Index i = 0; i < UNIT_COUNT; ++i) _storage[i] &= other._storage[i]; } diff --git a/development/ffsm2/detail/features/logger_interface.hpp b/development/ffsm2/detail/features/logger_interface.hpp index ec5418e..ce20492 100644 --- a/development/ffsm2/detail/features/logger_interface.hpp +++ b/development/ffsm2/detail/features/logger_interface.hpp @@ -1,11 +1,17 @@ namespace ffsm2 { +//------------------------------------------------------------------------------ + +struct FFSM2_EMPTY_BASES EmptyContext {}; + #if FFSM2_LOG_INTERFACE_AVAILABLE() //////////////////////////////////////////////////////////////////////////////// -template +template < + FeatureTag NFeatureTag = FFSM2_FEATURE_TAG + , typename TContext = EmptyContext +> struct LoggerInterfaceT { using Context = TContext; @@ -64,8 +70,10 @@ struct LoggerInterfaceT { #else -template +template < + FeatureTag NFeatureTag = FFSM2_FEATURE_TAG + , typename TContext = EmptyContext +> using LoggerInterfaceT = void; #endif diff --git a/development/ffsm2/detail/containers/task_list.hpp b/development/ffsm2/detail/features/task.hpp similarity index 66% rename from development/ffsm2/detail/containers/task_list.hpp rename to development/ffsm2/detail/features/task.hpp index 6a524ec..8fb34f5 100644 --- a/development/ffsm2/detail/containers/task_list.hpp +++ b/development/ffsm2/detail/features/task.hpp @@ -108,53 +108,7 @@ struct TaskT final //////////////////////////////////////////////////////////////////////////////// -template -class TaskListT { -public: - using Index = Long; - - static constexpr Index CAPACITY = NCapacity; - static constexpr Index INVALID = Index (-1); - -private: - using Payload = TPayload; - using Item = TaskT; - -public: - FFSM2_CONSTEXPR(14) void clear() noexcept; - - template - FFSM2_CONSTEXPR(14) Index emplace(TArgs&&... args) noexcept; - - FFSM2_CONSTEXPR(14) void remove(const Index i) noexcept; - - FFSM2_CONSTEXPR(14) Item& operator[] (const Index i) noexcept; - FFSM2_CONSTEXPR(11) const Item& operator[] (const Index i) const noexcept; - - FFSM2_CONSTEXPR(11) Index count() const noexcept { return _count; } - FFSM2_CONSTEXPR(11) bool empty() const noexcept { return _count == 0; } - -private: - FFSM2_IF_ASSERT(void verifyStructure(const Index occupied = INVALID) const noexcept); - -private: - Index _vacantHead = 0; - Index _vacantTail = 0; - Index _last = 0; - Index _count = 0; - Item _items[CAPACITY] {}; -}; - -//------------------------------------------------------------------------------ - -template -class TaskListT {}; - -//////////////////////////////////////////////////////////////////////////////// - } } -#include "task_list.inl" - #endif diff --git a/development/ffsm2/detail/features/task_list.hpp b/development/ffsm2/detail/features/task_list.hpp new file mode 100644 index 0000000..51950a1 --- /dev/null +++ b/development/ffsm2/detail/features/task_list.hpp @@ -0,0 +1,57 @@ +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class TaskListT { +public: + using Index = Long; + + static constexpr Index CAPACITY = NCapacity; + static constexpr Index INVALID = Index (-1); + +private: + using Payload = TPayload; + using Item = TaskT; + +public: + FFSM2_CONSTEXPR(14) void clear() noexcept; + + template + FFSM2_CONSTEXPR(14) Index emplace(TArgs&&... args) noexcept; + + FFSM2_CONSTEXPR(14) void remove(const Index i) noexcept; + + FFSM2_CONSTEXPR(14) Item& operator[] (const Index i) noexcept; + FFSM2_CONSTEXPR(11) const Item& operator[] (const Index i) const noexcept; + + FFSM2_CONSTEXPR(11) Index count() const noexcept { return _count; } + FFSM2_CONSTEXPR(11) bool empty() const noexcept { return _count == 0; } + +private: + FFSM2_IF_ASSERT(void verifyStructure(const Index occupied = INVALID) const noexcept); + +private: + Index _vacantHead = 0; + Index _vacantTail = 0; + Index _last = 0; + Index _count = 0; + Item _items[CAPACITY] {}; +}; + +//------------------------------------------------------------------------------ + +template +class TaskListT {}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "task_list.inl" + +#endif diff --git a/development/ffsm2/detail/containers/task_list.inl b/development/ffsm2/detail/features/task_list.inl similarity index 82% rename from development/ffsm2/detail/containers/task_list.inl rename to development/ffsm2/detail/features/task_list.inl index 7a749d3..6e59760 100644 --- a/development/ffsm2/detail/containers/task_list.inl +++ b/development/ffsm2/detail/features/task_list.inl @@ -5,10 +5,10 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// -template +template FFSM2_CONSTEXPR(14) void -TaskListT::clear() noexcept { +TaskListT::clear() noexcept { _vacantHead = 0; _vacantTail = 0; _last = 0; @@ -17,11 +17,11 @@ TaskListT::clear() noexcept { //------------------------------------------------------------------------------ -template -template +template +template FFSM2_CONSTEXPR(14) Long -TaskListT::emplace(TA&&... args) noexcept { +TaskListT::emplace(TA_&&... args) noexcept { FFSM2_ASSERT(_last <= CAPACITY); if (_count < CAPACITY) { @@ -59,7 +59,7 @@ TaskListT::emplace(TA&&... args) noexcept { _vacantTail = INVALID; } - new (&item) Item{forward(args)...}; + new (&item) Item{forward(args)...}; ++_count; FFSM2_IF_ASSERT(verifyStructure()); @@ -78,10 +78,10 @@ TaskListT::emplace(TA&&... args) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -TaskListT::remove(const Index i) noexcept { +TaskListT::remove(const Index i) noexcept { FFSM2_ASSERT(i < CAPACITY && _count); Item& item = _items[i]; @@ -117,10 +117,10 @@ TaskListT::remove(const Index i) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) -typename TaskListT::Item& -TaskListT::operator[] (const Index i) noexcept { +typename TaskListT::Item& +TaskListT::operator[] (const Index i) noexcept { FFSM2_IF_ASSERT(verifyStructure()); return _items[i]; @@ -128,10 +128,10 @@ TaskListT::operator[] (const Index i) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(11) -const typename TaskListT::Item& -TaskListT::operator[] (const Index i) const noexcept { +const typename TaskListT::Item& +TaskListT::operator[] (const Index i) const noexcept { FFSM2_IF_ASSERT(verifyStructure()); return _items[i]; @@ -141,9 +141,9 @@ TaskListT::operator[] (const Index i) const noexcept { #if FFSM2_ASSERT_AVAILABLE() -template +template void -TaskListT::verifyStructure(const Index occupied) const noexcept { +TaskListT::verifyStructure(const Index occupied) const noexcept { if (_count < CAPACITY) { FFSM2_ASSERT(_vacantHead < CAPACITY); FFSM2_ASSERT(_vacantTail < CAPACITY); diff --git a/development/ffsm2/detail/features/common.hpp b/development/ffsm2/detail/features/transition.hpp similarity index 90% rename from development/ffsm2/detail/features/common.hpp rename to development/ffsm2/detail/features/transition.hpp index 7e14c9b..b0e72a8 100644 --- a/development/ffsm2/detail/features/common.hpp +++ b/development/ffsm2/detail/features/transition.hpp @@ -18,14 +18,16 @@ enum class Method : uint8_t { EXIT_GUARD, EXIT, -#if FFSM2_PLANS_AVAILABLE() +//#if FFSM2_PLANS_AVAILABLE() PLAN_SUCCEEDED, PLAN_FAILED, -#endif +//#endif COUNT }; +//------------------------------------------------------------------------------ + #if FFSM2_PLANS_AVAILABLE() enum class StatusEvent : uint8_t { @@ -39,37 +41,6 @@ enum class StatusEvent : uint8_t { //------------------------------------------------------------------------------ -#if FFSM2_TYPEINDEX_AVAILABLE() - -static -inline -const char* -stateName(const std::type_index stateType) noexcept { - const char* const raw = stateType.name(); - - #if defined(_MSC_VER) - - Short first = - raw[0] == 's' ? 7 : // Struct - raw[0] == 'c' ? 6 : // Class - 0; - return raw + first; - - #elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - - return raw; - - #else - - return raw; - - #endif -} - -#endif - -//------------------------------------------------------------------------------ - static FFSM2_CONSTEXPR(14) const char* @@ -88,10 +59,10 @@ methodName(const Method method) noexcept { case Method::EXIT_GUARD: return "exitGuard"; case Method::EXIT: return "exit"; -#if FFSM2_PLANS_AVAILABLE() +//#if FFSM2_PLANS_AVAILABLE() case Method::PLAN_SUCCEEDED: return "planSucceeded"; case Method::PLAN_FAILED: return "planFailed"; -#endif +//#endif default: FFSM2_BREAK(); @@ -99,7 +70,6 @@ methodName(const Method method) noexcept { } } -//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ namespace detail { @@ -115,7 +85,7 @@ namespace detail { struct TransitionBase { FFSM2_CONSTEXPR(11) - TransitionBase() noexcept = default; + TransitionBase() noexcept = default; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/development/ffsm2/detail/root.hpp b/development/ffsm2/detail/root.hpp deleted file mode 100644 index f250be0..0000000 --- a/development/ffsm2/detail/root.hpp +++ /dev/null @@ -1,729 +0,0 @@ -namespace ffsm2 { -namespace detail { - -//////////////////////////////////////////////////////////////////////////////// - -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class R_ { -public: - static constexpr FeatureTag FEATURE_TAG = TConfig::FEATURE_TAG; - - using Context = typename TConfig::Context; - using Payload = typename TConfig::Payload; - -protected: - using Forward = RF_; - using StateList = typename Forward::StateList; - - using Args = typename Forward::Args; - using PureContext = typename Args::PureContext; - - static_assert(Args::STATE_COUNT < static_cast(-1), "Too many states in the FSM. Change 'Short' type."); - static_assert(Args::STATE_COUNT == static_cast(StateList::SIZE), "STATE_COUNT != StateList::SIZE"); - - using Core = CoreT; - - using Apex = MaterialT<0, Args, TApex>; - - using ConstControl = ConstControlT; - using Control = ControlT ; - using PlanControl = PlanControlT ; - using FullControl = FullControlT ; - using GuardControl = GuardControlT; - - static constexpr Long SUBSTITUTION_LIMIT = Forward::SUBSTITUTION_LIMIT; - -#if FFSM2_PLANS_AVAILABLE() - using PlanData = PlanDataT; -#endif - -#if FFSM2_SERIALIZATION_AVAILABLE() - using WriteStream = typename Args::WriteStream; - using ReadStream = typename Args::ReadStream; -#endif - -public: - /// @brief Transition - using Transition = typename Core::Transition; - -#if FFSM2_PLANS_AVAILABLE() - using CPlan = CPlanT; - using Plan = PlanT; - - static constexpr Long TASK_CAPACITY = Forward::TASK_CAPACITY; -#endif - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using Logger = typename TConfig::LoggerInterface; -#endif - -public: - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(11) explicit R_(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; - - FFSM2_CONSTEXPR(11) explicit R_(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; - - FFSM2_CONSTEXPR(NO) R_(const R_& ) noexcept = default; - FFSM2_CONSTEXPR(NO) R_( R_&&) noexcept = default; - - FFSM2_CONSTEXPR(20) ~R_() noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Access context - /// @return context - FFSM2_CONSTEXPR(14) Context& context() noexcept { return _core.context; } - - /// @brief Access context - /// @return context - FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Get state identifier for a state type - /// @tparam TState State type - /// @return Numeric state identifier - template - static constexpr StateID stateId() noexcept { return index(); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Access state instance - /// @tparam TState State type - /// @return State instance - template - FFSM2_CONSTEXPR(14) TState& access() noexcept { return static_cast< TState&>(_apex); } - - /// @brief Access state instance - /// @tparam TState State type - /// @return State instance - template - FFSM2_CONSTEXPR(11) const TState& access() const noexcept { return static_cast(_apex); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Trigger FSM update cycle (recursively call 'update()' from the root down to the leaf states, - /// on all active states, then process requested transitions) - FFSM2_CONSTEXPR(14) void update() noexcept; - - /// @brief Have FSM react to an event (recursively call matching 'react<>()' from the root down to the leaf states, - /// on all active states, then process requested transitions) - /// @tparam TEvent Event type - /// @param event Event to react to - template - FFSM2_CONSTEXPR(14) void react(const TEvent& event) noexcept; - - /// @brief Recursively call 'query()' from the root down to the leaf states, on all active states - /// @tparam TEvent Event type - /// @param event Event to react to - template - FFSM2_CONSTEXPR(14) void query(TEvent& event) const noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Get current active state ID - /// @return Current active state ID - FFSM2_CONSTEXPR(11) StateID activeStateId() const noexcept { return _core.registry.active; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Check if a state is active - /// @param stateId Destination state identifier - /// @return State active status - FFSM2_CONSTEXPR(11) bool isActive(const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } - - /// @brief Check if a state is active - /// @tparam TState Destination state type - /// @return State active status - template - FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return _core.registry.active == stateId(); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_PLANS_AVAILABLE() - - /// @brief Access plan - /// @return Plan - FFSM2_CONSTEXPR(14) Plan plan() noexcept { return Plan{_core.planData}; } - - /// @brief Access read-only plan - /// @return Read-only plan - FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } - - /// @brief Succeed a plan task for a state - /// @param stateId state ID - FFSM2_CONSTEXPR(14) void succeed(const StateID stateId_) noexcept; - - /// @brief Succeed a plan task for a state - /// @tparam TState state type - template - FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed(stateId()); } - - /// @brief Fail a plan task for a state - /// @param stateId state ID - FFSM2_CONSTEXPR(14) void fail (const StateID stateId_) noexcept; - - /// @brief Fail a plan task for a state - /// @tparam TState state type - template - FFSM2_CONSTEXPR(14) void fail () noexcept { fail (stateId()); } - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON - - /// @brief Queue a transition into a state (takes effect during immediate*(), update() or react()) - /// @param stateId Destination state identifier - FFSM2_CONSTEXPR(14) void changeTo (const StateID stateId_) noexcept; - - /// @brief Queue a transition into a state (takes effect during immediate*(), update() or react()) - /// @tparam TState Destination state type - template - FFSM2_CONSTEXPR(14) void changeTo () noexcept { changeTo (stateId()); } - - // COMMON - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_UTILITY_THEORY_AVAILABLE() - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#endif - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON - - /// @brief Transition into a state - /// (if transitioning into a region, acts depending on the region type) - /// @param stateId Destination state identifier - FFSM2_CONSTEXPR(14) void immediateChangeTo (const StateID stateId_) noexcept; - - /// @brief Transition into a state (if transitioning into a region, acts depending on the region type) - /// @tparam TState Destination state type - template - FFSM2_CONSTEXPR(14) void immediateChangeTo () noexcept { immediateChangeTo (stateId()); } - - // COMMON - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - - /// @brief Get the transition recorded during last 'update()' / 'react()' - /// @return Array of last recorded transitions - /// @see FFSM2_ENABLE_TRANSITION_HISTORY - FFSM2_CONSTEXPR(11) const Transition& previousTransition() const noexcept { return _core.previousTransition; } - - /// @brief Force process a transition (skips 'guard()' calls) - /// Can be used to synchronize multiple FSMs - /// @param destination Transition destination - /// @return Success status - /// @see FFSM2_ENABLE_TRANSITION_HISTORY - FFSM2_CONSTEXPR(14) bool replayTransition(const StateID destination) noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - - /// @brief Attach logger - /// @param logger A logger implementing 'ffsm2::LoggerInterfaceT<>' interface - /// @see FFSM2_ENABLE_LOG_INTERFACE - FFSM2_CONSTEXPR(14) void attachLogger(Logger* const logger) noexcept { _core.logger = logger; } - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -protected: - FFSM2_CONSTEXPR(14) void initialEnter() noexcept; - FFSM2_CONSTEXPR(14) void finalExit() noexcept; - - FFSM2_CONSTEXPR(14) void processRequest() noexcept; - FFSM2_CONSTEXPR(14) void processTransitions(Transition& currentTransition) noexcept; - - FFSM2_CONSTEXPR(14) bool applyRequest(const Transition& currentTransition, - const StateID destination) noexcept; - - FFSM2_CONSTEXPR(14) bool cancelledByEntryGuards(const Transition& currentTransition, - const Transition& pendingTransition) noexcept; - - FFSM2_CONSTEXPR(14) bool cancelledByGuards(const Transition& currentTransition, - const Transition& pendingTransition) noexcept; - -#if FFSM2_SERIALIZATION_AVAILABLE() - FFSM2_CONSTEXPR(14) void save(WriteStream& stream) const noexcept; - FFSM2_CONSTEXPR(14) void load( ReadStream& stream) noexcept; -#endif - -protected: - Core _core; - Apex _apex; -}; - -//////////////////////////////////////////////////////////////////////////////// - -// Automatic / manual [de]activation - -template -class RV_; - -//------------------------------------------------------------------------------ -// Automatic enter() / exit() - -template -class RV_ , TApex> - : public R_, TApex> -{ - using Base = R_, TApex>; - -protected: - using typename Base::Context; - using typename Base::PureContext; - -#if FFSM2_SERIALIZATION_AVAILABLE() - using typename Base::Args; - using typename Base::WriteStream; - using typename Base::ReadStream; -#endif - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; -#endif - -public: - FFSM2_CONSTEXPR(14) explicit RV_(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; - - FFSM2_CONSTEXPR(14) explicit RV_(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; - - FFSM2_CONSTEXPR(14) RV_(const RV_& other) noexcept; - FFSM2_CONSTEXPR(14) RV_( RV_&& other) noexcept; - - FFSM2_CONSTEXPR(20) ~RV_() noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_SERIALIZATION_AVAILABLE() - - /// @brief Buffer for serialization - /// @see `FFSM2_ENABLE_SERIALIZATION` - using SerialBuffer = typename Args::SerialBuffer; - - /// @brief Serialize FSM into 'buffer' - /// @param buffer `SerialBuffer` to serialize to - /// @see `FFSM2_ENABLE_SERIALIZATION` - FFSM2_CONSTEXPR(14) void save( SerialBuffer& buffer) const noexcept; - - /// @brief De-serialize FSM from 'buffer' - /// @param buffer `SerialBuffer` to de-serialize from - /// @see `FFSM2_ENABLE_SERIALIZATION` - FFSM2_CONSTEXPR(14) void load(const SerialBuffer& buffer) noexcept; - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -private: -#if FFSM2_SERIALIZATION_AVAILABLE() - using Base::save; - using Base::load; -#endif - -private: - using Base::initialEnter; - using Base::finalExit; - -protected: -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - using Base::_core; - using Base::_apex; -#endif -}; - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Manual enter() / exit() - -template -class RV_ , TApex> - : public R_, TApex> -{ - using Base = R_, TApex>; - -protected: -#if FFSM2_SERIALIZATION_AVAILABLE() - using typename Base::PlanControl; - - using typename Base::Args; - using typename Base::WriteStream; - using typename Base::ReadStream; -#endif - -public: - using typename Base::Transition; - -private: -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - using typename Base::PlanControl; -#endif - -public: - using Base::Base; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Check if FSM is active - /// @return FSM active status - FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return _core.registry.isActive(); } - - using Base::isActive; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Manually start the FSM - /// Can be used with UE4 to start / stop the FSM in BeginPlay() / EndPlay() - FFSM2_CONSTEXPR(14) void enter() noexcept { initialEnter(); } - - /// @brief Manually stop the FSM - /// Can be used with UE4 to start / stop the FSM in BeginPlay() / EndPlay() - FFSM2_CONSTEXPR(14) void exit() noexcept { finalExit(); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_SERIALIZATION_AVAILABLE() - - /// @brief Buffer for serialization - /// @see `FFSM2_ENABLE_SERIALIZATION` - using SerialBuffer = typename Args::SerialBuffer; - - /// @brief Serialize FSM into 'buffer' - /// @param buffer `SerialBuffer` to serialize to - /// @see `FFSM2_ENABLE_SERIALIZATION` - FFSM2_CONSTEXPR(14) void save( SerialBuffer& buffer) const noexcept; - - /// @brief De-serialize FSM from 'buffer' - /// @param buffer `SerialBuffer` to de-serialize from - /// @see `FFSM2_ENABLE_SERIALIZATION` - FFSM2_CONSTEXPR(14) void load(const SerialBuffer& buffer) noexcept; - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - - /// @brief Start the FSM from a specific state - /// Can be used with UE4 USTRUCT() NetSerialize() to load replicated FSM from FArchive - /// @param destination Transition destination - /// @see FFSM2_ENABLE_TRANSITION_HISTORY - FFSM2_CONSTEXPR(14) void replayEnter(const StateID destination) noexcept; - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -private: -#if FFSM2_SERIALIZATION_AVAILABLE() - using Base::save; - using Base::load; - - FFSM2_CONSTEXPR(14) void loadEnter(ReadStream& stream) noexcept; -#endif - -protected: - using Base::initialEnter; - using Base::finalExit; - - using Base::_core; - -#if FFSM2_SERIALIZATION_AVAILABLE() || FFSM2_TRANSITION_HISTORY_AVAILABLE() - using Base::_apex; -#endif - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - using Base::applyRequest; -#endif -}; - -//////////////////////////////////////////////////////////////////////////////// - -template -class RP_; - -//------------------------------------------------------------------------------ -// Non-'void' payloads - -template -class RP_ , TApex> - : public RV_, TApex> -{ - using Base = RV_, TApex>; - - using Transition = TransitionT; - -public: - using typename Base::Payload; - -public: - using Base::Base; - using Base::processRequest; - - /// @brief Get state identifier for a state type - /// @tparam TState State type - /// @return Numeric state identifier - template - static constexpr StateID stateId() noexcept { return Base::template stateId(); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON - - /// @brief Transition into a state - /// @param stateId Destination state identifier - /// @param payload Payload - FFSM2_CONSTEXPR(14) void changeWith (const StateID stateId_, - const Payload& payload) noexcept; - - /// @brief Transition into a state - /// @tparam TState Destination state type - /// @param payload Payload - template - FFSM2_CONSTEXPR(14) void changeWith (const Payload& payload) noexcept { changeWith(stateId(), payload ); } - - // COMMON - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON - - /// @brief Transition into a state (if transitioning into a region, acts depending on the region type) - /// @param stateId Destination state identifier - /// @param payload Payload - FFSM2_CONSTEXPR(14) void immediateChangeWith (const StateID stateId_, - const Payload& payload) noexcept; - - /// @brief Transition into a state (if transitioning into a region, acts depending on the region type) - /// @tparam TState Destination state type - /// @param payload Payload - template - FFSM2_CONSTEXPR(14) void immediateChangeWith (const Payload& payload) noexcept { immediateChangeWith (stateId(), payload ); } - - // COMMON - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_UTILITY_THEORY_AVAILABLE() - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -protected: - using Base::_core; -}; - -//------------------------------------------------------------------------------ - -template -class RP_ , TApex> - : public RV_, TApex> -{ - using Base = RV_, TApex>; - -public: - using Base::Base; -}; - -//////////////////////////////////////////////////////////////////////////////// - -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class InstanceT; - -//------------------------------------------------------------------------------ -// TContext - -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class InstanceT , TApex> final - : public RP_, TApex> -{ - using Base = RP_, TApex>; - -public: - static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; - - using typename Base::Context; - using typename Base::PureContext; - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; -#endif - -public: - FFSM2_CONSTEXPR(11) explicit InstanceT(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; - - FFSM2_CONSTEXPR(11) explicit InstanceT(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; - - FFSM2_CONSTEXPR(NO) InstanceT(const InstanceT& ) noexcept = default; - FFSM2_CONSTEXPR(NO) InstanceT( InstanceT&&) noexcept = default; - -private: - using Base::_core; -}; - -//------------------------------------------------------------------------------ -// TContext& - -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class InstanceT , TApex> final - : public RP_, TApex> -{ - using Base = RP_, TApex>; - -public: - static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; - - using typename Base::Context; - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; -#endif - -public: - using Base::Base; - -private: - using Base::_core; -}; - -//------------------------------------------------------------------------------ -// TContext* - -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class InstanceT , TApex> final - : public RP_, TApex> -{ - using Base = RP_, TApex>; - -public: - static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; - - using typename Base::Context; - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; -#endif - -public: - FFSM2_CONSTEXPR(11) explicit InstanceT(Context context = nullptr - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; - - FFSM2_CONSTEXPR(NO) InstanceT(const InstanceT& ) noexcept = default; - FFSM2_CONSTEXPR(NO) InstanceT( InstanceT&&) noexcept = default; - - FFSM2_CONSTEXPR(14) void setContext(Context context) noexcept { _core.context = context; } - -private: - using Base::_core; -}; - -//------------------------------------------------------------------------------ -// TContext == EmptyContext - -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class FFSM2_EMPTY_BASES InstanceT, TApex> final - : public RP_, TApex> - , EmptyContext -{ - using Base = RP_, TApex>; - -public: - static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; -#endif - -public: - FFSM2_CONSTEXPR(11) explicit InstanceT(FFSM2_IF_LOG_INTERFACE(Logger* const logger = nullptr)) noexcept; - - using Base::Base; -}; - -//////////////////////////////////////////////////////////////////////////////// - -} -} - -#include "root.inl" diff --git a/development/ffsm2/detail/root.inl b/development/ffsm2/detail/root.inl deleted file mode 100644 index 4147235..0000000 --- a/development/ffsm2/detail/root.inl +++ /dev/null @@ -1,690 +0,0 @@ -namespace ffsm2 { -namespace detail { - -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(11) -R_::R_(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept - : _core{context - FFSM2_IF_LOG_INTERFACE(, logger)} -{} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(11) -R_::R_(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept - : _core{move(context) - FFSM2_IF_LOG_INTERFACE(, logger)} -{} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(20) -R_::~R_() noexcept { - FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -void -R_::update() noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - - Transition emptyTransition; - FullControl control{_core, emptyTransition}; - - _apex. deepPreUpdate(control); - _apex. deepUpdate(control); - _apex.deepPostUpdate(control); - -#if FFSM2_PLANS_AVAILABLE() - _apex.deepUpdatePlans(control); - _core.planData.clearRegionStatuses(); -#endif - - processRequest(); -} - -//------------------------------------------------------------------------------ - -template -template -FFSM2_CONSTEXPR(14) -void -R_::react(const TEvent& event) noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - - Transition emptyTransition; - FullControl control{_core, emptyTransition}; - - _apex. deepPreReact(control, event); - _apex. deepReact(control, event); - _apex.deepPostReact(control, event); - -#if FFSM2_PLANS_AVAILABLE() - _apex.deepUpdatePlans(control); - _core.planData.clearRegionStatuses(); -#endif - - processRequest(); -} - -//------------------------------------------------------------------------------ - -template -template -FFSM2_CONSTEXPR(14) -void -R_::query(TEvent& event) const noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - - ConstControl control{_core}; - - _apex.deepQuery(control, event); -} - -//------------------------------------------------------------------------------ - -#if FFSM2_PLANS_AVAILABLE() - -template -FFSM2_CONSTEXPR(14) -void -R_::succeed(const StateID stateId_) noexcept { - _core.planData.tasksSuccesses.set(stateId_); - - FFSM2_LOG_TASK_STATUS(_core.context, stateId_, StatusEvent::SUCCEEDED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -void -R_::fail(const StateID stateId_) noexcept { - _core.planData.tasksFailures.set(stateId_); - - FFSM2_LOG_TASK_STATUS(_core.context, stateId_, StatusEvent::FAILED); -} - -#endif - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -void -R_::changeTo(const StateID stateId_) noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - - _core.request = Transition{stateId_}; - - FFSM2_LOG_TRANSITION(_core.context, INVALID_STATE_ID, stateId_); -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -void -R_::immediateChangeTo(const StateID stateId_) noexcept { - changeTo(stateId_); - - processRequest(); -} - -//------------------------------------------------------------------------------ - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - -template -FFSM2_CONSTEXPR(14) -bool -R_::replayTransition(const StateID destination) noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - - _core.previousTransition.clear(); - - if (FFSM2_CHECKED(destination != INVALID_SHORT)) { - Transition currentTransition; - PlanControl control{_core, currentTransition}; - - applyRequest(currentTransition, - destination); - - _core.previousTransition = Transition{destination}; - - _apex.deepChangeToRequested(control); - - _core.registry.clearRequests(); - - FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); - - return true; - } - - return false; -} - -#endif - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -void -R_::initialEnter() noexcept { - FFSM2_ASSERT(!_core.registry.isActive()); - FFSM2_ASSERT(!_core.request); - FFSM2_IF_TRANSITION_HISTORY(FFSM2_ASSERT(!_core.previousTransition)); - - Transition currentTransition; - Transition pendingTransition; - - PlanControl control{_core, currentTransition}; - applyRequest(currentTransition, 0); - - cancelledByEntryGuards(currentTransition, - pendingTransition); - - for (Long i = 0; - i < SUBSTITUTION_LIMIT && _core.request; - ++i) - { - //backup(); - - if (applyRequest(currentTransition, - _core.request.destination)) - { - pendingTransition = _core.request; - _core.request.clear(); - - if (cancelledByEntryGuards(currentTransition, - pendingTransition)) - FFSM2_BREAK(); - else - currentTransition = pendingTransition; - - pendingTransition.clear(); - } else - _core.request.clear(); - } - FFSM2_ASSERT(!_core.request); - FFSM2_IF_TRANSITION_HISTORY(_core.previousTransition = currentTransition); - - _apex.deepEnter(control); - - _core.registry.clearRequests(); - - FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -void -R_::finalExit() noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - FFSM2_ASSERT(!_core.request); - - Transition emptyTransition; - PlanControl control{_core, emptyTransition}; - - _apex.deepExit(control); - - _core.registry.clear(); - _core.request .clear(); - -#if FFSM2_PLANS_AVAILABLE() - _core.planData.clear(); -#endif - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - _core.previousTransition.clear(); -#endif -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -void -R_::processRequest() noexcept { - FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); - - Transition currentTransition; - - if (_core.request) { - processTransitions(currentTransition); - - FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); - } - - FFSM2_IF_TRANSITION_HISTORY(_core.previousTransition = currentTransition); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -void -R_::processTransitions(Transition& currentTransition) noexcept { - FFSM2_ASSERT(_core.request); - - PlanControl control{_core, currentTransition}; - - Transition pendingTransition; - - for (Long i = 0; - i < SUBSTITUTION_LIMIT && _core.request; - ++i) - { - //backup(); - - if (applyRequest(currentTransition, - _core.request.destination)) - { - pendingTransition = _core.request; - _core.request.clear(); - - if (cancelledByGuards(currentTransition, - pendingTransition)) - ; - else - currentTransition = pendingTransition; - - pendingTransition.clear(); - } else - _core.request.clear(); - } - FFSM2_ASSERT(!_core.request); - - if (currentTransition) - _apex.deepChangeToRequested(control); - - _core.registry.clearRequests(); -} - -// COMMON -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -bool -R_::applyRequest(const Transition& currentTransition, - const StateID destination) noexcept -{ - if (currentTransition != Transition{destination}) { - _core.registry.requested = destination; - - return true; - } else - return false; -} - -//------------------------------------------------------------------------------ -// COMMON - -template -FFSM2_CONSTEXPR(14) -bool -R_::cancelledByEntryGuards(const Transition& currentTransition, - const Transition& pendingTransition) noexcept -{ - GuardControl guardControl{_core - , currentTransition - , pendingTransition}; - - return _apex.deepEntryGuard(guardControl); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -bool -R_::cancelledByGuards(const Transition& currentTransition, - const Transition& pendingTransition) noexcept -{ - GuardControl guardControl{_core - , currentTransition - , pendingTransition}; - - return _apex.deepForwardExitGuard (guardControl) || - _apex.deepForwardEntryGuard(guardControl); -} - -//------------------------------------------------------------------------------ - -#if FFSM2_SERIALIZATION_AVAILABLE() - -template -FFSM2_CONSTEXPR(14) -void -R_::save(WriteStream& stream) const noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - - _apex.deepSaveActive(_core.registry, stream); - - // TODO: save(stream, _core.requests); - -#if FFSM2_PLANS_AVAILABLE() - // TODO: save(stream, _core.planData); -#endif - -#if FFSM2_UTILITY_THEORY_AVAILABLE() - // TODO: save(stream, _core.rng); -#endif - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - // TODO: save(stream, _core.transitionTarget); - // TODO: save(stream, _core.previousTransition); -#endif -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -void -R_::load(ReadStream& stream) noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - - _core.registry.clearRequests(); - _apex.deepLoadRequested(_core.registry, stream); - - _core.request.clear(); - // TODO: load(stream, _core.requests); - -#if FFSM2_PLANS_AVAILABLE() - _core.planData.clear(); - // TODO: load(stream, _core.planData); -#endif - -#if FFSM2_UTILITY_THEORY_AVAILABLE() - // TODO: load(stream, _core.rng); -#endif - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - _core.previousTransition.clear(); -#endif - - Transition emptyTransition; - PlanControl control{_core, emptyTransition}; - - _apex.deepChangeToRequested(control); -} - -#endif - -//------------------------------------------------------------------------------ - -#if FFSM2_STRUCTURE_REPORT_AVAILABLE() -#endif - -//------------------------------------------------------------------------------ - -#if FFSM2_STRUCTURE_REPORT_AVAILABLE() -#endif - -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(14) -RV_, TA>::RV_(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept - : Base{context - FFSM2_IF_LOG_INTERFACE(, logger)} -{ - initialEnter(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -RV_, TA>::RV_(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept - : Base{move(context) - FFSM2_IF_LOG_INTERFACE(, logger)} -{ - initialEnter(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -RV_, TA>::RV_(const RV_& other) noexcept - : Base{other} -{} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -RV_, TA>::RV_(RV_&& other) noexcept - : Base{move(other)} -{} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(20) -RV_, TA>::~RV_() noexcept { - finalExit(); -} - -//------------------------------------------------------------------------------ - -#if FFSM2_SERIALIZATION_AVAILABLE() - -template -FFSM2_CONSTEXPR(14) -void -RV_, TA>::save(SerialBuffer& buffer) const noexcept { - WriteStream stream{buffer}; - - stream.template write<1>(1); - save(stream); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -void -RV_, TA>::load(const SerialBuffer& buffer) noexcept { - ReadStream stream{buffer}; - - if (FFSM2_CHECKED(stream.template read<1>())) - Base::load(stream); -} - -#endif - -//////////////////////////////////////////////////////////////////////////////// - -#if FFSM2_SERIALIZATION_AVAILABLE() - -template -FFSM2_CONSTEXPR(14) -void -RV_, TA>::save(SerialBuffer& buffer) const noexcept { - WriteStream stream{buffer}; - - if (isActive()) { - stream.template write<1>(1); - - save(stream); - } - else - stream.template write<1>(0); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -void -RV_, TA>::load(const SerialBuffer& buffer) noexcept { - ReadStream stream{buffer}; - - if (stream.template read<1>()) { - if (isActive()) - Base::load(stream); - else - loadEnter (stream); - } - else - if (isActive()) - finalExit(); -} - -#endif - -//------------------------------------------------------------------------------ - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - -template -FFSM2_CONSTEXPR(14) -void -RV_, TA>::replayEnter(const StateID destination) noexcept { - FFSM2_ASSERT(_core.registry.active == INVALID_SHORT); - FFSM2_ASSERT(!_core.request); - FFSM2_IF_TRANSITION_HISTORY(FFSM2_ASSERT(!_core.previousTransition)); - - Transition currentTransition; - PlanControl control{_core, currentTransition}; - - applyRequest(currentTransition, - destination); - - FFSM2_IF_TRANSITION_HISTORY(_core.previousTransition = Transition{destination}); - - _apex.deepEnter(control); - - _core.registry.clearRequests(); - - FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); -} - -#endif - -//------------------------------------------------------------------------------ - -#if FFSM2_SERIALIZATION_AVAILABLE() - -template -FFSM2_CONSTEXPR(14) -void -RV_, TA>::loadEnter(ReadStream& stream) noexcept { - FFSM2_ASSERT(_core.registry.empty()); - _apex.deepLoadRequested(_core.registry, stream); - - FFSM2_ASSERT(!_core.request); - -#if FFSM2_PLANS_AVAILABLE() - FFSM2_ASSERT(_core.planData.empty() == 0); -#endif - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - FFSM2_ASSERT(_core.transitionTargets .empty()); - FFSM2_ASSERT(_core.previousTransitions.empty()); -#endif - - Transition emptyTransition; - PlanControl control{_core, emptyTransition}; - - _apex.deepEnter(control); -} - -#endif - -//////////////////////////////////////////////////////////////////////////////// -// COMMON - -template -FFSM2_CONSTEXPR(14) -void -RP_, TA>::changeWith(const StateID stateId_, - const Payload& payload) noexcept -{ - FFSM2_ASSERT(_core.registry.isActive()); - - _core.request = Transition{stateId_, payload}; - - FFSM2_LOG_TRANSITION(_core.context, INVALID_STATE_ID, stateId_); -} - -// COMMON -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -void -RP_, TA>::immediateChangeWith(const StateID stateId_, - const Payload& payload) noexcept -{ - changeWith(stateId_, payload); - - processRequest(); -} - -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(11) -InstanceT, TA>::InstanceT(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept - : Base{context - FFSM2_IF_LOG_INTERFACE(, logger)} -{} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(11) -InstanceT, TA>::InstanceT(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept - : Base{move(context) - FFSM2_IF_LOG_INTERFACE(, logger)} -{} - -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(11) -InstanceT, TA>::InstanceT(Context context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept - : Base{context - FFSM2_IF_LOG_INTERFACE(, logger)} -{} - -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(11) -InstanceT, TA>::InstanceT(FFSM2_IF_LOG_INTERFACE(Logger* const logger)) noexcept - : Base{static_cast(*this) - FFSM2_IF_LOG_INTERFACE(, logger)} -{} - -//////////////////////////////////////////////////////////////////////////////// - -} -} diff --git a/development/ffsm2/detail/root/control.hpp b/development/ffsm2/detail/root/control.hpp deleted file mode 100644 index ec1f1d7..0000000 --- a/development/ffsm2/detail/root/control.hpp +++ /dev/null @@ -1,702 +0,0 @@ -namespace ffsm2 { -namespace detail { - -//////////////////////////////////////////////////////////////////////////////// - -template -class ConstControlT { - template - friend struct S_; - - template - friend struct C_; - - template - friend class R_; - -protected: - using Context = typename TArgs::Context; - - using StateList = typename TArgs::StateList; - - using Core = CoreT; - - using Payload = typename TArgs::Payload; - using Transition = TransitionT; - -#if FFSM2_PLANS_AVAILABLE() - using PlanData = PlanDataT; -#endif - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using Logger = typename TArgs::Logger; -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct Origin final { - FFSM2_CONSTEXPR(14) Origin(ConstControlT& control_, - const StateID stateId_) noexcept; - - FFSM2_CONSTEXPR(20) ~Origin() noexcept; - - ConstControlT& control; - const StateID prevId; - }; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(11) ConstControlT(const Core& core) noexcept - : _core{core} - {} - -public: - -#if FFSM2_PLANS_AVAILABLE() - using CPlan = CPlanT; -#endif - - /// @brief Get current state's identifier - /// @return Numeric state identifier - FFSM2_CONSTEXPR(11) StateID stateId() const noexcept { return _originId; } - - /// @brief Get state identifier for a state type - /// @tparam TState State type - /// @return Numeric state identifier - template - static constexpr StateID stateId() noexcept { return index(); } - - /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) - /// @return context - /// @see Control::context() - FFSM2_CONSTEXPR(11) const Context& _() const noexcept { return _core.context; } - - /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) - /// @return context - /// @see Control::_() - FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Inspect current transition request - /// @return Transition requests - FFSM2_CONSTEXPR(11) const Transition& request() const noexcept { return _core.request; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Check if a state is active - /// @param stateId State identifier - /// @return State active status - FFSM2_CONSTEXPR(11) bool isActive (const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } - - /// @brief Check if a state is active - /// @tparam TState State type - /// @return State active status - template - FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return isActive(stateId()); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_PLANS_AVAILABLE() - - /// @brief Access read-only plan - /// @return Plan - FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - - /// @brief Get transitions processed during last 'update()', 'react()' or 'replayTransition()' - /// @return Array of last transition requests - FFSM2_CONSTEXPR(11) const Transition& previousTransitions() const noexcept { return _core.previousTransition; } - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -protected: - const Core& _core; - StateID _originId = INVALID_STATE_ID; -}; - -//////////////////////////////////////////////////////////////////////////////// - -template -class ControlT { - template - friend struct S_; - - template - friend struct C_; - - template - friend class R_; - -protected: - using Context = typename TArgs::Context; - - using StateList = typename TArgs::StateList; - - using Core = CoreT; - - using Payload = typename TArgs::Payload; - using Transition = TransitionT; - -#if FFSM2_PLANS_AVAILABLE() - using PlanData = PlanDataT; -#endif - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using Logger = typename TArgs::Logger; -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct Origin final { - FFSM2_CONSTEXPR(14) Origin(ControlT& control_, - const StateID stateId_) noexcept; - - FFSM2_CONSTEXPR(20) ~Origin() noexcept; - - ControlT& control; - const StateID prevId; - }; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(11) ControlT(Core& core) noexcept - : _core{core} - {} - -public: - -#if FFSM2_PLANS_AVAILABLE() - using CPlan = CPlanT; -#endif - - /// @brief Get current state's identifier - /// @return Numeric state identifier - constexpr StateID stateId() const noexcept { return _originId; } - - /// @brief Get state identifier for a state type - /// @tparam TState State type - /// @return Numeric state identifier - template - static constexpr StateID stateId() noexcept { return index(); } - - /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) - /// @return context - /// @see Control::context() - FFSM2_CONSTEXPR(14) Context& _() noexcept { return _core.context; } - - /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) - /// @return context - /// @see Control::context() - FFSM2_CONSTEXPR(11) const Context& _() const noexcept { return _core.context; } - - /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) - /// @return context - /// @see Control::_() - FFSM2_CONSTEXPR(14) Context& context() noexcept { return _core.context; } - - /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) - /// @return context - /// @see Control::_() - FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Inspect current transition request - /// @return Transition requests - FFSM2_CONSTEXPR(11) const Transition& request() const noexcept { return _core.request; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Check if a state is active - /// @param stateId State identifier - /// @return State active status - FFSM2_CONSTEXPR(11) bool isActive (const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } - - /// @brief Check if a state is active - /// @tparam TState State type - /// @return State active status - template - FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return isActive(stateId()); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_PLANS_AVAILABLE() - - /// @brief Access read-only plan - /// @return Plan - FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - - /// @brief Get transitions processed during last 'update()', 'react()' or 'replayTransition()' - /// @return Array of last transition requests - FFSM2_CONSTEXPR(11) const Transition& previousTransitions() const noexcept { return _core.previousTransition; } - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -protected: - Core& _core; - StateID _originId = INVALID_STATE_ID; -}; - -//////////////////////////////////////////////////////////////////////////////// - -template -class PlanControlT - : public ControlT -{ - template - friend struct S_; - - template - friend struct C_; - - template - friend class R_; - - template - friend class RV_; - -protected: - using Control = ControlT; - - using typename Control::StateList; - using typename Control::Core; - - using Transition = typename Core::Transition; - -#if FFSM2_PLANS_AVAILABLE() - using typename Control::PlanData; -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct Region { - FFSM2_CONSTEXPR(14) Region(PlanControlT& control) noexcept; - - FFSM2_CONSTEXPR(20) ~Region() noexcept; - - PlanControlT& control; - }; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(11) PlanControlT(Core& core, - const Transition& currentTransition) noexcept - : Control{core} - , _currentTransition{currentTransition} - {} - - FFSM2_CONSTEXPR(14) void setRegion() noexcept; - FFSM2_CONSTEXPR(14) void resetRegion() noexcept; - -public: - using Control::isActive; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_PLANS_AVAILABLE() - using typename Control::CPlan; - - using Plan = PlanT; - - /// @brief Access plan - /// @return Plan - FFSM2_CONSTEXPR(14) Plan plan() noexcept { return Plan{_core.planData}; } - -// COMMON -// COMMON - - /// @brief Access read-only plan - /// @return Read-only plan - FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } - -// COMMON -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Get current transition request - /// @return Current transition request - FFSM2_CONSTEXPR(11) const Transition& currentTransition() const noexcept { return _currentTransition; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -protected: - using Control::_core; - - const Transition& _currentTransition; - TaskStatus _taskStatus; -}; - -//------------------------------------------------------------------------------ - -template -class FullControlBaseT - : public PlanControlT -{ - template - friend struct S_; - - template - friend struct C_; - - template - friend class R_; - -protected: - using PlanControl = PlanControlT; - - using typename PlanControl::StateList; - using typename PlanControl::Transition; - -#if FFSM2_PLANS_AVAILABLE() - using TasksBits = BitArrayT; -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct Lock final { - FFSM2_CONSTEXPR(14) Lock(FullControlBaseT& control_) noexcept; - FFSM2_CONSTEXPR(20) ~Lock() noexcept; - - FullControlBaseT* const control; - }; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - using PlanControl::PlanControl; - -public: - using PlanControl::context; - - using PlanControl::isActive; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON - - /// @brief Transition into a state - /// @param stateId State identifier - FFSM2_CONSTEXPR(14) void changeTo(const StateID stateId_) noexcept; - - /// @brief Transition into a state - /// @tparam TState State type - template - FFSM2_CONSTEXPR(14) void changeTo() noexcept { changeTo (PlanControl::template stateId()); } - - // COMMON - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_PLANS_AVAILABLE() - - /// @brief Succeed a plan task for the current state - FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed (_originId ); } - - /// @brief Succeed a plan task for a state - /// @param stateId State ID - FFSM2_CONSTEXPR(14) void succeed(const StateID stateId_) noexcept; - - /// @brief Succeed a plan task for a state - /// @tparam TState State type - template - FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed (PlanControl::template stateId()); } - - /// @brief Fail a plan task for the current state - FFSM2_CONSTEXPR(14) void fail () noexcept { fail (_originId ); } - - /// @brief Fail a plan task for a state - /// @param stateId State ID - FFSM2_CONSTEXPR(14) void fail (const StateID stateId_) noexcept; - - /// @brief Fail a plan task for a state - /// @tparam TState State type - template - FFSM2_CONSTEXPR(14) void fail () noexcept { fail (PlanControl::template stateId()); } - -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -protected: - using PlanControl::_core; - - using PlanControl::_originId; - using PlanControl::_taskStatus; - - bool _locked = false; -}; - -//------------------------------------------------------------------------------ - -template -class FullControlT; - -//------------------------------------------------------------------------------ - -template -class FullControlT> - : public FullControlBaseT> -{ - template - friend struct S_; - - template - friend struct C_; - - template - friend class R_; - - using Args = ArgsT; - -protected: - using FullControlBase = FullControlBaseT; - - using typename FullControlBase::Payload; - using typename FullControlBase::Transition; - - using typename FullControlBase::Origin; - -#if FFSM2_PLANS_AVAILABLE() - using typename FullControlBase::Plan; - using typename FullControlBase::TasksBits; -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - using FullControlBase::FullControlBase; - -#if FFSM2_PLANS_AVAILABLE() - - template - FFSM2_CONSTEXPR(14) void updatePlan(TState& headState, - const TaskStatus subStatus) noexcept; - -#endif - -public: - using FullControlBase::context; - - using FullControlBase::isActive; - using FullControlBase::changeTo; - - FFSM2_IF_PLANS(using FullControlBase::plan); - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON - - /// @brief Transition into a state - /// @param stateId Destination state identifier - /// @param payload Payload - FFSM2_CONSTEXPR(14) void changeWith (const StateID stateId_, - const Payload& payload) noexcept; - - /// @brief Transition into a state - /// @tparam TState Destination state type - /// @param payload Payload - template - FFSM2_CONSTEXPR(14) void changeWith(const Payload& payload) noexcept { changeWith(FullControlBase::template stateId(), payload ); } - - // COMMON - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif - -protected: - using FullControlBase::_core; - - using FullControlBase::_originId; - using FullControlBase::_taskStatus; - using FullControlBase::_locked; -}; - -//------------------------------------------------------------------------------ - -template -class FullControlT> - : public FullControlBaseT> -{ - template - friend struct S_; - - template - friend struct C_; - - template - friend class R_; - - using Args = ArgsT; - -protected: - using FullControlBase = FullControlBaseT; - - using typename FullControlBase::Origin; - -#if FFSM2_PLANS_AVAILABLE() - using typename FullControlBase::Plan; - using typename FullControlBase::TasksBits; -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - using FullControlBase::FullControlBase; - -#if FFSM2_PLANS_AVAILABLE() - - template - FFSM2_CONSTEXPR(14) void updatePlan(TState& headState, - const TaskStatus subStatus) noexcept; - -#endif - -public: - using FullControlBase::isActive; - using FullControlBase::changeTo; - - FFSM2_IF_PLANS(using FullControlBase::plan); - -protected: - FFSM2_IF_PLANS(using FullControlBase::_core); - - using FullControlBase::_taskStatus; -}; - -//------------------------------------------------------------------------------ - -template -class GuardControlT final - : public FullControlT -{ - template - friend struct S_; - - template - friend struct C_; - - template - friend class R_; - - using FullControl = FullControlT; - - using typename FullControl::Context; - using typename FullControl::Core; - - using typename FullControl::Transition; - -#if FFSM2_PLANS_AVAILABLE() - using typename FullControl::PlanData; -#endif - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename FullControl::Logger; -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(11) GuardControlT(Core& core, - const Transition& currentTransition, - const Transition& pendingTransition) noexcept - : FullControl{core, currentTransition} - , _pendingTransition{pendingTransition} - {} - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -public: - using FullControl::context; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON - - /// @brief Get pending transition request - /// @return Pending transition request - FFSM2_CONSTEXPR(11) const Transition& pendingTransition() const noexcept { return _pendingTransition; } - - /// @brief Cancel pending transition request - /// (can be used to substitute a transition into the current state with a different one) - FFSM2_CONSTEXPR(14) void cancelPendingTransition() noexcept; - -private: - using FullControl::_core; - using FullControl::_originId; - - const Transition& _pendingTransition; - bool _cancelled = false; -}; - -//////////////////////////////////////////////////////////////////////////////// - -} -} - -#include "control.inl" diff --git a/development/ffsm2/detail/root/control_0.hpp b/development/ffsm2/detail/root/control_0.hpp new file mode 100644 index 0000000..421ed3a --- /dev/null +++ b/development/ffsm2/detail/root/control_0.hpp @@ -0,0 +1,134 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class ConstControlT { + template + friend struct S_; + + template + friend struct C_; + + template + friend class R_; + +protected: + using Context = typename TArgs::Context; + + using StateList = typename TArgs::StateList; + + using Core = CoreT; + + using Payload = typename TArgs::Payload; + using Transition = TransitionT; + +#if FFSM2_PLANS_AVAILABLE() + using PlanData = PlanDataT; +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using Logger = typename TArgs::Logger; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + struct Origin final { + FFSM2_CONSTEXPR(14) Origin(ConstControlT& control_, + const StateID stateId_) noexcept; + + FFSM2_CONSTEXPR(20) ~Origin() noexcept; + + ConstControlT& control; + const StateID prevId; + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(11) ConstControlT(const Core& core) noexcept + : _core{core} + {} + +public: + +#if FFSM2_PLANS_AVAILABLE() + using CPlan = CPlanT; +#endif + + /// @brief Get current state's identifier + /// @return Numeric state identifier + FFSM2_CONSTEXPR(11) StateID stateId() const noexcept { return _originId; } + + /// @brief Get state identifier for a state type + /// @tparam `TState` State type + /// @return Numeric state identifier + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index(); } + + /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) + /// @return context + /// @see Control::context() + FFSM2_CONSTEXPR(11) const Context& _() const noexcept { return _core.context; } + + /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) + /// @return context + /// @see Control::_() + FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Inspect current transition request + /// @return Transition requests + FFSM2_CONSTEXPR(11) const Transition& request() const noexcept { return _core.request; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Check if a state is active + /// @param `stateId` State identifier + /// @return State active status + FFSM2_CONSTEXPR(11) bool isActive (const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } + + /// @brief Check if a state is active + /// @tparam `TState` State type + /// @return State active status + template + FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return isActive(stateId()); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_PLANS_AVAILABLE() + + /// @brief Access read-only plan + /// @return Plan + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + + /// @brief Get transitions processed during last `update()`, `react()` or `replayTransition()` + /// @return Array of last transition requests + /// @see `FFSM2_ENABLE_TRANSITION_HISTORY` + FFSM2_CONSTEXPR(11) const Transition& previousTransitions() const noexcept { return _core.previousTransition; } + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +protected: + const Core& _core; + StateID _originId = INVALID_STATE_ID; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "control_0.inl" diff --git a/development/ffsm2/detail/root/control_0.inl b/development/ffsm2/detail/root/control_0.inl new file mode 100644 index 0000000..8dee5b4 --- /dev/null +++ b/development/ffsm2/detail/root/control_0.inl @@ -0,0 +1,30 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +ConstControlT::Origin::Origin(ConstControlT& control_, + const StateID stateId_) noexcept + : control{control_} + , prevId{control._originId} +{ + FFSM2_ASSERT(stateId_ < StateList::SIZE || + stateId_ == INVALID_STATE_ID); // specific + + control._originId = stateId_; +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(20) +ConstControlT::Origin::~Origin() noexcept { + control._originId = prevId; +} + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/root/control_1.hpp b/development/ffsm2/detail/root/control_1.hpp new file mode 100644 index 0000000..50a968a --- /dev/null +++ b/development/ffsm2/detail/root/control_1.hpp @@ -0,0 +1,148 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class ControlT { + template + friend struct S_; + + template + friend struct C_; + + template + friend class R_; + +protected: + using Context = typename TArgs::Context; + + using StateList = typename TArgs::StateList; + + using Core = CoreT; + + using Payload = typename TArgs::Payload; + using Transition = TransitionT; + +#if FFSM2_PLANS_AVAILABLE() + using PlanData = PlanDataT; +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using Logger = typename TArgs::Logger; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + struct Origin final { + FFSM2_CONSTEXPR(14) Origin(ControlT& control_, + const StateID stateId_) noexcept; + + FFSM2_CONSTEXPR(20) ~Origin() noexcept; + + ControlT& control; + const StateID prevId; + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(11) ControlT(Core& core) noexcept + : _core{core} + {} + +public: + +#if FFSM2_PLANS_AVAILABLE() + using CPlan = CPlanT; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Get current state's identifier + /// @return Numeric state identifier + FFSM2_CONSTEXPR(11) StateID stateId() const noexcept { return _originId; } + + /// @brief Get state identifier for a state type + /// @tparam `TState` State type + /// @return Numeric state identifier + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index(); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) + /// @return context + /// @see `Control::context()` + FFSM2_CONSTEXPR(14) Context& _() noexcept { return _core.context; } + + /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) + /// @return context + /// @see `Control::context()` + FFSM2_CONSTEXPR(11) const Context& _() const noexcept { return _core.context; } + + /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) + /// @return context + /// @see `Control::_()` + FFSM2_CONSTEXPR(14) Context& context() noexcept { return _core.context; } + + /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) + /// @return context + /// @see `Control::_()` + FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Inspect current transition request + /// @return Transition requests + FFSM2_CONSTEXPR(11) const Transition& request() const noexcept { return _core.request; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Check if a state is active + /// @param `stateId` State identifier + /// @return State active status + FFSM2_CONSTEXPR(11) bool isActive (const StateID stateId_) const noexcept { return _core.registry.isActive(stateId_); } + + /// @brief Check if a state is active + /// @tparam `TState` State type + /// @return State active status + template + FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return isActive(stateId()); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_PLANS_AVAILABLE() + + /// @brief Access read-only plan + /// @return Plan + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + + /// @brief Get transitions processed during last `update()`, `react()` or `replayTransition()` + /// @return Array of last transition requests + /// @see `FFSM2_ENABLE_TRANSITION_HISTORY` + FFSM2_CONSTEXPR(11) const Transition& previousTransitions() const noexcept { return _core.previousTransition; } + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +protected: + Core& _core; + StateID _originId = INVALID_STATE_ID; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "control_1.inl" diff --git a/development/ffsm2/detail/root/control_1.inl b/development/ffsm2/detail/root/control_1.inl new file mode 100644 index 0000000..ca277ff --- /dev/null +++ b/development/ffsm2/detail/root/control_1.inl @@ -0,0 +1,30 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +ControlT::Origin::Origin(ControlT& control_, + const StateID stateId_) noexcept + : control{control_} + , prevId{control._originId} +{ + FFSM2_ASSERT(stateId_ < StateList::SIZE || + stateId_ == INVALID_STATE_ID); // specific + + control._originId = stateId_; +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(20) +ControlT::Origin::~Origin() noexcept { + control._originId = prevId; +} + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/root/control_2.hpp b/development/ffsm2/detail/root/control_2.hpp new file mode 100644 index 0000000..6af27d7 --- /dev/null +++ b/development/ffsm2/detail/root/control_2.hpp @@ -0,0 +1,101 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class PlanControlT + : public ControlT +{ + template + friend struct S_; + + template + friend struct C_; + + template + friend class R_; + + template + friend class RV_; + +protected: + using Control = ControlT; + + using typename Control::StateList; + + using typename Control::Core; + + using Transition = typename Core::Transition; + +#if FFSM2_PLANS_AVAILABLE() + using typename Control::PlanData; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + struct Region { + FFSM2_CONSTEXPR(14) Region(PlanControlT& control) noexcept; + + FFSM2_CONSTEXPR(20) ~Region() noexcept; + + PlanControlT& control; + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(11) PlanControlT(Core& core, + const Transition& currentTransition) noexcept + : Control{core} + , _currentTransition{currentTransition} + {} + + FFSM2_CONSTEXPR(14) void setRegion() noexcept; + FFSM2_CONSTEXPR(14) void resetRegion() noexcept; + +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_PLANS_AVAILABLE() + using typename Control::CPlan; + + using Plan = PayloadPlanT; + + /// @brief Access plan + /// @return Plan + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) Plan plan() noexcept { return Plan{_core.planData}; } + +// COMMON +// COMMON + + /// @brief Access read-only plan + /// @return Read-only plan + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } + +// COMMON +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Get current transition request + /// @return Current transition request + FFSM2_CONSTEXPR(11) const Transition& currentTransition() const noexcept { return _currentTransition; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +protected: + using Control::_core; + + const Transition& _currentTransition; + + TaskStatus _taskStatus; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "control_2.inl" diff --git a/development/ffsm2/detail/root/control_2.inl b/development/ffsm2/detail/root/control_2.inl new file mode 100644 index 0000000..221e2d8 --- /dev/null +++ b/development/ffsm2/detail/root/control_2.inl @@ -0,0 +1,44 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +PlanControlT::Region::Region(PlanControlT& control_) noexcept + : control {control_} +{ + control.setRegion(); +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(20) +PlanControlT::Region::~Region() noexcept { + control.resetRegion(); +} + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +void +PlanControlT::setRegion() noexcept +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +PlanControlT::resetRegion() noexcept +{ + _taskStatus.clear(); +} + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/root/control_3.hpp b/development/ffsm2/detail/root/control_3.hpp new file mode 100644 index 0000000..334db66 --- /dev/null +++ b/development/ffsm2/detail/root/control_3.hpp @@ -0,0 +1,314 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class FullControlBaseT + : public PlanControlT +{ + template + friend struct S_; + + template + friend struct C_; + + template + friend class R_; + +protected: + using PlanControl = PlanControlT; + + using typename PlanControl::StateList; + using typename PlanControl::Transition; + +#if FFSM2_PLANS_AVAILABLE() + using TasksBits = BitArrayT; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + struct Lock final { + FFSM2_CONSTEXPR(14) Lock(FullControlBaseT& control_) noexcept; + FFSM2_CONSTEXPR(20) ~Lock() noexcept; + + FullControlBaseT* const control; + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + using PlanControl::PlanControl; + +public: + using PlanControl::context; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // COMMON + + /// @brief Transition into a state + /// @param `stateId` State identifier + FFSM2_CONSTEXPR(14) void changeTo(const StateID stateId_) noexcept; + + /// @brief Transition into a state + /// @tparam `TState` State type + template + FFSM2_CONSTEXPR(14) void changeTo() noexcept { changeTo (PlanControl::template stateId()); } + + // COMMON + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_PLANS_AVAILABLE() + + /// @brief Succeed a plan task for the current state + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed (_originId ); } + + /// @brief Succeed a plan task for a state + /// @param `stateId` State identifier + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void succeed(const StateID stateId_) noexcept; + + /// @brief Succeed a plan task for a state + /// @tparam `TState` State type + /// @see `FFSM2_ENABLE_PLANS` + template + FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed (PlanControl::template stateId()); } + + /// @brief Fail a plan task for the current state + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void fail () noexcept { fail (_originId ); } + + /// @brief Fail a plan task for a state + /// @param stateId State ID + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void fail (const StateID stateId_) noexcept; + + /// @brief Fail a plan task for a state + /// @tparam `TState` State type + /// @see `FFSM2_ENABLE_PLANS` + template + FFSM2_CONSTEXPR(14) void fail () noexcept { fail (PlanControl::template stateId()); } + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +protected: + using PlanControl::_core; + using PlanControl::_originId; + + using PlanControl::_taskStatus; + + bool _locked = false; +}; + +//------------------------------------------------------------------------------ + +template +class FullControlT; + +//------------------------------------------------------------------------------ + +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload +> +class FullControlT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + > + : public FullControlBaseT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + > +{ + template + friend struct S_; + + template + friend struct C_; + + template + friend class R_; + + using Args = ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + >; + +protected: + using FullControlBase = FullControlBaseT; + + using typename FullControlBase::Payload; + using typename FullControlBase::Transition; + + using typename FullControlBase::Origin; + +#if FFSM2_PLANS_AVAILABLE() + using typename FullControlBase::Plan; + using typename FullControlBase::TasksBits; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + using FullControlBase::FullControlBase; + +#if FFSM2_PLANS_AVAILABLE() + + template + FFSM2_CONSTEXPR(14) void updatePlan(TState& headState, + const TaskStatus subStatus) noexcept; + +#endif + +public: + using FullControlBase::context; + + using FullControlBase::isActive; + using FullControlBase::changeTo; + + FFSM2_IF_PLANS(using FullControlBase::plan); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // COMMON + + /// @brief Transition into a state + /// @param `stateId` Destination state identifier + /// @param `payload` Payload + FFSM2_CONSTEXPR(14) void changeWith (const StateID stateId_, + const Payload& payload) noexcept; + + /// @brief Transition into a state + /// @tparam `TState` Destination state type + /// @param `payload` Payload + template + FFSM2_CONSTEXPR(14) void changeWith(const Payload& payload) noexcept { changeWith(FullControlBase::template stateId(), payload ); } + + // COMMON + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + +protected: + using FullControlBase::_core; + using FullControlBase::_originId; + + using FullControlBase::_taskStatus; + + using FullControlBase::_locked; +}; + +//------------------------------------------------------------------------------ + +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + FFSM2_IF_PLANS(, Long NTaskCapacity) +> +class FullControlT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + > + : public FullControlBaseT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + > +{ + template + friend struct S_; + + template + friend struct C_; + + template + friend class R_; + + using Args = ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , void + >; + +protected: + using FullControlBase = FullControlBaseT; + + using typename FullControlBase::Origin; + +#if FFSM2_PLANS_AVAILABLE() + using typename FullControlBase::Plan; + using typename FullControlBase::TasksBits; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + using FullControlBase::FullControlBase; + +#if FFSM2_PLANS_AVAILABLE() + + template + FFSM2_CONSTEXPR(14) void updatePlan(TState& headState, + const TaskStatus subStatus) noexcept; + +#endif + +public: + using FullControlBase::isActive; + using FullControlBase::changeTo; + + FFSM2_IF_PLANS(using FullControlBase::plan); + +protected: + FFSM2_IF_PLANS(using FullControlBase::_core); + + using FullControlBase::_taskStatus; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "control_3.inl" diff --git a/development/ffsm2/detail/root/control.inl b/development/ffsm2/detail/root/control_3.inl similarity index 58% rename from development/ffsm2/detail/root/control.inl rename to development/ffsm2/detail/root/control_3.inl index 00fe67a..f66c0c3 100644 --- a/development/ffsm2/detail/root/control.inl +++ b/development/ffsm2/detail/root/control_3.inl @@ -3,87 +3,6 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// -template -FFSM2_CONSTEXPR(14) -ConstControlT::Origin::Origin(ConstControlT& control_, - const StateID stateId_) noexcept - : control{control_} - , prevId{control._originId} -{ - FFSM2_ASSERT(stateId_ < StateList::SIZE || stateId_ == INVALID_STATE_ID); - control._originId = stateId_; -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(20) -ConstControlT::Origin::~Origin() noexcept { - control._originId = prevId; -} - -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(14) -ControlT::Origin::Origin(ControlT& control_, - const StateID stateId_) noexcept - : control{control_} - , prevId{control._originId} -{ - FFSM2_ASSERT(stateId_ < StateList::SIZE || stateId_ == INVALID_STATE_ID); - control._originId = stateId_; -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(20) -ControlT::Origin::~Origin() noexcept { - control._originId = prevId; -} - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(14) -PlanControlT::Region::Region(PlanControlT& control_) noexcept - : control {control_} -{ - control.setRegion(); -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(20) -PlanControlT::Region::~Region() noexcept { - control.resetRegion(); -} - -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(14) -void -PlanControlT::setRegion() noexcept -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -FFSM2_CONSTEXPR(14) -void -PlanControlT::resetRegion() noexcept -{ - _taskStatus.clear(); -} - -//////////////////////////////////////////////////////////////////////////////// - template FFSM2_CONSTEXPR(14) FullControlBaseT::Lock::Lock(FullControlBaseT& control_) noexcept @@ -150,12 +69,12 @@ FullControlBaseT::fail(const StateID stateId_) noexcept { #if FFSM2_PLANS_AVAILABLE() -template +template template FFSM2_CONSTEXPR(14) void -FullControlT>::updatePlan(TState& headState, - const TaskStatus subStatus) noexcept +FullControlT>::updatePlan(TState& headState, + const TaskStatus subStatus) noexcept { FFSM2_ASSERT(subStatus); @@ -169,7 +88,7 @@ FullControlT>::u TasksBits successesToClear; successesToClear.set(); - for (auto it = p.first(); + for (auto it = p.begin(); it && isActive(it->origin); ++it) { @@ -204,11 +123,11 @@ FullControlT>::u //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -FullControlT>::changeWith(const StateID stateId_, - const Payload& payload) noexcept +FullControlT>::changeWith(const StateID stateId_, + const Payload& payload) noexcept { if (!_locked) { _core.request = Transition{_originId, stateId_, payload}; @@ -227,12 +146,12 @@ FullControlT +template template FFSM2_CONSTEXPR(14) void -FullControlT>::updatePlan(TState& headState, - const TaskStatus subStatus) noexcept +FullControlT>::updatePlan(TState& headState, + const TaskStatus subStatus) noexcept { FFSM2_ASSERT(subStatus); @@ -246,7 +165,7 @@ FullControlT>:: TasksBits successesToClear; successesToClear.set(); - for (auto it = p.first(); + for (auto it = p.begin(); it && isActive(it->origin); ++it) { @@ -278,16 +197,5 @@ FullControlT>:: //////////////////////////////////////////////////////////////////////////////// -template -FFSM2_CONSTEXPR(14) -void -GuardControlT::cancelPendingTransition() noexcept { - _cancelled = true; - - FFSM2_LOG_CANCELLED_PENDING(context(), _originId); -} - -//////////////////////////////////////////////////////////////////////////////// - } } diff --git a/development/ffsm2/detail/root/control_4.hpp b/development/ffsm2/detail/root/control_4.hpp new file mode 100644 index 0000000..d49b722 --- /dev/null +++ b/development/ffsm2/detail/root/control_4.hpp @@ -0,0 +1,75 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class GuardControlT final + : public FullControlT +{ + template + friend struct S_; + + template + friend struct C_; + + template + friend class R_; + + using FullControl = FullControlT; + + using typename FullControl::Core; + using typename FullControl::Context; + + using typename FullControl::Transition; + +#if FFSM2_PLANS_AVAILABLE() + using typename FullControl::PlanData; +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename FullControl::Logger; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(11) GuardControlT(Core& core, + const Transition& currentTransition, + const Transition& pendingTransition) noexcept + : FullControl{core, currentTransition} + , _pendingTransition{pendingTransition} + {} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +public: + using FullControl::context; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // COMMON + + /// @brief Get pending transition request + /// @return Pending transition request + FFSM2_CONSTEXPR(11) const Transition& pendingTransition() const noexcept { return _pendingTransition; } + + /// @brief Cancel pending transition request + /// (can be used to substitute a transition into the current state with a different one) + FFSM2_CONSTEXPR(14) void cancelPendingTransition() noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +private: + using FullControl::_core; + using FullControl::_originId; + + const Transition& _pendingTransition; + + bool _cancelled = false; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "control_4.inl" diff --git a/development/ffsm2/detail/root/control_4.inl b/development/ffsm2/detail/root/control_4.inl new file mode 100644 index 0000000..fb37bbe --- /dev/null +++ b/development/ffsm2/detail/root/control_4.inl @@ -0,0 +1,18 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +void +GuardControlT::cancelPendingTransition() noexcept { + _cancelled = true; + + FFSM2_LOG_CANCELLED_PENDING(context(), _originId); +} + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/root/core.hpp b/development/ffsm2/detail/root/core.hpp index d4e9350..a249ff0 100644 --- a/development/ffsm2/detail/root/core.hpp +++ b/development/ffsm2/detail/root/core.hpp @@ -38,8 +38,8 @@ struct CoreT { Context context; Registry registry; - FFSM2_IF_PLANS(PlanData planData); Transition request; + FFSM2_IF_PLANS(PlanData planData); FFSM2_IF_LOG_INTERFACE(Logger* logger); }; diff --git a/development/ffsm2/detail/root/core.inl b/development/ffsm2/detail/root/core.inl index f6ef6f0..74ec42e 100644 --- a/development/ffsm2/detail/root/core.inl +++ b/development/ffsm2/detail/root/core.inl @@ -28,13 +28,9 @@ FFSM2_CONSTEXPR(11) CoreT::CoreT(const CoreT& other) noexcept : context {other.context } , registry{other.registry} -#if FFSM2_PLANS_AVAILABLE() - , planData{other.planData} -#endif , request {other.request } -#if FFSM2_LOG_INTERFACE_AVAILABLE() - , logger {other.logger } -#endif + FFSM2_IF_PLANS (, planData {other.planData }) + FFSM2_IF_LOG_INTERFACE (, logger {other.logger }) {} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -44,13 +40,9 @@ FFSM2_CONSTEXPR(11) CoreT::CoreT(CoreT&& other) noexcept : context {move(other.context )} , registry{move(other.registry)} -#if FFSM2_PLANS_AVAILABLE() - , planData{move(other.planData)} -#endif , request {move(other.request )} -#if FFSM2_LOG_INTERFACE_AVAILABLE() - , logger {move(other.logger )} -#endif + FFSM2_IF_PLANS (, planData {move(other.planData )}) + FFSM2_IF_LOG_INTERFACE (, logger {move(other.logger )}) {} //////////////////////////////////////////////////////////////////////////////// diff --git a/development/ffsm2/detail/root/plan.hpp b/development/ffsm2/detail/root/plan.hpp deleted file mode 100644 index 8b990ce..0000000 --- a/development/ffsm2/detail/root/plan.hpp +++ /dev/null @@ -1,356 +0,0 @@ -namespace ffsm2 { -namespace detail { - -//////////////////////////////////////////////////////////////////////////////// - -#if FFSM2_PLANS_AVAILABLE() - -template -class CPlanT { - template - friend class R_; - - template - friend class ControlT; - - template - friend class PlanControlT; - - template - friend class FullControlT; - - template - friend class GuardControlT; - - template - friend class R_; - - using Args = TArgs; - using Context = typename Args::Context; - using StateList = typename Args::StateList; - - static constexpr Long TASK_CAPACITY = Args::TASK_CAPACITY; - -public: - using PlanData = PlanDataT; - using Task = typename PlanData::Task; - using TaskLinks = typename PlanData::TaskLinks; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct IteratorT final { - FFSM2_CONSTEXPR(14) IteratorT(const CPlanT& plan) noexcept; - - FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; - - FFSM2_CONSTEXPR(14) void operator ++() noexcept; - - FFSM2_CONSTEXPR(11) const Task& operator *() const noexcept { return _plan._planData.tasks[_curr]; } - FFSM2_CONSTEXPR(11) const Task* operator ->() const noexcept { return &_plan._planData.tasks[_curr]; } - - FFSM2_CONSTEXPR(14) Long next() const noexcept; - - const CPlanT& _plan; - Long _curr; - Long _next; - }; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -private: - FFSM2_CONSTEXPR(11) CPlanT(const PlanData& planData) noexcept - : _planData{planData} - , _bounds{planData.tasksBounds} - {} - - template - static constexpr StateID stateId() noexcept { return index(); } - -public: - FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; - - FFSM2_CONSTEXPR(14) IteratorT first() noexcept { return IteratorT{*this}; } - -private: - const PlanData& _planData; - const Bounds& _bounds; -}; - -//////////////////////////////////////////////////////////////////////////////// - -template -class PlanBaseT { - using Args = TArgs; - using Context = typename Args::Context; - using StateList = typename Args::StateList; - - static constexpr Long STATE_COUNT = StateList::SIZE; - static constexpr Long TASK_CAPACITY = Args::TASK_CAPACITY; - -public: - using PlanData = PlanDataT; - using Task = typename PlanData::Task; - using Tasks = typename PlanData::Tasks; - using TaskLinks = typename PlanData::TaskLinks; - using TaskIndex = typename TaskLinks::Index; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct CIterator final { - FFSM2_CONSTEXPR(14) CIterator(const PlanBaseT& plan) noexcept; - - FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; - - FFSM2_CONSTEXPR(14) void operator ++() noexcept; - - FFSM2_CONSTEXPR(14) const Task& operator *() const noexcept { return _plan._planData.tasks[_curr]; } - FFSM2_CONSTEXPR(11) const Task* operator ->() const noexcept { return &_plan._planData.tasks[_curr]; } - - FFSM2_CONSTEXPR(14) Long next() const noexcept; - - const PlanBaseT& _plan; - Long _curr; - Long _next; - }; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct IteratorT final { - FFSM2_CONSTEXPR(14) IteratorT(PlanBaseT& plan) noexcept; - - FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; - - FFSM2_CONSTEXPR(14) void operator ++() noexcept; - - FFSM2_CONSTEXPR(14) Task& operator *() noexcept { return _plan._planData.tasks[_curr]; } - FFSM2_CONSTEXPR(14) Task* operator ->() noexcept { return &_plan._planData.tasks[_curr]; } - - FFSM2_CONSTEXPR(14) void remove() noexcept { _plan.remove(_curr); } - - FFSM2_CONSTEXPR(14) Long next() const noexcept; - - PlanBaseT& _plan; - Long _curr; - Long _next; - }; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -protected: - FFSM2_CONSTEXPR(11) PlanBaseT(PlanData& planData) noexcept; - - template - static constexpr StateID stateId() noexcept { return index(); } - - FFSM2_CONSTEXPR(14) bool append(const StateID origin, - const StateID destination) noexcept; - - FFSM2_CONSTEXPR(14) bool linkTask(const Long index) noexcept; - - FFSM2_CONSTEXPR(14) void clearTasks() noexcept; - -public: - FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; - - /// @brief Clear all tasks from the plan - FFSM2_CONSTEXPR(14) void clear() noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @param origin Origin state identifier - /// @param destination Destination state identifier - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - FFSM2_CONSTEXPR(14) bool change(const StateID origin, const StateID destination) noexcept { return append(origin , destination) ; } - - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @tparam TOrigin Origin state type - /// @param destination Destination state identifier - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - template - FFSM2_CONSTEXPR(14) bool change(const StateID destination) noexcept { return change(stateId(), destination) ; } - - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @tparam TOrigin Origin state type - /// @tparam TDestination Destination state type - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - template - FFSM2_CONSTEXPR(14) bool change() noexcept { return change(stateId(), stateId()); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Begin iteration over plan tasks - /// @return IteratorT to the first task - FFSM2_CONSTEXPR(14) IteratorT first() noexcept { return IteratorT{*this}; } - - /// @brief Begin iteration over plan tasks - /// @return CIterator to the first task - FFSM2_CONSTEXPR(11) CIterator first() const noexcept { return CIterator{*this}; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -private: - FFSM2_CONSTEXPR(14) void remove(const Long task) noexcept; - -protected: - PlanData& _planData; - Bounds& _bounds; -}; - -//////////////////////////////////////////////////////////////////////////////// - -template -class PlanT; - -//------------------------------------------------------------------------------ - -template -class PlanT> final - : public PlanBaseT> -{ - template - friend class R_; - - template - friend class PlanControlT; - - template - friend class FullControlT; - - template - friend class GuardControlT; - - using Args = ArgsT; - - using Payload = typename Args::Payload; - - using PlanBase = PlanBaseT; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - using PlanBase::PlanBase; - - using PlanBase::linkTask; - - FFSM2_CONSTEXPR(14) bool append(const StateID origin, - const StateID destination, - const Payload& payload) noexcept; - -public: - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @param origin Origin state identifier - /// @param destination Destination state identifier - /// @param payload Payload - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - FFSM2_CONSTEXPR(14) bool changeWith(const StateID origin, const StateID destination, const Payload& payload) noexcept { return append(origin , destination , payload ); } - - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @tparam TOrigin Origin state type - /// @param destination Destination state identifier - /// @param payload Payload - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - template - FFSM2_CONSTEXPR(14) bool changeWith( const StateID destination, const Payload& payload) noexcept { return append(PlanBase::template stateId(), destination , payload ); } - - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @tparam TOrigin Origin state type - /// @tparam TDestination Destination state type - /// @param payload Payload - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - template - FFSM2_CONSTEXPR(14) bool changeWith( const Payload& payload) noexcept { return append(PlanBase::template stateId(), PlanBase::template stateId(), payload ); } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -private: - using PlanBase::_planData; -}; - -//------------------------------------------------------------------------------ - -template -class PlanT> final - : public PlanBaseT> -{ - template - friend class R_; - - template - friend class PlanControlT; - - template - friend class FullControlT; - - template - friend class GuardControlT; - - using Args = ArgsT; - - using PlanBase = PlanBaseT; - - using PlanBase::PlanBase; -}; - -#endif - -//////////////////////////////////////////////////////////////////////////////// - -} -} - -#include "plan.inl" diff --git a/development/ffsm2/detail/root/plan_0.hpp b/development/ffsm2/detail/root/plan_0.hpp new file mode 100644 index 0000000..98c9682 --- /dev/null +++ b/development/ffsm2/detail/root/plan_0.hpp @@ -0,0 +1,107 @@ +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class CPlanT { + template + friend class R_; + + template + friend class ControlT; + + template + friend class PlanControlT; + + template + friend class FullControlT; + + template + friend class GuardControlT; + + template + friend class R_; + + using Args = TArgs; + using Context = typename Args::Context; + using StateList = typename Args::StateList; + + static constexpr Long TASK_CAPACITY = Args::TASK_CAPACITY; + +public: + using PlanData = PlanDataT; + using Task = typename PlanData::Task; + using TaskLinks = typename PlanData::TaskLinks; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + struct Iterator final { + FFSM2_CONSTEXPR(14) Iterator(const CPlanT& plan) noexcept; + + FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; + + FFSM2_CONSTEXPR(14) void operator ++() noexcept; + + FFSM2_CONSTEXPR(11) const Task& operator *() const noexcept { return _plan._planData.tasks[_curr]; } + FFSM2_CONSTEXPR(11) const Task* operator ->() const noexcept { return &_plan._planData.tasks[_curr]; } + + FFSM2_CONSTEXPR(14) Long next() const noexcept; + + const CPlanT& _plan; + Long _curr; + Long _next; + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +private: + FFSM2_CONSTEXPR(11) CPlanT(const PlanData& planData) noexcept + : _planData{planData} + , _bounds{planData.tasksBounds} + {} + + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index(); } + +public: + FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Begin iteration over plan tasks + /// @return CIterator to the first task + FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator{*this}; } + + /// @brief Iteration terminator + /// @return Dummy Iterator + FFSM2_CONSTEXPR(14) Iterator end () noexcept { return Iterator{*this}; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief First task + /// @return First task + FFSM2_CONSTEXPR(14) const Task& first() const noexcept; + + /// @brief Last task + /// @return Last task + FFSM2_CONSTEXPR(14) const Task& last() const noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +private: + const PlanData& _planData; + const Bounds& _bounds; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif + +#include "plan_0.inl" diff --git a/development/ffsm2/detail/root/plan_0.inl b/development/ffsm2/detail/root/plan_0.inl new file mode 100644 index 0000000..779b411 --- /dev/null +++ b/development/ffsm2/detail/root/plan_0.inl @@ -0,0 +1,94 @@ +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +CPlanT::Iterator::Iterator(const CPlanT& plan) noexcept + : _plan{plan} + , _curr{plan._bounds.first} +{ + _next = next(); +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +CPlanT::Iterator::operator bool() const noexcept { + FFSM2_ASSERT(_curr < CPlanT::TASK_CAPACITY || + _curr == INVALID_LONG); + + return _curr < CPlanT::TASK_CAPACITY; +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +void +CPlanT::Iterator::operator ++() noexcept { + _curr = _next; + _next = next(); +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +Long +CPlanT::Iterator::next() const noexcept { + if (_curr < CPlanT::TASK_CAPACITY) { + const TaskLink& link = _plan._planData.taskLinks[_curr]; + + return link.next; + } else { + FFSM2_ASSERT(_curr == INVALID_LONG); + + return INVALID_LONG; + } +} + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +CPlanT::operator bool() const noexcept { + FFSM2_ASSERT(_bounds.first < TASK_CAPACITY && + _bounds.last < TASK_CAPACITY || + _bounds.last == INVALID_LONG); + + return _bounds.first < TASK_CAPACITY; +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +const typename CPlanT::Task& +CPlanT::first() const noexcept { + FFSM2_ASSERT(_bounds.first < TASK_CAPACITY); + + return _planData.tasks[_bounds.first]; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +const typename CPlanT::Task& +CPlanT::last() const noexcept { + FFSM2_ASSERT(_bounds.last < TASK_CAPACITY); + + return _planData.tasks[_bounds.last]; +} + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/development/ffsm2/detail/root/plan_1.hpp b/development/ffsm2/detail/root/plan_1.hpp new file mode 100644 index 0000000..1140676 --- /dev/null +++ b/development/ffsm2/detail/root/plan_1.hpp @@ -0,0 +1,171 @@ +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class PlanT { + using Args = TArgs; + using Context = typename Args::Context; + using StateList = typename Args::StateList; + + static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long TASK_CAPACITY = Args::TASK_CAPACITY; + +public: + using PlanData = PlanDataT; + using Task = typename PlanData::Task; + using Tasks = typename PlanData::Tasks; + using TaskLinks = typename PlanData::TaskLinks; + using TaskIndex = typename TaskLinks::Index; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + struct CIterator final { + FFSM2_CONSTEXPR(14) CIterator(const PlanT& plan) noexcept; + + FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; + + FFSM2_CONSTEXPR(14) void operator ++() noexcept; + + FFSM2_CONSTEXPR(14) const Task& operator *() const noexcept { return _plan._planData.tasks[_curr]; } + FFSM2_CONSTEXPR(11) const Task* operator ->() const noexcept { return &_plan._planData.tasks[_curr]; } + + FFSM2_CONSTEXPR(14) Long next() const noexcept; + + const PlanT& _plan; + Long _curr; + Long _next; + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + struct Iterator final { + FFSM2_CONSTEXPR(14) Iterator(PlanT& plan) noexcept; + + FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; + + FFSM2_CONSTEXPR(14) void operator ++() noexcept; + + FFSM2_CONSTEXPR(14) Task& operator *() noexcept { return _plan._planData.tasks[_curr]; } + FFSM2_CONSTEXPR(14) Task* operator ->() noexcept { return &_plan._planData.tasks[_curr]; } + + FFSM2_CONSTEXPR(14) void remove() noexcept { _plan.remove(_curr); } + + FFSM2_CONSTEXPR(14) Long next() const noexcept; + + PlanT& _plan; + Long _curr; + Long _next; + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +protected: + FFSM2_CONSTEXPR(11) PlanT(PlanData& planData) noexcept; + + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index(); } + + FFSM2_CONSTEXPR(14) bool append(const StateID origin, + const StateID destination) noexcept; + + FFSM2_CONSTEXPR(14) bool linkTask(const Long index) noexcept; + + FFSM2_CONSTEXPR(14) void clearTasks() noexcept; + +public: + FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; + + /// @brief Clear all tasks from the plan + FFSM2_CONSTEXPR(14) void clear() noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @param `origin` Origin state identifier + /// @param `destination` Destination state identifier + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + FFSM2_CONSTEXPR(14) bool change(const StateID origin, + const StateID destination) noexcept { return append(origin , destination) ; } + + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @tparam `TOrigin` Origin state type + /// @param `destination` Destination state identifier + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + template + FFSM2_CONSTEXPR(14) bool change(const StateID destination) noexcept { return change(stateId(), destination) ; } + + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @tparam `TOrigin` Origin state type + /// @tparam `TDestination` Destination state type + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + template + FFSM2_CONSTEXPR(14) bool change() noexcept { return change(stateId(), stateId()); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Begin iteration over plan tasks + /// @return Iterator to the first task + FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator{*this}; } + + /// @brief Begin iteration over plan tasks + /// @return CIterator to the first task + FFSM2_CONSTEXPR(11) CIterator begin() const noexcept { return CIterator{*this}; } + + /// @brief Iteration terminator + /// @return Dummy Iterator + FFSM2_CONSTEXPR(14) Iterator end() noexcept { return Iterator{*this}; } + + /// @brief Iteration terminator + /// @return Dummy CIterator + FFSM2_CONSTEXPR(11) CIterator end() const noexcept { return CIterator{*this}; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief First task + /// @return First task + FFSM2_CONSTEXPR(14) Task& first() noexcept; + + /// @brief First task + /// @return First task + FFSM2_CONSTEXPR(14) const Task& first() const noexcept; + + /// @brief Last task + /// @return Last task + FFSM2_CONSTEXPR(14) Task& last() noexcept; + + /// @brief Last task + /// @return Last task + FFSM2_CONSTEXPR(14) const Task& last() const noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +private: + FFSM2_CONSTEXPR(14) void remove(const Long task) noexcept; + +protected: + PlanData& _planData; + Bounds& _bounds; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif + +#include "plan_1.inl" diff --git a/development/ffsm2/detail/root/plan.inl b/development/ffsm2/detail/root/plan_1.inl similarity index 62% rename from development/ffsm2/detail/root/plan.inl rename to development/ffsm2/detail/root/plan_1.inl index f70ae0f..eb0e105 100644 --- a/development/ffsm2/detail/root/plan.inl +++ b/development/ffsm2/detail/root/plan_1.inl @@ -1,74 +1,13 @@ -namespace ffsm2 { -namespace detail { - -//////////////////////////////////////////////////////////////////////////////// - #if FFSM2_PLANS_AVAILABLE() -template -FFSM2_CONSTEXPR(14) -CPlanT::IteratorT::IteratorT(const CPlanT& plan) noexcept - : _plan{plan} - , _curr{plan._bounds.first} -{ - _next = next(); -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -CPlanT::IteratorT::operator bool() const noexcept { - FFSM2_ASSERT(_curr < CPlanT::TASK_CAPACITY || - _curr == INVALID_LONG); - - return _curr < CPlanT::TASK_CAPACITY; -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -void -CPlanT::IteratorT::operator ++() noexcept { - _curr = _next; - _next = next(); -} - -//------------------------------------------------------------------------------ - -template -FFSM2_CONSTEXPR(14) -Long -CPlanT::IteratorT::next() const noexcept { - if (_curr < CPlanT::TASK_CAPACITY) { - const TaskLink& link = _plan._planData.taskLinks[_curr]; - - return link.next; - } else { - FFSM2_ASSERT(_curr == INVALID_LONG); - - return INVALID_LONG; - } -} - -//////////////////////////////////////////////////////////////////////////////// - -template -FFSM2_CONSTEXPR(14) -CPlanT::operator bool() const noexcept { - FFSM2_ASSERT(_bounds.first < TASK_CAPACITY && - _bounds.last < TASK_CAPACITY || - _bounds.last == INVALID_LONG); - - return _bounds.first < TASK_CAPACITY; -} +namespace ffsm2 { +namespace detail { //////////////////////////////////////////////////////////////////////////////// template FFSM2_CONSTEXPR(14) -PlanBaseT::CIterator::CIterator(const PlanBaseT& plan) noexcept +PlanT::CIterator::CIterator(const PlanT& plan) noexcept : _plan{plan} , _curr{plan._bounds.first} , _next{next()} @@ -78,11 +17,11 @@ PlanBaseT::CIterator::CIterator(const PlanBaseT& plan) noexcept template FFSM2_CONSTEXPR(14) -PlanBaseT::CIterator::operator bool() const noexcept { - FFSM2_ASSERT(_curr < PlanBaseT::TASK_CAPACITY || +PlanT::CIterator::operator bool() const noexcept { + FFSM2_ASSERT(_curr < PlanT::TASK_CAPACITY || _curr == INVALID_LONG); - return _curr < PlanBaseT::TASK_CAPACITY; + return _curr < PlanT::TASK_CAPACITY; } //------------------------------------------------------------------------------ @@ -90,7 +29,7 @@ PlanBaseT::CIterator::operator bool() const noexcept { template FFSM2_CONSTEXPR(14) void -PlanBaseT::CIterator::operator ++() noexcept { +PlanT::CIterator::operator ++() noexcept { _curr = _next; _next = next(); } @@ -100,8 +39,8 @@ PlanBaseT::CIterator::operator ++() noexcept { template FFSM2_CONSTEXPR(14) Long -PlanBaseT::CIterator::next() const noexcept { - if (_curr < PlanBaseT::TASK_CAPACITY) { +PlanT::CIterator::next() const noexcept { + if (_curr < PlanT::TASK_CAPACITY) { const TaskLink& link = _plan._planData.taskLinks[_curr]; return link.next; @@ -116,7 +55,7 @@ PlanBaseT::CIterator::next() const noexcept { template FFSM2_CONSTEXPR(14) -PlanBaseT::IteratorT::IteratorT(PlanBaseT& plan) noexcept +PlanT::Iterator::Iterator(PlanT& plan) noexcept : _plan{plan} , _curr{plan._bounds.first} , _next{next()} @@ -126,11 +65,11 @@ PlanBaseT::IteratorT::IteratorT(PlanBaseT& plan) noexcept template FFSM2_CONSTEXPR(14) -PlanBaseT::IteratorT::operator bool() const noexcept { - FFSM2_ASSERT(_curr < PlanBaseT::TASK_CAPACITY || +PlanT::Iterator::operator bool() const noexcept { + FFSM2_ASSERT(_curr < PlanT::TASK_CAPACITY || _curr == INVALID_LONG); - return _curr < PlanBaseT::TASK_CAPACITY; + return _curr < PlanT::TASK_CAPACITY; } //------------------------------------------------------------------------------ @@ -138,7 +77,7 @@ PlanBaseT::IteratorT::operator bool() const noexcept { template FFSM2_CONSTEXPR(14) void -PlanBaseT::IteratorT::operator ++() noexcept { +PlanT::Iterator::operator ++() noexcept { _curr = _next; _next = next(); } @@ -148,8 +87,8 @@ PlanBaseT::IteratorT::operator ++() noexcept { template FFSM2_CONSTEXPR(14) Long -PlanBaseT::IteratorT::next() const noexcept { - if (_curr < PlanBaseT::TASK_CAPACITY) { +PlanT::Iterator::next() const noexcept { + if (_curr < PlanT::TASK_CAPACITY) { const TaskLink& link = _plan._planData.taskLinks[_curr]; return link.next; @@ -164,7 +103,7 @@ PlanBaseT::IteratorT::next() const noexcept { template FFSM2_CONSTEXPR(11) -PlanBaseT::PlanBaseT(PlanData& planData) noexcept +PlanT::PlanT(PlanData& planData) noexcept : _planData{planData} , _bounds{planData.tasksBounds} {} @@ -174,8 +113,8 @@ PlanBaseT::PlanBaseT(PlanData& planData) noexcept template FFSM2_CONSTEXPR(14) bool -PlanBaseT::append(const StateID origin, - const StateID destination) noexcept +PlanT::append(const StateID origin, + const StateID destination) noexcept { if (_planData.tasks.count() < TASK_CAPACITY) { _planData.planExists = true; @@ -190,7 +129,7 @@ PlanBaseT::append(const StateID origin, template FFSM2_CONSTEXPR(14) bool -PlanBaseT::linkTask(const Long index) noexcept { +PlanT::linkTask(const Long index) noexcept { if (index != Tasks::INVALID) { if (_bounds.first == INVALID_LONG) { FFSM2_ASSERT(_bounds.last == INVALID_LONG); @@ -226,7 +165,7 @@ PlanBaseT::linkTask(const Long index) noexcept { template FFSM2_CONSTEXPR(14) void -PlanBaseT::clearTasks() noexcept { +PlanT::clearTasks() noexcept { if (_bounds.first < TaskLinks::CAPACITY) { FFSM2_ASSERT(_bounds.last < TaskLinks::CAPACITY); @@ -260,7 +199,7 @@ PlanBaseT::clearTasks() noexcept { template FFSM2_CONSTEXPR(14) -PlanBaseT::operator bool() const noexcept { +PlanT::operator bool() const noexcept { FFSM2_ASSERT(_bounds.first < TASK_CAPACITY && _bounds.last < TASK_CAPACITY || _bounds.last == INVALID_LONG); @@ -273,10 +212,10 @@ PlanBaseT::operator bool() const noexcept { template FFSM2_CONSTEXPR(14) void -PlanBaseT::clear() noexcept { +PlanT::clear() noexcept { clearTasks(); - for (Short i = 0; + for (StateID i = 0; i < STATE_COUNT; ++i) { @@ -290,7 +229,7 @@ PlanBaseT::clear() noexcept { template FFSM2_CONSTEXPR(14) void -PlanBaseT::remove(const Long index) noexcept { +PlanT::remove(const Long index) noexcept { FFSM2_ASSERT(_planData.planExists); FFSM2_ASSERT(_bounds.first < TaskLinks::CAPACITY); FFSM2_ASSERT(_bounds.last < TaskLinks::CAPACITY); @@ -323,21 +262,7 @@ PlanBaseT::remove(const Long index) noexcept { //////////////////////////////////////////////////////////////////////////////// -template -FFSM2_CONSTEXPR(14) -bool -PlanT>::append(const StateID origin, - const StateID destination, - const Payload& payload) noexcept -{ - _planData.planExists = true; - - return linkTask(_planData.tasks.emplace(origin, destination, payload)); +} } #endif - -//////////////////////////////////////////////////////////////////////////////// - -} -} diff --git a/development/ffsm2/detail/root/plan_2.hpp b/development/ffsm2/detail/root/plan_2.hpp new file mode 100644 index 0000000..e1b7b35 --- /dev/null +++ b/development/ffsm2/detail/root/plan_2.hpp @@ -0,0 +1,180 @@ +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class PayloadPlanT; + +//------------------------------------------------------------------------------ + +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + , Long NTaskCapacity + , typename TPayload +> +class PayloadPlanT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , TPayload + > + > final + : public PlanT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , TPayload + > + > +{ + template + friend class R_; + + template + friend class PlanControlT; + + template + friend class FullControlT; + + template + friend class GuardControlT; + + using Args = ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , TPayload + >; + + using Payload = typename Args::Payload; + + static constexpr Long TASK_CAPACITY = Args::TASK_CAPACITY; + + using PlanBase = PlanT; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + using PlanBase::PlanBase; + + using PlanBase::linkTask; + + FFSM2_CONSTEXPR(14) bool append(const StateID origin, + const StateID destination, + const Payload& payload) noexcept; + +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @param `origin` Origin state identifier + /// @param `destination` Destination state identifier + /// @param `payload` Payload + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + FFSM2_CONSTEXPR(14) bool changeWith (const StateID origin, + const StateID destination, + const Payload& payload) noexcept { return append(origin , destination , payload ); } + + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @tparam `TOrigin` Origin state type + /// @param `destination` Destination state identifier + /// @param `payload` Payload + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + template + FFSM2_CONSTEXPR(14) bool changeWith (const StateID destination, + const Payload& payload) noexcept { return append(PlanBase::template stateId(), destination , payload ); } + + /// @brief Prepend a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @tparam `TOrigin` Origin state type + /// @tparam `TDestination` Destination state type + /// @param `payload` Payload + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + template + FFSM2_CONSTEXPR(14) bool changeWith (const Payload& payload) noexcept { return append(PlanBase::template stateId(), PlanBase::template stateId(), payload ); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +private: + using PlanBase::_planData; +}; + +//------------------------------------------------------------------------------ + +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + , Long NTaskCapacity +> +class PayloadPlanT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , void + > + > final + : public PlanT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , void + > + > +{ + template + friend class R_; + + template + friend class PlanControlT; + + template + friend class FullControlT; + + template + friend class GuardControlT; + + using Args = ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , void + >; + + using PlanBase = PlanT; + + using PlanBase::PlanBase; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif + +#include "plan_2.inl" diff --git a/development/ffsm2/detail/root/plan_2.inl b/development/ffsm2/detail/root/plan_2.inl new file mode 100644 index 0000000..b9304a7 --- /dev/null +++ b/development/ffsm2/detail/root/plan_2.inl @@ -0,0 +1,25 @@ +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +bool +PayloadPlanT>::append(const StateID origin, + const StateID destination, + const Payload& payload) noexcept +{ + _planData.planExists = true; + + return linkTask(_planData.tasks.emplace(origin, destination, payload)); +} + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/development/ffsm2/detail/root/plan_data.hpp b/development/ffsm2/detail/root/plan_data.hpp index 2ca0c95..2c736cb 100644 --- a/development/ffsm2/detail/root/plan_data.hpp +++ b/development/ffsm2/detail/root/plan_data.hpp @@ -32,8 +32,6 @@ FFSM2_CONSTEXPR(14) TaskStatus& operator |= (TaskStatus& l, const TaskStatus r) #if FFSM2_PLANS_AVAILABLE() -#pragma pack(push, 1) - struct TaskLink final { Long prev = INVALID_LONG; Long next = INVALID_LONG; @@ -48,17 +46,15 @@ struct Bounds final { FFSM2_CONSTEXPR(14) void clear() noexcept { first = INVALID_LONG; last = INVALID_LONG; } }; -#pragma pack(pop) - //////////////////////////////////////////////////////////////////////////////// -template +template < + typename + , typename + FFSM2_IF_SERIALIZATION(, Long) + , Long + , typename +> struct ArgsT; template @@ -66,33 +62,35 @@ struct PlanDataT; //------------------------------------------------------------------------------ -template -struct PlanDataT> final +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + , Long NTaskCapacity + , typename TPayload +> +struct PlanDataT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , TPayload + > + > final { - using StateList = TStateList; - using Payload = TPayload; + using StateList = TStateList; + using Payload = TPayload; - static constexpr Long STATE_COUNT = StateList::SIZE; - static constexpr Short TASK_CAPACITY = NTaskCapacity; + static constexpr Long STATE_COUNT = StateList ::SIZE; + static constexpr Long TASK_CAPACITY = NTaskCapacity; - using Task = TaskT ; - using Tasks = TaskListT ; - using TaskLinks = StaticArrayT; - using Payloads = StaticArrayT; + using Task = TaskT ; + using Tasks = TaskListT ; + using TaskLinks = StaticArrayT; + using Payloads = StaticArrayT; - using TasksBits = BitArrayT; + using TasksBits = BitArrayT < STATE_COUNT>; Tasks tasks; TaskLinks taskLinks; @@ -120,30 +118,32 @@ struct PlanDataT -struct PlanDataT> final +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + , Long NTaskCapacity +> +struct PlanDataT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , void + > + > final { - using StateList = TStateList; + using StateList = TStateList; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList ::SIZE; static constexpr Long TASK_CAPACITY = NTaskCapacity; - using Task = TaskT; - using Tasks = TaskListT ; - using TaskLinks = StaticArrayT; + using Task = TaskT ; + using Tasks = TaskListT ; + using TaskLinks = StaticArrayT; - using TasksBits = BitArrayT; + using TasksBits = BitArrayT < STATE_COUNT>; Tasks tasks; TaskLinks taskLinks; diff --git a/development/ffsm2/detail/root/plan_data.inl b/development/ffsm2/detail/root/plan_data.inl index 4ec1a93..e961d34 100644 --- a/development/ffsm2/detail/root/plan_data.inl +++ b/development/ffsm2/detail/root/plan_data.inl @@ -44,7 +44,7 @@ operator |= (TaskStatus& lhs, const TaskStatus rhs) noexcept { const TaskStatus::Result result = lhs.result > rhs.result ? - lhs.result : rhs.result; + lhs.result : rhs.result; lhs = TaskStatus{result}; @@ -55,10 +55,10 @@ operator |= (TaskStatus& lhs, #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clearTaskStatus(const StateID stateId) noexcept { +PlanDataT>::clearTaskStatus(const StateID stateId) noexcept { if (stateId != INVALID_STATE_ID) { tasksSuccesses.clear(stateId); tasksFailures .clear(stateId); @@ -67,10 +67,10 @@ PlanDataT>::clea //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::verifyEmptyStatus(const StateID FFSM2_IF_ASSERT(stateId)) const noexcept { +PlanDataT>::verifyEmptyStatus(const StateID FFSM2_IF_ASSERT(stateId)) const noexcept { #if FFSM2_ASSERT_AVAILABLE() if (stateId != INVALID_STATE_ID) { @@ -83,20 +83,20 @@ PlanDataT>::veri //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clearRegionStatuses() noexcept { +PlanDataT>::clearRegionStatuses() noexcept { headStatus.clear(); - subStatus .clear(); + subStatus.clear(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clear() noexcept { +PlanDataT>::clear() noexcept { tasks .clear(); taskLinks .clear(); taskPayloads .clear(); @@ -116,10 +116,10 @@ PlanDataT>::clea //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) Long -PlanDataT>::verifyPlan() const noexcept { +PlanDataT>::verifyPlan() const noexcept { Long length = 0; const Bounds& bounds = tasksBounds; @@ -159,10 +159,10 @@ PlanDataT>::veri //////////////////////////////////////////////////////////////////////////////// -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clearTaskStatus(const StateID stateId) noexcept { +PlanDataT>::clearTaskStatus(const StateID stateId) noexcept { if (stateId != INVALID_STATE_ID) { tasksSuccesses.clear(stateId); tasksFailures .clear(stateId); @@ -171,10 +171,10 @@ PlanDataT>::cle //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::verifyEmptyStatus(const StateID FFSM2_IF_ASSERT(stateId)) const noexcept { +PlanDataT>::verifyEmptyStatus(const StateID FFSM2_IF_ASSERT(stateId)) const noexcept { #if FFSM2_ASSERT_AVAILABLE() if (stateId != INVALID_STATE_ID) { @@ -187,20 +187,20 @@ PlanDataT>::ver //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clearRegionStatuses() noexcept { +PlanDataT>::clearRegionStatuses() noexcept { headStatus.clear(); subStatus .clear(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clear() noexcept { +PlanDataT>::clear() noexcept { tasks .clear(); taskLinks .clear(); @@ -218,10 +218,10 @@ PlanDataT>::cle //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) Long -PlanDataT>::verifyPlan() const noexcept { +PlanDataT>::verifyPlan() const noexcept { Long length = 0; const Bounds& bounds = tasksBounds; diff --git a/development/ffsm2/detail/root/registry.hpp b/development/ffsm2/detail/root/registry.hpp index a003a66..1869cb7 100644 --- a/development/ffsm2/detail/root/registry.hpp +++ b/development/ffsm2/detail/root/registry.hpp @@ -3,24 +3,30 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// -template +template < + typename + , typename + FFSM2_IF_SERIALIZATION(, Long) + FFSM2_IF_PLANS(, Long) + , typename +> struct ArgsT; //------------------------------------------------------------------------------ struct Registry final { - FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return active != INVALID_SHORT; } + FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return active != INVALID_SHORT; } - FFSM2_CONSTEXPR(14) void clearRequests () noexcept { requested = INVALID_SHORT; } - FFSM2_CONSTEXPR(14) void clear () noexcept { requested = INVALID_SHORT; active = INVALID_SHORT; } + FFSM2_CONSTEXPR(14) bool isActive (const StateID stateId) const noexcept { + return stateId == 0 ? + active != INVALID_SHORT : + active == stateId; + } - FFSM2_CONSTEXPR(11) bool empty () const noexcept { return requested == INVALID_SHORT && active == INVALID_SHORT; } + FFSM2_CONSTEXPR(14) void clearRequests () noexcept { requested = INVALID_SHORT; } + FFSM2_CONSTEXPR(14) void clear () noexcept { requested = INVALID_SHORT; active = INVALID_SHORT; } + + FFSM2_CONSTEXPR(11) bool empty () const noexcept { return requested == INVALID_SHORT && active == INVALID_SHORT; } Short requested = INVALID_SHORT; Short active = INVALID_SHORT; diff --git a/development/ffsm2/detail/root_0.hpp b/development/ffsm2/detail/root_0.hpp new file mode 100644 index 0000000..85bfd03 --- /dev/null +++ b/development/ffsm2/detail/root_0.hpp @@ -0,0 +1,300 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + typename TConfig + , typename TApex +> +class R_ { +public: + static constexpr FeatureTag FEATURE_TAG = TConfig::FEATURE_TAG; + + using Context = typename TConfig::Context; + using Payload = typename TConfig::Payload; + +protected: + using Forward = RF_; + using StateList = typename Forward::StateList; + + using Args = typename Forward::Args; + using PureContext = typename Args::PureContext; + + static_assert(Args::STATE_COUNT < static_cast(-1), "Too many states in the FSM. Change 'Short' type."); + static_assert(Args::STATE_COUNT == static_cast(StateList::SIZE), "STATE_COUNT != StateList::SIZE"); + + using Core = CoreT; + + using Apex = MaterialT<0, Args, TApex>; + + using ConstControl = ConstControlT; + using Control = ControlT ; + using PlanControl = PlanControlT ; + using FullControl = FullControlT ; + using GuardControl = GuardControlT; + + static constexpr Short SUBSTITUTION_LIMIT = Forward::SUBSTITUTION_LIMIT; + +#if FFSM2_PLANS_AVAILABLE() + using PlanData = PlanDataT; +#endif + +public: +#if FFSM2_SERIALIZATION_AVAILABLE() + using WriteStream = typename Args::WriteStream; + using ReadStream = typename Args::ReadStream; +#endif + +public: + /// @brief Transition + using Transition = typename Core::Transition; + +#if FFSM2_PLANS_AVAILABLE() + using CPlan = CPlanT; + using Plan = PayloadPlanT; + + static constexpr Long TASK_CAPACITY = Forward::TASK_CAPACITY; +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using Logger = typename TConfig::LoggerInterface; +#endif + +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(11) explicit R_(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(11) explicit R_(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(NO) R_(const R_& ) noexcept = default; + FFSM2_CONSTEXPR(NO) R_( R_&&) noexcept = default; + + FFSM2_CONSTEXPR(20) ~R_() noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Access context + /// @return context + FFSM2_CONSTEXPR(14) Context& context() noexcept { return _core.context; } + + /// @brief Access context + /// @return context + FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Get state identifier for a state type + /// @tparam `TState` State type + /// @return Numeric state identifier + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index() ; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Access state instance + /// @tparam `TState` State type + /// @return State instance + template + FFSM2_CONSTEXPR(14) TState& access() noexcept { return static_cast< TState&>(_apex); } + + /// @brief Access state instance + /// @tparam `TState` State type + /// @return State instance + template + FFSM2_CONSTEXPR(11) const TState& access() const noexcept { return static_cast(_apex); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Trigger FSM update cycle (recursively call `update()` from the root down to the leaf states + /// on all active states then process requested transitions) + FFSM2_CONSTEXPR(14) void update() noexcept; + + /// @brief Have FSM react to an event (recursively call matching 'react<>()' from the root down to the leaf states + /// on all active states then process requested transitions) + /// @tparam `TEvent` Event type + /// @param `event` Event to react to + template + FFSM2_CONSTEXPR(14) void react(const TEvent& event) noexcept; + + /// @brief Recursively call 'query()' from the root down to the leaf states on all active states + /// @tparam `TEvent` Event type + /// @param `event` Event to react to + template + FFSM2_CONSTEXPR(14) void query(TEvent& event) const noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Get current active state ID + /// @return Current active state ID + FFSM2_CONSTEXPR(11) StateID activeStateId() const noexcept { return _core.registry.active; } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Check if a state is active + /// @param `stateId` Destination state identifier + /// @return State active status + FFSM2_CONSTEXPR(11) bool isActive(const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } + + /// @brief Check if a state is active + /// @tparam `TState` Destination state type + /// @return State active status + template + FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return _core.registry.active == stateId(); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_PLANS_AVAILABLE() + + /// @brief Access plan + /// @return Plan + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) Plan plan() noexcept { return Plan{_core.planData}; } + + /// @brief Access read-only plan + /// @return Read-only plan + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } + + /// @brief Succeed a plan task for a state + /// @param `stateId` State identifier + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void succeed(const StateID stateId_) noexcept; + + /// @brief Succeed a plan task for a state + /// @tparam `TState` State type + /// @see `FFSM2_ENABLE_PLANS` + template + FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed(stateId()); } + + /// @brief Fail a plan task for a state + /// @param `stateId` State identifier + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void fail (const StateID stateId_) noexcept; + + /// @brief Fail a plan task for a state + /// @tparam `TState` State type + /// @see `FFSM2_ENABLE_PLANS` + template + FFSM2_CONSTEXPR(14) void fail () noexcept { fail (stateId()); } + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // COMMON + + /// @brief Queue a transition into a state (takes effect during `immediate*()`, `update()` or `react()`) + /// @param `stateId` Destination state identifier + /// @see `immediateChangeTo()` + FFSM2_CONSTEXPR(14) void changeTo (const StateID stateId_) noexcept; + + /// @brief Queue a transition into a state (takes effect during `immediate*()`, `update()` or `react()`) + /// @tparam `TState` Destination state type + /// @see `immediateChangeTo()` + template + FFSM2_CONSTEXPR(14) void changeTo () noexcept { changeTo (stateId()); } + + // COMMON + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#if FFSM2_UTILITY_THEORY_AVAILABLE() + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#endif + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // COMMON + + /// @brief Transition into a state + /// (if transitioning into a region, acts depending on the region type) + /// @param `stateId` Destination state identifier + /// @see `changeTo()` + FFSM2_CONSTEXPR(14) void immediateChangeTo (const StateID stateId_) noexcept; + + /// @brief Transition into a state + /// @tparam `TState` Destination state type + /// @see `changeTo()` + template + FFSM2_CONSTEXPR(14) void immediateChangeTo () noexcept { immediateChangeTo (stateId()); } + + // COMMON + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + + /// @brief Get the transition recorded during last `update()` / `react()` + /// @return Array of last recorded transitions + /// @see FFSM2_ENABLE_TRANSITION_HISTORY + FFSM2_CONSTEXPR(11) const Transition& previousTransition() const noexcept { return _core.previousTransition; } + + /// @brief Force process a transition (skips `guard()` calls) + /// Can be used to synchronize multiple FSMs + /// @param `transition` 'Transition' to replay + /// @return Success status + /// @see FFSM2_ENABLE_TRANSITION_HISTORY + FFSM2_CONSTEXPR(14) bool replayTransition(const StateID destination) noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + + /// @brief Attach logger + /// @param `logger` A logger implementing 'ffsm2::LoggerInterfaceT<>' interface + /// @see FFSM2_ENABLE_LOG_INTERFACE + FFSM2_CONSTEXPR(14) void attachLogger(Logger* const logger) noexcept { _core.logger = logger; } + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +protected: + FFSM2_CONSTEXPR(14) void initialEnter() noexcept; + FFSM2_CONSTEXPR(14) void finalExit() noexcept; + + FFSM2_CONSTEXPR(14) void processRequest() noexcept; + FFSM2_CONSTEXPR(14) void processTransitions(Transition& currentTransition) noexcept; + + FFSM2_CONSTEXPR(14) bool applyRequest(const Transition& currentTransition, + const StateID destination) noexcept; + + FFSM2_CONSTEXPR(14) bool cancelledByEntryGuards(const Transition& currentTransition, + const Transition& pendingTransition) noexcept; + + FFSM2_CONSTEXPR(14) bool cancelledByGuards(const Transition& currentTransition, + const Transition& pendingTransition) noexcept; + +#if FFSM2_SERIALIZATION_AVAILABLE() + FFSM2_CONSTEXPR(14) void save(WriteStream& stream) const noexcept; + FFSM2_CONSTEXPR(14) void load( ReadStream& stream) noexcept; +#endif + +protected: + Core _core; + Apex _apex; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "root_0.inl" diff --git a/development/ffsm2/detail/root_0.inl b/development/ffsm2/detail/root_0.inl new file mode 100644 index 0000000..3ed1a57 --- /dev/null +++ b/development/ffsm2/detail/root_0.inl @@ -0,0 +1,441 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(11) +R_::R_(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept + : _core{context + FFSM2_IF_LOG_INTERFACE(, logger)} +{} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(11) +R_::R_(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept + : _core{move(context) + FFSM2_IF_LOG_INTERFACE(, logger)} +{} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(20) +R_::~R_() noexcept { + FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +void +R_::update() noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + + Transition emptyTransition; + FullControl control{_core, emptyTransition}; + + _apex. deepPreUpdate(control); + _apex. deepUpdate(control); + _apex.deepPostUpdate(control); + +#if FFSM2_PLANS_AVAILABLE() + _apex.deepUpdatePlans(control); + _core.planData.clearRegionStatuses(); +#endif + + processRequest(); +} + +//------------------------------------------------------------------------------ + +template +template +FFSM2_CONSTEXPR(14) +void +R_::react(const TEvent& event) noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + + Transition emptyTransition; + FullControl control{_core, emptyTransition}; + + _apex. deepPreReact(control, event); + _apex. deepReact(control, event); + _apex.deepPostReact(control, event); + +#if FFSM2_PLANS_AVAILABLE() + _apex.deepUpdatePlans(control); + _core.planData.clearRegionStatuses(); +#endif + + processRequest(); +} + +//------------------------------------------------------------------------------ + +template +template +FFSM2_CONSTEXPR(14) +void +R_::query(TEvent& event) const noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + + ConstControl control{_core}; + + _apex.deepQuery(control, event); +} + +//------------------------------------------------------------------------------ + +#if FFSM2_PLANS_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +void +R_::succeed(const StateID stateId_) noexcept { + _core.planData.tasksSuccesses.set(stateId_); + + FFSM2_LOG_TASK_STATUS(_core.context, stateId_, StatusEvent::SUCCEEDED); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +R_::fail(const StateID stateId_) noexcept { + _core.planData.tasksFailures.set(stateId_); + + FFSM2_LOG_TASK_STATUS(_core.context, stateId_, StatusEvent::FAILED); +} + +#endif + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +void +R_::changeTo(const StateID stateId_) noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + + _core.request = Transition{stateId_}; + + FFSM2_LOG_TRANSITION(_core.context, INVALID_STATE_ID, stateId_); +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +void +R_::immediateChangeTo(const StateID stateId_) noexcept { + changeTo(stateId_); + + processRequest(); +} + +//------------------------------------------------------------------------------ + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +bool +R_::replayTransition(const StateID destination) noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + + _core.previousTransition.clear(); + + if (FFSM2_CHECKED(destination != INVALID_SHORT)) { + Transition currentTransition; + PlanControl control{_core, currentTransition}; + + applyRequest(currentTransition, + destination); + + _core.previousTransition = Transition{destination}; + + _apex.deepChangeToRequested(control); + + _core.registry.clearRequests(); + + FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); + + return true; + } + + return false; +} + +#endif + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +void +R_::initialEnter() noexcept { + FFSM2_ASSERT(!_core.registry.isActive()); + FFSM2_ASSERT(!_core.request); + FFSM2_IF_TRANSITION_HISTORY(FFSM2_ASSERT(!_core.previousTransition)); + + Transition currentTransition; + Transition pendingTransition; + + PlanControl control{_core, currentTransition}; + applyRequest(currentTransition, 0); + + cancelledByEntryGuards(currentTransition, + pendingTransition); + + for (Long i = 0; + i < SUBSTITUTION_LIMIT && _core.request; + ++i) + { + //backup(); + + if (applyRequest(currentTransition, + _core.request.destination)) + { + pendingTransition = _core.request; + _core.request.clear(); + + if (cancelledByEntryGuards(currentTransition, + pendingTransition)) + FFSM2_BREAK(); + else + currentTransition = pendingTransition; + + pendingTransition.clear(); + } else + _core.request.clear(); + } + FFSM2_ASSERT(!_core.request); + FFSM2_IF_TRANSITION_HISTORY(_core.previousTransition = currentTransition); + + _apex.deepEnter(control); + + _core.registry.clearRequests(); + + FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +R_::finalExit() noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + FFSM2_ASSERT(!_core.request); + + Transition emptyTransition; + PlanControl control{_core, emptyTransition}; + + _apex.deepExit(control); + + _core.registry.clear(); + _core.request .clear(); + +#if FFSM2_PLANS_AVAILABLE() + _core.planData.clear(); +#endif + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + _core.previousTransition.clear(); +#endif +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +void +R_::processRequest() noexcept { + FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); + + Transition currentTransition; + + if (_core.request) { + processTransitions(currentTransition); + + FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); + } + + FFSM2_IF_TRANSITION_HISTORY(_core.previousTransition = currentTransition); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +R_::processTransitions(Transition& currentTransition) noexcept { + FFSM2_ASSERT(_core.request); + + PlanControl control{_core, currentTransition}; + + Transition pendingTransition; + + for (Long i = 0; + i < SUBSTITUTION_LIMIT && _core.request; + ++i) + { + //backup(); + + if (applyRequest(currentTransition, + _core.request.destination)) + { + pendingTransition = _core.request; + _core.request.clear(); + + if (cancelledByGuards(currentTransition, + pendingTransition)) + ; + else + currentTransition = pendingTransition; + + pendingTransition.clear(); + } else + _core.request.clear(); + } + FFSM2_ASSERT(!_core.request); + + if (currentTransition) + _apex.deepChangeToRequested(control); + + _core.registry.clearRequests(); +} + +// COMMON +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +bool +R_::applyRequest(const Transition& currentTransition, + const StateID destination) noexcept +{ + if (currentTransition != Transition{destination}) { + _core.registry.requested = destination; + + return true; + } else + return false; +} + +//------------------------------------------------------------------------------ +// COMMON + +template +FFSM2_CONSTEXPR(14) +bool +R_::cancelledByEntryGuards(const Transition& currentTransition, + const Transition& pendingTransition) noexcept +{ + GuardControl guardControl{_core + , currentTransition + , pendingTransition}; + + return _apex.deepEntryGuard(guardControl); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +bool +R_::cancelledByGuards(const Transition& currentTransition, + const Transition& pendingTransition) noexcept +{ + GuardControl guardControl{_core + , currentTransition + , pendingTransition}; + + return _apex.deepForwardExitGuard (guardControl) || + _apex.deepForwardEntryGuard(guardControl); +} + +//------------------------------------------------------------------------------ + +#if FFSM2_SERIALIZATION_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +void +R_::save(WriteStream& stream) const noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + + _apex.deepSaveActive(_core.registry, stream); + + // TODO: save(stream, _core.requests); + +#if FFSM2_PLANS_AVAILABLE() + // TODO: save(stream, _core.planData); +#endif + +#if FFSM2_UTILITY_THEORY_AVAILABLE() + // TODO: save(stream, _core.rng); +#endif + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + // TODO: save(stream, _core.transitionTarget); + // TODO: save(stream, _core.previousTransition); +#endif +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +R_::load(ReadStream& stream) noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + + _core.registry.clearRequests(); + _apex.deepLoadRequested(_core.registry, stream); + + _core.request.clear(); + // TODO: load(stream, _core.requests); + +#if FFSM2_PLANS_AVAILABLE() + _core.planData.clear(); + // TODO: load(stream, _core.planData); +#endif + +#if FFSM2_UTILITY_THEORY_AVAILABLE() + // TODO: load(stream, _core.rng); +#endif + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + _core.previousTransition.clear(); +#endif + + Transition emptyTransition; + PlanControl control{_core, emptyTransition}; + + _apex.deepChangeToRequested(control); +} + +#endif + +//------------------------------------------------------------------------------ + +#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#endif + +//------------------------------------------------------------------------------ + +#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#endif + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/root_1.hpp b/development/ffsm2/detail/root_1.hpp new file mode 100644 index 0000000..7da1ab5 --- /dev/null +++ b/development/ffsm2/detail/root_1.hpp @@ -0,0 +1,271 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +// Automatic / manual [de]activation + +template < + typename + , typename +> +class RV_; + +//------------------------------------------------------------------------------ +// Automatic enter() / exit() + +template < + FeatureTag NFeatureTag + , typename TContext + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES RV_< + G_< + NFeatureTag + , TContext + , Automatic + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > + : public R_ < + G_< + NFeatureTag + , TContext + , Automatic + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = R_ < + G_< + NFeatureTag + , TContext + , Automatic + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +protected: + using typename Base::Context; + using typename Base::PureContext; + +#if FFSM2_SERIALIZATION_AVAILABLE() + using typename Base::Args; + using typename Base::WriteStream; + using typename Base::ReadStream; +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + FFSM2_CONSTEXPR(14) explicit RV_(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(14) explicit RV_(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(14) RV_(const RV_& other) noexcept; + FFSM2_CONSTEXPR(14) RV_( RV_&& other) noexcept; + + FFSM2_CONSTEXPR(20) ~RV_() noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_SERIALIZATION_AVAILABLE() + + /// @brief Buffer for serialization + /// @see `FFSM2_ENABLE_SERIALIZATION` + using SerialBuffer = typename Args::SerialBuffer; + + /// @brief Serialize FSM into 'buffer' + /// @param buffer `SerialBuffer` to serialize to + /// @see `FFSM2_ENABLE_SERIALIZATION` + FFSM2_CONSTEXPR(14) void save( SerialBuffer& buffer) const noexcept; + + /// @brief De-serialize FSM from 'buffer' + /// @param buffer `SerialBuffer` to de-serialize from + /// @see `FFSM2_ENABLE_SERIALIZATION` + FFSM2_CONSTEXPR(14) void load(const SerialBuffer& buffer) noexcept; + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +private: +#if FFSM2_SERIALIZATION_AVAILABLE() + using Base::save; + using Base::load; +#endif + +private: + using Base::initialEnter; + using Base::finalExit; + +protected: +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + using Base::_core; + using Base::_apex; +#endif +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Manual enter() / exit() + +template < + FeatureTag NFeatureTag + , typename TContext + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES RV_< + G_< + NFeatureTag + , TContext + , Manual + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > + : public R_< + G_< + NFeatureTag + , TContext + , Manual + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = R_< + G_< + NFeatureTag + , TContext + , Manual + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +protected: +#if FFSM2_SERIALIZATION_AVAILABLE() + using typename Base::PlanControl; + + using typename Base::Args; + using typename Base::WriteStream; + using typename Base::ReadStream; +#endif + +public: + using typename Base::Transition; + +private: +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + using typename Base::PlanControl; +#endif + +public: + using Base::Base; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Check if FSM is active + /// @return FSM active status + FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return _core.registry.isActive(); } + + using Base::isActive; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Manually start the FSM + /// Can be used with UE4 to start / stop the FSM in `BeginPlay()` / `EndPlay()` + FFSM2_CONSTEXPR(14) void enter() noexcept { initialEnter(); } + + /// @brief Manually stop the FSM + /// Can be used with UE4 to start / stop the FSM in `BeginPlay()` / `EndPlay()` + FFSM2_CONSTEXPR(14) void exit() noexcept { finalExit(); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_SERIALIZATION_AVAILABLE() + + /// @brief Buffer for serialization + /// @see `FFSM2_ENABLE_SERIALIZATION` + using SerialBuffer = typename Args::SerialBuffer; + + /// @brief Serialize FSM into 'buffer' + /// @param buffer `SerialBuffer` to serialize to + /// @see `FFSM2_ENABLE_SERIALIZATION` + FFSM2_CONSTEXPR(14) void save( SerialBuffer& buffer) const noexcept; + + /// @brief De-serialize FSM from 'buffer' + /// @param buffer `SerialBuffer` to de-serialize from + /// @see `FFSM2_ENABLE_SERIALIZATION` + FFSM2_CONSTEXPR(14) void load(const SerialBuffer& buffer) noexcept; + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + + /// @brief Start the FSM from a specific state + /// Can be used with UE4 USTRUCT() NetSerialize() to load replicated FSM from FArchive + /// @param `destination` Transition destination + /// @see `FFSM2_ENABLE_TRANSITION_HISTORY` + FFSM2_CONSTEXPR(14) void replayEnter(const StateID destination) noexcept; + +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +private: +#if FFSM2_SERIALIZATION_AVAILABLE() + using Base::save; + using Base::load; + + FFSM2_CONSTEXPR(14) void loadEnter(ReadStream& stream) noexcept; +#endif + +protected: + using Base::initialEnter; + using Base::finalExit; + + using Base::_core; + +#if FFSM2_SERIALIZATION_AVAILABLE() || FFSM2_TRANSITION_HISTORY_AVAILABLE() + using Base::_apex; +#endif + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + using Base::applyRequest; +#endif +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "root_1.inl" diff --git a/development/ffsm2/detail/root_1.inl b/development/ffsm2/detail/root_1.inl new file mode 100644 index 0000000..4f257bb --- /dev/null +++ b/development/ffsm2/detail/root_1.inl @@ -0,0 +1,182 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(14) +RV_, TA_>::RV_(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept + : Base{context + FFSM2_IF_LOG_INTERFACE(, logger)} +{ + initialEnter(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +RV_, TA_>::RV_(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept + : Base{move(context) + FFSM2_IF_LOG_INTERFACE(, logger)} +{ + initialEnter(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +RV_, TA_>::RV_(const RV_& other) noexcept + : Base{other} +{} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +RV_, TA_>::RV_(RV_&& other) noexcept + : Base{move(other)} +{} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(20) +RV_, TA_>::~RV_() noexcept { + finalExit(); +} + +//------------------------------------------------------------------------------ + +#if FFSM2_SERIALIZATION_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +void +RV_, TA_>::save(SerialBuffer& buffer) const noexcept { + WriteStream stream{buffer}; + + stream.template write<1>(1); + save(stream); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +RV_, TA_>::load(const SerialBuffer& buffer) noexcept { + ReadStream stream{buffer}; + + if (FFSM2_CHECKED(stream.template read<1>())) + Base::load(stream); +} + +#endif + +//////////////////////////////////////////////////////////////////////////////// + +#if FFSM2_SERIALIZATION_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +void +RV_, TA_>::save(SerialBuffer& buffer) const noexcept { + WriteStream stream{buffer}; + + if (isActive()) { + stream.template write<1>(1); + + save(stream); + } + else + stream.template write<1>(0); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +RV_, TA_>::load(const SerialBuffer& buffer) noexcept { + ReadStream stream{buffer}; + + if (stream.template read<1>()) { + if (isActive()) + Base::load(stream); + else + loadEnter (stream); + } + else + if (isActive()) + finalExit(); +} + +#endif + +//------------------------------------------------------------------------------ + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +void +RV_, TA_>::replayEnter(const StateID destination) noexcept { + FFSM2_ASSERT(_core.registry.active == INVALID_SHORT); + FFSM2_ASSERT(!_core.request); + FFSM2_IF_TRANSITION_HISTORY(FFSM2_ASSERT(!_core.previousTransition)); + + Transition currentTransition; + PlanControl control{_core, currentTransition}; + + applyRequest(currentTransition, + destination); + + FFSM2_IF_TRANSITION_HISTORY(_core.previousTransition = Transition{destination}); + + _apex.deepEnter(control); + + _core.registry.clearRequests(); + + FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); +} + +#endif + +//------------------------------------------------------------------------------ + +#if FFSM2_SERIALIZATION_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +void +RV_, TA_>::loadEnter(ReadStream& stream) noexcept { + FFSM2_ASSERT(_core.registry.empty()); + _apex.deepLoadRequested(_core.registry, stream); + + FFSM2_ASSERT(!_core.request); + +#if FFSM2_PLANS_AVAILABLE() + FFSM2_ASSERT(_core.planData.empty() == 0); +#endif + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + FFSM2_ASSERT(_core.transitionTargets .empty()); + FFSM2_ASSERT(_core.previousTransitions.empty()); +#endif + + Transition emptyTransition; + PlanControl control{_core, emptyTransition}; + + _apex.deepEnter(control); +} + +#endif + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/root_2.hpp b/development/ffsm2/detail/root_2.hpp new file mode 100644 index 0000000..aa230f8 --- /dev/null +++ b/development/ffsm2/detail/root_2.hpp @@ -0,0 +1,182 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template < + typename + , typename +> +class RP_; + +//------------------------------------------------------------------------------ +// Non-'void' payloads + +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES RP_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > + : public RV_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = RV_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + + using Transition = TransitionT; + +public: + using typename Base::Payload; + +public: + using Base::Base; + using Base::processRequest; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// @brief Get state identifier for a state type + /// @tparam `TState` State type + /// @return Numeric state identifier + template + static constexpr StateID stateId() noexcept { return Base::template stateId(); } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // COMMON + + /// @brief Queue a transition into a state (takes effect during `immediate*()`, `update()` or `react()`) + /// @param `stateId` Destination state identifier + /// @param `payload` Payload + FFSM2_CONSTEXPR(14) void changeWith (const StateID stateId_, + const Payload& payload) noexcept; + + /// @brief Queue a transition into a state (takes effect during `immediate*()`, `update()` or `react()`) + /// @tparam `TState` Destination state type + /// @param `payload` Payload + template + FFSM2_CONSTEXPR(14) void changeWith (const Payload& payload) noexcept { changeWith(stateId(), payload ); } + + // COMMON + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // COMMON + + /// @brief Transition into a state + /// @param `stateId` Destination state identifier + /// @param `payload` Payload + /// @see `changeWith()` + FFSM2_CONSTEXPR(14) void immediateChangeWith (const StateID stateId_, + const Payload& payload) noexcept; + + /// @brief Transition into a state + /// @tparam `TState` Destination state type + /// @param `payload` Payload + /// @see `changeWith()` + template + FFSM2_CONSTEXPR(14) void immediateChangeWith (const Payload& payload) noexcept { immediateChangeWith (stateId(), payload ); } + + // COMMON + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_UTILITY_THEORY_AVAILABLE() + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +protected: + using Base::_core; +}; + +//------------------------------------------------------------------------------ + +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TApex +> +class FFSM2_EMPTY_BASES RP_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + , TApex + > + : public RV_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + , TApex + > +{ + using Base = RV_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + , TApex + >; + +public: + using Base::Base; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "root_2.inl" diff --git a/development/ffsm2/detail/root_2.inl b/development/ffsm2/detail/root_2.inl new file mode 100644 index 0000000..f835888 --- /dev/null +++ b/development/ffsm2/detail/root_2.inl @@ -0,0 +1,42 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// +// COMMON + +template +FFSM2_CONSTEXPR(14) +void +RP_, TA_>::changeWith(const StateID stateId_, + const Payload& payload) noexcept +{ + FFSM2_ASSERT(_core.registry.isActive()); + + _core.request = Transition{stateId_, payload}; + + FFSM2_LOG_TRANSITION(_core.context, INVALID_STATE_ID, stateId_); +} + +// COMMON +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +RP_, TA_>::immediateChangeWith(const StateID stateId_, + const Payload& payload) noexcept +{ + changeWith(stateId_, payload); + + processRequest(); +} + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/root_3.hpp b/development/ffsm2/detail/root_3.hpp new file mode 100644 index 0000000..8522f21 --- /dev/null +++ b/development/ffsm2/detail/root_3.hpp @@ -0,0 +1,295 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + typename + , typename +> +class InstanceT; + +//------------------------------------------------------------------------------ +// TContext + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES InstanceT< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > final + : public RP_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = RP_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +public: + static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + + using typename Base::Context; + using typename Base::PureContext; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + FFSM2_CONSTEXPR(11) explicit InstanceT(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(11) explicit InstanceT(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(NO) InstanceT(const InstanceT& ) noexcept = default; + FFSM2_CONSTEXPR(NO) InstanceT( InstanceT&&) noexcept = default; + +private: + using Base::_core; +}; + +//------------------------------------------------------------------------------ +// TContext& + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES InstanceT< + G_< + NFeatureTag + , TContext& + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > final + : public RP_< + G_< + NFeatureTag + , TContext& + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = RP_< + G_< + NFeatureTag + , TContext& + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +public: + static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + + using typename Base::Context; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + using Base::Base; + +private: + using Base::_core; +}; + +//------------------------------------------------------------------------------ +// TContext* + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES InstanceT< + G_< + NFeatureTag + , TContext* + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > final + : public RP_< + G_< + NFeatureTag + , TContext* + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = RP_< + G_< + NFeatureTag + , TContext* + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +public: + static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + + using typename Base::Context; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + FFSM2_CONSTEXPR(11) explicit InstanceT(Context context = nullptr + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(NO) InstanceT(const InstanceT& ) noexcept = default; + FFSM2_CONSTEXPR(NO) InstanceT( InstanceT&&) noexcept = default; + + FFSM2_CONSTEXPR(14) void setContext(Context context) noexcept { _core.context = context; } + +private: + using Base::_core; +}; + +//------------------------------------------------------------------------------ +// TContext == EmptyContext + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + FeatureTag NFeatureTag + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES InstanceT< + G_< + NFeatureTag + , EmptyContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > final + : public RP_< + G_< + NFeatureTag + , EmptyContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > + , public EmptyContext +{ + using Base = RP_< + G_< + NFeatureTag + , EmptyContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +public: + static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + FFSM2_CONSTEXPR(11) explicit InstanceT(FFSM2_IF_LOG_INTERFACE(Logger* const logger = nullptr)) noexcept; + + using Base::Base; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "root_3.inl" diff --git a/development/ffsm2/detail/root_3.inl b/development/ffsm2/detail/root_3.inl new file mode 100644 index 0000000..b9854b0 --- /dev/null +++ b/development/ffsm2/detail/root_3.inl @@ -0,0 +1,46 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(11) +InstanceT, TA_>::InstanceT(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept + : Base{context + FFSM2_IF_LOG_INTERFACE(, logger)} +{} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(11) +InstanceT, TA_>::InstanceT(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept + : Base{move(context) + FFSM2_IF_LOG_INTERFACE(, logger)} +{} + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(11) +InstanceT, TA_>::InstanceT(Context context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept + : Base{context + FFSM2_IF_LOG_INTERFACE(, logger)} +{} + +//////////////////////////////////////////////////////////////////////////////// + +template +FFSM2_CONSTEXPR(11) +InstanceT, TA_>::InstanceT(FFSM2_IF_LOG_INTERFACE(Logger* const logger)) noexcept + : Base{static_cast(*this) + FFSM2_IF_LOG_INTERFACE(, logger)} +{} + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/shared/bit_stream.inl b/development/ffsm2/detail/shared/bit_stream.inl index 94abc73..23b7211 100644 --- a/development/ffsm2/detail/shared/bit_stream.inl +++ b/development/ffsm2/detail/shared/bit_stream.inl @@ -5,10 +5,10 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// -template +template FFSM2_CONSTEXPR(14) bool -StreamBufferT::operator == (const StreamBuffer& buffer) const noexcept { +StreamBufferT::operator == (const StreamBuffer& buffer) const noexcept { for (Long i = 0; i < BYTE_COUNT; ++i) if (_data[i] != buffer._data[i]) return false; @@ -18,10 +18,10 @@ StreamBufferT::operator == (const StreamBuffer& buffer) const noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) bool -StreamBufferT::operator != (const StreamBuffer& buffer) const noexcept { +StreamBufferT::operator != (const StreamBuffer& buffer) const noexcept { for (Long i = 0; i < BYTE_COUNT; ++i) if (_data[i] != buffer._data[i]) return true; @@ -31,11 +31,11 @@ StreamBufferT::operator != (const StreamBuffer& buffer) const noexcept { //////////////////////////////////////////////////////////////////////////////// -template +template template FFSM2_CONSTEXPR(14) void -BitWriteStreamT::write(const UBitWidth item) noexcept { +BitWriteStreamT::write(const UBitWidth item) noexcept { constexpr Short BIT_WIDTH = NBitWidth; static_assert(BIT_WIDTH > 0, "STATIC ASSERT"); @@ -63,11 +63,11 @@ BitWriteStreamT::write(const UBitWidth item) noexcept { //////////////////////////////////////////////////////////////////////////////// -template +template template FFSM2_CONSTEXPR(14) UBitWidth -BitReadStreamT::read() noexcept { +BitReadStreamT::read() noexcept { constexpr Short BIT_WIDTH = NBitWidth; static_assert(BIT_WIDTH > 0, "STATIC ASSERT"); diff --git a/development/ffsm2/detail/shared/iterator.hpp b/development/ffsm2/detail/shared/iterator.hpp index 31f5bf4..836b29f 100644 --- a/development/ffsm2/detail/shared/iterator.hpp +++ b/development/ffsm2/detail/shared/iterator.hpp @@ -11,7 +11,7 @@ class IteratorT { using Index = typename Container::Index; template - friend class ArrayT; + friend class DynamicArrayT; private: FFSM2_CONSTEXPR(11) IteratorT(Container& container, @@ -55,7 +55,7 @@ class IteratorT { using Index = typename Container::Index; template - friend class ArrayT; + friend class DynamicArrayT; private: FFSM2_CONSTEXPR(11) IteratorT(const Container& container, diff --git a/development/ffsm2/detail/shared/macros_off.hpp b/development/ffsm2/detail/shared/macros_off.hpp index 9ed307d..f218d46 100644 --- a/development/ffsm2/detail/shared/macros_off.hpp +++ b/development/ffsm2/detail/shared/macros_off.hpp @@ -16,49 +16,105 @@ //#undef FFSM2_UNUSED +//------------------------------------------------------------------------------ + #undef FFSM2_ATTRIBUTE + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_ATTRIBUTE_FALLTHROUGH + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_ATTRIBUTE_NO_UNIQUE_ADDRESS +//------------------------------------------------------------------------------ + #undef FFSM2_CONSTEXPR + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_CONSTEXPR_NO + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_CONSTEXPR_11 + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_CONSTEXPR_14 + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_CONSTEXPR_17 + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_CONSTEXPR_20 +//------------------------------------------------------------------------------ + +//#undef FFSM2_EMPTY_BASES + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + //#undef FFSM2_BREAK #undef FFSM2_BREAK_AVAILABLE +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_IF_DEBUG #undef FFSM2_UNLESS_DEBUG #undef FFSM2_DEBUG_OR +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_ASSERT_AVAILABLE #undef FFSM2_IF_ASSERT //#undef FFSM2_CHECKED #undef FFSM2_ASSERT #undef FFSM2_ASSERT_OR +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------ + #undef FFSM2_IF_TYPEINDEX #undef FFSM2_TYPEINDEX_AVAILABLE #undef FFSM2_IF_TYPEINDEX +//------------------------------------------------------------------------------ + //#undef FFSM2_DEBUG_STATE_TYPE_AVAILABLE +//------------------------------------------------------------------------------ + //#undef FFSM2_PLANS_AVAILABLE #undef FFSM2_IF_PLANS +//------------------------------------------------------------------------------ + //#undef FFSM2_SERIALIZATION_AVAILABLE #undef FFSM2_IF_SERIALIZATION +//------------------------------------------------------------------------------ + //#undef FFSM2_STRUCTURE_REPORT_AVAILABLE //#undef FFSM2_IF_STRUCTURE_REPORT +//------------------------------------------------------------------------------ + //#undef FFSM2_TRANSITION_HISTORY_AVAILABLE #undef FFSM2_IF_TRANSITION_HISTORY +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + #undef FFSM2_VERBOSE_DEBUG_LOG_AVAILABLE + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #undef FFSM2_LOG_INTERFACE_AVAILABLE #undef FFSM2_IF_LOG_INTERFACE diff --git a/development/ffsm2/detail/shared/macros_on.hpp b/development/ffsm2/detail/shared/macros_on.hpp index 5bc0e84..5275ace 100644 --- a/development/ffsm2/detail/shared/macros_on.hpp +++ b/development/ffsm2/detail/shared/macros_on.hpp @@ -74,6 +74,7 @@ #define FFSM2_EMPTY_BASES #endif +//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ #if defined _DEBUG && defined _MSC_VER @@ -112,6 +113,7 @@ #define FFSM2_ASSERT_OR(y, n) n #endif +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //////////////////////////////////////////////////////////////////////////////// #ifdef FFSM2_ENABLE_ALL @@ -262,16 +264,22 @@ if (auto* const logger = control._core.logger) \ logger->recordMethod(control.context(), STATE_ID, METHOD_ID) + #define FFSM2_IF_LOG_STATE_METHOD(...) __VA_ARGS__ + #elif FFSM2_LOG_INTERFACE_AVAILABLE() #define FFSM2_LOG_STATE_METHOD(METHOD, METHOD_ID) \ if (auto* const logger = control._core.logger) \ log(METHOD, *logger, control.context(), METHOD_ID) + #define FFSM2_IF_LOG_STATE_METHOD(...) __VA_ARGS__ + #else #define FFSM2_LOG_STATE_METHOD(METHOD, METHOD_ID) + #define FFSM2_IF_LOG_STATE_METHOD(...) + #endif //////////////////////////////////////////////////////////////////////////////// diff --git a/development/ffsm2/detail/shared/type_list.hpp b/development/ffsm2/detail/shared/type_list.hpp index 38c3a3d..a408c64 100644 --- a/development/ffsm2/detail/shared/type_list.hpp +++ b/development/ffsm2/detail/shared/type_list.hpp @@ -110,8 +110,8 @@ struct FindImpl {}; template -struct FindImpl - : FindImpl +struct FindImpl + : FindImpl {}; template diff --git a/development/ffsm2/detail/shared/utility.hpp b/development/ffsm2/detail/shared/utility.hpp index 48297ec..f6bbb83 100644 --- a/development/ffsm2/detail/shared/utility.hpp +++ b/development/ffsm2/detail/shared/utility.hpp @@ -2,7 +2,6 @@ namespace ffsm2 { //------------------------------------------------------------------------------ -struct EmptyContext {}; struct EmptyPayload final {}; struct Automatic; @@ -13,48 +12,43 @@ struct Manual; using Short = uint8_t; static constexpr Short INVALID_SHORT = UINT8_MAX; +using Prong = Short; +static constexpr Prong INVALID_PRONG = INVALID_SHORT; + using Long = uint8_t; static constexpr Long INVALID_LONG = UINT8_MAX; using StateID = Long; static constexpr StateID INVALID_STATE_ID = INVALID_LONG; -//------------------------------------------------------------------------------ - //////////////////////////////////////////////////////////////////////////////// -template +template < + bool B + , typename TT + , typename TF +> struct ConditionalT final { using Type = TT; }; -template +template < + typename TT + , typename TF +> struct ConditionalT final { using Type = TF; }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template < + bool B + , typename TT + , typename TF +> using Conditional = typename ConditionalT::Type; -//------------------------------------------------------------------------------ - -template -struct IsSameT final { - static constexpr bool Value = false; -}; - -template -struct IsSameT final { - static constexpr bool Value = true; -}; - //////////////////////////////////////////////////////////////////////////////// template @@ -257,6 +251,7 @@ contain(const T x, return (x + static_cast(to) - 1) / static_cast(to); } +//------------------------------------------------------------------------------ //////////////////////////////////////////////////////////////////////////////// template @@ -266,6 +261,7 @@ fill(T& a, const char value) noexcept { memset(&a, static_cast(value), sizeof(a)); } +//------------------------------------------------------------------------------ //////////////////////////////////////////////////////////////////////////////// template diff --git a/development/ffsm2/detail/structure/ancestors.hpp b/development/ffsm2/detail/structure/ancestors.hpp deleted file mode 100644 index cbe5293..0000000 --- a/development/ffsm2/detail/structure/ancestors.hpp +++ /dev/null @@ -1,235 +0,0 @@ -namespace ffsm2 { -namespace detail { - -//////////////////////////////////////////////////////////////////////////////// - -template -class B_ { - template - friend struct A_; - -protected: - using Context = typename TArgs::Context; - - using StateList = typename TArgs::StateList; - - using ConstControl = ConstControlT; - using Control = ControlT ; - using PlanControl = PlanControlT ; - -#if FFSM2_PLANS_AVAILABLE() - using Plan = PlanT; -#endif - - using FullControl = FullControlT ; - using GuardControl = GuardControlT; - -public: - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(14) void entryGuard (GuardControl& ) noexcept {} - - FFSM2_CONSTEXPR(14) void enter ( PlanControl& ) noexcept {} - FFSM2_CONSTEXPR(14) void reenter ( PlanControl& ) noexcept {} - - FFSM2_CONSTEXPR(14) void preUpdate ( FullControl& ) noexcept {} - FFSM2_CONSTEXPR(14) void update ( FullControl& ) noexcept {} - FFSM2_CONSTEXPR(14) void postUpdate ( FullControl& ) noexcept {} - - template - FFSM2_CONSTEXPR(14) void preReact (const TEvent& , - FullControl& ) noexcept {} - - template - FFSM2_CONSTEXPR(14) void react (const TEvent& , - FullControl& ) noexcept {} - - template - FFSM2_CONSTEXPR(14) void postReact (const TEvent& , - FullControl& ) noexcept {} - - template - FFSM2_CONSTEXPR(14) void query ( TEvent& , - ConstControl& ) const noexcept {} - - FFSM2_CONSTEXPR(14) void exitGuard (GuardControl& ) noexcept {} - - FFSM2_CONSTEXPR(14) void exit ( PlanControl& ) noexcept {} - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template - static constexpr StateID stateId() noexcept { return index(); } -}; - -//////////////////////////////////////////////////////////////////////////////// - -template -struct A_; - -//------------------------------------------------------------------------------ - -template -struct FFSM2_EMPTY_BASES A_ - : TFirst - , A_ -{ - using typename TFirst::Context; - - using typename TFirst::StateList; - - using typename TFirst::ConstControl; - using typename TFirst::Control; - using typename TFirst::PlanControl; - -#if FFSM2_PLANS_AVAILABLE() - using typename TFirst::Plan; -#endif - - using typename TFirst::FullControl; - using typename TFirst::GuardControl; - - using TFirst::stateId; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(14) void wideEntryGuard(GuardControl& control) noexcept; - - FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control) noexcept; - FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control) noexcept; - - FFSM2_CONSTEXPR(14) void widePreUpdate ( FullControl& control) noexcept; - FFSM2_CONSTEXPR(14) void wideUpdate ( FullControl& control) noexcept; - FFSM2_CONSTEXPR(14) void widePostUpdate( FullControl& control) noexcept; - - template - FFSM2_CONSTEXPR(14) void widePreReact (const TEvent& event , - FullControl& control) noexcept; - - template - FFSM2_CONSTEXPR(14) void wideReact (const TEvent& event , - FullControl& control) noexcept; - - template - FFSM2_CONSTEXPR(14) void widePostReact (const TEvent& event , - FullControl& control) noexcept; - - template - FFSM2_CONSTEXPR(14) void wideQuery ( TEvent& event , - ConstControl& control) const noexcept; - - FFSM2_CONSTEXPR(14) void wideExitGuard (GuardControl& control) noexcept; - - FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control) noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -}; - -//------------------------------------------------------------------------------ - -template -struct A_ - : TFirst -{ - using typename TFirst::Context; - - using typename TFirst::StateList; - - using typename TFirst::ConstControl; - using typename TFirst::Control; - using typename TFirst::PlanControl; - -#if FFSM2_PLANS_AVAILABLE() - using typename TFirst::Plan; -#endif - - using typename TFirst::FullControl; - using typename TFirst::GuardControl; - - using TFirst::stateId; - -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(14) void entryGuard (GuardControl& ) noexcept {} - - FFSM2_CONSTEXPR(14) void enter ( PlanControl& ) noexcept {} - FFSM2_CONSTEXPR(14) void reenter ( PlanControl& ) noexcept {} - - FFSM2_CONSTEXPR(14) void preUpdate ( FullControl& ) noexcept {} - FFSM2_CONSTEXPR(14) void update ( FullControl& ) noexcept {} - FFSM2_CONSTEXPR(14) void postUpdate ( FullControl& ) noexcept {} - - template - FFSM2_CONSTEXPR(14) void preReact (const TEvent& , - FullControl& ) noexcept {} - - template - FFSM2_CONSTEXPR(14) void react (const TEvent& , - FullControl& ) noexcept {} - - template - FFSM2_CONSTEXPR(14) void postReact (const TEvent& , - FullControl& ) noexcept {} - - template - FFSM2_CONSTEXPR(14) void query ( TEvent& , - ConstControl& ) const noexcept {} - - FFSM2_CONSTEXPR(14) void exitGuard (GuardControl& ) noexcept {} - - FFSM2_CONSTEXPR(14) void exit ( PlanControl& ) noexcept {} - -#if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(14) void planSucceeded ( FullControl& ) noexcept {} - FFSM2_CONSTEXPR(14) void planFailed ( FullControl& ) noexcept {} -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(14) void wideEntryGuard(GuardControl& control) noexcept; - - FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control) noexcept; - FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control) noexcept; - - FFSM2_CONSTEXPR(14) void widePreUpdate ( FullControl& control) noexcept; - FFSM2_CONSTEXPR(14) void wideUpdate ( FullControl& control) noexcept; - FFSM2_CONSTEXPR(14) void widePostUpdate( FullControl& control) noexcept; - - template - FFSM2_CONSTEXPR(14) void widePreReact (const TEvent& event , - FullControl& control) noexcept; - - template - FFSM2_CONSTEXPR(14) void wideReact (const TEvent& event , - FullControl& control) noexcept; - - template - FFSM2_CONSTEXPR(14) void widePostReact (const TEvent& event , - FullControl& control) noexcept; - - template - FFSM2_CONSTEXPR(14) void wideQuery ( TEvent& event , - ConstControl& control) const noexcept; - - FFSM2_CONSTEXPR(14) void wideExitGuard (GuardControl& control) noexcept; - - FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control) noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -}; - -//------------------------------------------------------------------------------ - -template -using EmptyT = A_>; - -//////////////////////////////////////////////////////////////////////////////// - -} -} - -#include "ancestors_1.inl" -#include "ancestors_2.inl" diff --git a/development/ffsm2/detail/structure/ancestors_1.hpp b/development/ffsm2/detail/structure/ancestors_1.hpp new file mode 100644 index 0000000..3ce6567 --- /dev/null +++ b/development/ffsm2/detail/structure/ancestors_1.hpp @@ -0,0 +1,78 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +struct A_; + +template +using EmptyT = A_>; + +//------------------------------------------------------------------------------ + +template +struct FFSM2_EMPTY_BASES A_ + : TFirst + , A_ +{ + using First = TFirst; + using typename First::Context; + + using typename First::StateList; + + using typename First::ConstControl; + using typename First::Control; + using typename First::PlanControl; + +#if FFSM2_PLANS_AVAILABLE() + using typename First::Plan; +#endif + + using typename First::FullControl; + using typename First::GuardControl; + + using First::stateId; + + using Rest = A_; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) void wideEntryGuard(GuardControl& control) noexcept; + + FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control) noexcept; + FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control) noexcept; + + FFSM2_CONSTEXPR(14) void widePreUpdate ( FullControl& control) noexcept; + FFSM2_CONSTEXPR(14) void wideUpdate ( FullControl& control) noexcept; + FFSM2_CONSTEXPR(14) void widePostUpdate( FullControl& control) noexcept; + + template + FFSM2_CONSTEXPR(14) void widePreReact (const TEvent& event , + FullControl& control) noexcept; + + template + FFSM2_CONSTEXPR(14) void wideReact (const TEvent& event , + FullControl& control) noexcept; + + template + FFSM2_CONSTEXPR(14) void widePostReact (const TEvent& event , + FullControl& control) noexcept; + + template + FFSM2_CONSTEXPR(14) void wideQuery ( TEvent& event , + ConstControl& control) const noexcept; + + FFSM2_CONSTEXPR(14) void wideExitGuard (GuardControl& control) noexcept; + + FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control) noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "ancestors_1.inl" diff --git a/development/ffsm2/detail/structure/ancestors_1.inl b/development/ffsm2/detail/structure/ancestors_1.inl index 524bf8e..9e0a0da 100644 --- a/development/ffsm2/detail/structure/ancestors_1.inl +++ b/development/ffsm2/detail/structure/ancestors_1.inl @@ -3,134 +3,134 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// -template +template FFSM2_CONSTEXPR(14) void -A_::wideEntryGuard(GuardControl& control) noexcept { - TF :: entryGuard( control); - A_::wideEntryGuard( control); +A_::wideEntryGuard(GuardControl& control) noexcept { + First:: entryGuard(control); + Rest ::wideEntryGuard(control); } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -A_::wideEnter(PlanControl& control) noexcept { - TF :: enter( control); - A_::wideEnter( control); +A_::wideEnter(PlanControl& control) noexcept { + First:: enter(control); + Rest ::wideEnter(control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -A_::wideReenter(PlanControl& control) noexcept { - TF :: Reenter( control); - A_::wideReenter( control); +A_::wideReenter(PlanControl& control) noexcept { + First:: reenter(control); + Rest ::wideReenter(control); } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -A_::widePreUpdate(FullControl& control) noexcept { - TF :: preUpdate( control); - A_::widePreUpdate( control); +A_::widePreUpdate(FullControl& control) noexcept { + First:: preUpdate(control); + Rest ::widePreUpdate(control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -A_::wideUpdate(FullControl& control) noexcept { - TF :: update( control); - A_::wideUpdate( control); +A_::wideUpdate(FullControl& control) noexcept { + First:: update(control); + Rest ::wideUpdate(control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -A_::widePostUpdate(FullControl& control) noexcept { - A_::widePostUpdate( control); - TF :: postUpdate( control); +A_::widePostUpdate(FullControl& control) noexcept { + Rest ::widePostUpdate(control); + First:: postUpdate(control); } //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -A_::widePreReact(const TEvent& event, - FullControl& control) noexcept +A_::widePreReact(const TEvent& event, + FullControl& control) noexcept { - TF :: preReact( event, control); - A_::widePreReact( event, control); + First:: preReact(event, control); + Rest ::widePreReact(event, control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) void -A_::wideReact(const TEvent& event, - FullControl& control) noexcept +A_::wideReact(const TEvent& event, + FullControl& control) noexcept { - TF :: react( event, control); - A_::wideReact( event, control); + First:: react(event, control); + Rest ::wideReact(event, control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) void -A_::widePostReact(const TEvent& event, - FullControl& control) noexcept +A_::widePostReact(const TEvent& event, + FullControl& control) noexcept { - A_::widePostReact( event, control); - TF :: postReact( event, control); + Rest ::widePostReact(event, control); + First:: postReact(event, control); } //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -A_::wideQuery(TEvent& event, - ConstControl& control) const noexcept +A_::wideQuery(TEvent& event, + ConstControl& control) const noexcept { - A_::wideQuery( event, control); - TF :: query( event, control); + First:: query(event, control); + Rest ::wideQuery(event, control); } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -A_::wideExitGuard(GuardControl& control) noexcept { - A_::wideExitGuard( control); - TF :: exitGuard( control); +A_::wideExitGuard(GuardControl& control) noexcept { + Rest ::wideExitGuard(control); + First:: exitGuard(control); } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -A_::wideExit(PlanControl& control) noexcept { - A_::wideExit( control); - TF :: exit( control); +A_::wideExit(PlanControl& control) noexcept { + Rest ::wideExit(control); + First:: exit(control); } //////////////////////////////////////////////////////////////////////////////// diff --git a/development/ffsm2/detail/structure/ancestors_2.hpp b/development/ffsm2/detail/structure/ancestors_2.hpp new file mode 100644 index 0000000..a9cd468 --- /dev/null +++ b/development/ffsm2/detail/structure/ancestors_2.hpp @@ -0,0 +1,106 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +struct A_ + : TFirst +{ + using First = TFirst; + using typename First::Context; + + using typename First::StateList; + + using typename First::ConstControl; + using typename First::Control; + using typename First::PlanControl; + +#if FFSM2_PLANS_AVAILABLE() + using typename First::Plan; +#endif + + using typename First::FullControl; + using typename First::GuardControl; + + using First::stateId; + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) void entryGuard (GuardControl& ) noexcept {} + + FFSM2_CONSTEXPR(14) void enter ( PlanControl& ) noexcept {} + FFSM2_CONSTEXPR(14) void reenter ( PlanControl& ) noexcept {} + + FFSM2_CONSTEXPR(14) void preUpdate ( FullControl& ) noexcept {} + FFSM2_CONSTEXPR(14) void update ( FullControl& ) noexcept {} + FFSM2_CONSTEXPR(14) void postUpdate ( FullControl& ) noexcept {} + + template + FFSM2_CONSTEXPR(14) void preReact (const TEvent& , + FullControl& ) noexcept {} + + template + FFSM2_CONSTEXPR(14) void react (const TEvent& , + FullControl& ) noexcept {} + + template + FFSM2_CONSTEXPR(14) void postReact (const TEvent& , + FullControl& ) noexcept {} + + template + FFSM2_CONSTEXPR(14) void query ( TEvent& , + ConstControl& ) const noexcept {} + + FFSM2_CONSTEXPR(14) void exitGuard (GuardControl& ) noexcept {} + + FFSM2_CONSTEXPR(14) void exit ( PlanControl& ) noexcept {} + +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) void planSucceeded ( FullControl& ) noexcept {} + FFSM2_CONSTEXPR(14) void planFailed ( FullControl& ) noexcept {} +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) void wideEntryGuard(GuardControl& control) noexcept; + + FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control) noexcept; + FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control) noexcept; + + FFSM2_CONSTEXPR(14) void widePreUpdate ( FullControl& control) noexcept; + FFSM2_CONSTEXPR(14) void wideUpdate ( FullControl& control) noexcept; + FFSM2_CONSTEXPR(14) void widePostUpdate( FullControl& control) noexcept; + + template + FFSM2_CONSTEXPR(14) void widePreReact (const TEvent& event , + FullControl& control) noexcept; + + template + FFSM2_CONSTEXPR(14) void wideReact (const TEvent& event , + FullControl& control) noexcept; + + template + FFSM2_CONSTEXPR(14) void widePostReact (const TEvent& event , + FullControl& control) noexcept; + + template + FFSM2_CONSTEXPR(14) void wideQuery ( TEvent& event , + ConstControl& control) const noexcept; + + FFSM2_CONSTEXPR(14) void wideExitGuard (GuardControl& control) noexcept; + + FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control) noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "ancestors_2.inl" diff --git a/development/ffsm2/detail/structure/ancestors_2.inl b/development/ffsm2/detail/structure/ancestors_2.inl index bcbd465..8c21f11 100644 --- a/development/ffsm2/detail/structure/ancestors_2.inl +++ b/development/ffsm2/detail/structure/ancestors_2.inl @@ -3,122 +3,122 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// -template +template FFSM2_CONSTEXPR(14) void -A_::wideEntryGuard(GuardControl& control) noexcept { - TF:: entryGuard( control); +A_::wideEntryGuard(GuardControl& control) noexcept { + First:: entryGuard(control); } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -A_::wideEnter(PlanControl& control) noexcept { - TF:: enter( control); +A_::wideEnter(PlanControl& control) noexcept { + First:: enter(control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -A_::wideReenter(PlanControl& control) noexcept { - TF:: reenter( control); +A_::wideReenter(PlanControl& control) noexcept { + First:: reenter(control); } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -A_::widePreUpdate(FullControl& control) noexcept { - TF:: preUpdate( control); +A_::widePreUpdate(FullControl& control) noexcept { + First:: preUpdate(control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -A_::wideUpdate(FullControl& control) noexcept { - TF:: update( control); +A_::wideUpdate(FullControl& control) noexcept { + First:: update(control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -A_::widePostUpdate(FullControl& control) noexcept { - TF:: postUpdate( control); +A_::widePostUpdate(FullControl& control) noexcept { + First:: postUpdate(control); } //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -A_::widePreReact(const TEvent& event, - FullControl& control) noexcept +A_::widePreReact(const TEvent& event, + FullControl& control) noexcept { - TF:: preReact( event, control); + First:: preReact(event, control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) void -A_::wideReact(const TEvent& event, - FullControl& control) noexcept +A_::wideReact(const TEvent& event, + FullControl& control) noexcept { - TF:: react( event, control); + First:: react(event, control); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) void -A_::widePostReact(const TEvent& event, - FullControl& control) noexcept +A_::widePostReact(const TEvent& event, + FullControl& control) noexcept { - TF:: postReact( event, control); + First:: postReact(event, control); } //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -A_::wideQuery(TEvent& event, - ConstControl& control) const noexcept +A_::wideQuery(TEvent& event, + ConstControl& control) const noexcept { - TF:: query( event, control); + First:: query(event, control); } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -A_::wideExitGuard(GuardControl& control) noexcept { - TF:: exitGuard( control); +A_::wideExitGuard(GuardControl& control) noexcept { + First:: exitGuard(control); } //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -A_::wideExit(PlanControl& control) noexcept { - TF:: exit( control); +A_::wideExit(PlanControl& control) noexcept { + First:: exit(control); } //////////////////////////////////////////////////////////////////////////////// diff --git a/development/ffsm2/detail/structure/base.hpp b/development/ffsm2/detail/structure/base.hpp new file mode 100644 index 0000000..88a0eb0 --- /dev/null +++ b/development/ffsm2/detail/structure/base.hpp @@ -0,0 +1,69 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template +class B_ { + template + friend struct A_; + +protected: + using Context = typename TArgs::Context; + + using StateList = typename TArgs::StateList; + + using ConstControl = ConstControlT; + using Control = ControlT ; + using PlanControl = PlanControlT ; + +#if FFSM2_PLANS_AVAILABLE() + using Plan = PayloadPlanT ; +#endif + + using FullControl = FullControlT ; + using GuardControl = GuardControlT; + +public: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) void entryGuard (GuardControl& ) noexcept {} + + FFSM2_CONSTEXPR(14) void enter ( PlanControl& ) noexcept {} + FFSM2_CONSTEXPR(14) void reenter ( PlanControl& ) noexcept {} + + FFSM2_CONSTEXPR(14) void preUpdate ( FullControl& ) noexcept {} + FFSM2_CONSTEXPR(14) void update ( FullControl& ) noexcept {} + FFSM2_CONSTEXPR(14) void postUpdate ( FullControl& ) noexcept {} + + template + FFSM2_CONSTEXPR(14) void preReact (const TEvent& , + FullControl& ) noexcept {} + + template + FFSM2_CONSTEXPR(14) void react (const TEvent& , + FullControl& ) noexcept {} + + template + FFSM2_CONSTEXPR(14) void postReact (const TEvent& , + FullControl& ) noexcept {} + + template + FFSM2_CONSTEXPR(14) void query ( TEvent& , + ConstControl& ) const noexcept {} + + FFSM2_CONSTEXPR(14) void exitGuard (GuardControl& ) noexcept {} + + FFSM2_CONSTEXPR(14) void exit ( PlanControl& ) noexcept {} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index() ; } +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/detail/structure/composite.hpp b/development/ffsm2/detail/structure/composite.hpp index 0ccb1dc..b9f9bd2 100644 --- a/development/ffsm2/detail/structure/composite.hpp +++ b/development/ffsm2/detail/structure/composite.hpp @@ -3,12 +3,19 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// -template +template < + typename TArgs + , typename THead + , typename... TSubStates +> struct FFSM2_EMPTY_BASES C_ : S_ - , CS_<0, TArgs, 0, TL_> + , CS_< + 0 + , TArgs + , 0 + , TL_ + > { using Args = TArgs; @@ -48,14 +55,19 @@ struct FFSM2_EMPTY_BASES C_ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(11) static Short& compoRequested ( Control& control) noexcept { return control._core.registry.requested; } +#if FFSM2_SERIALIZATION_AVAILABLE() + FFSM2_CONSTEXPR(11) static Prong compoRequested (const Registry& registry) noexcept { return registry.requested; } + FFSM2_CONSTEXPR(11) static Prong& compoRequested ( Registry& registry) noexcept { return registry.requested; } +#endif + + FFSM2_CONSTEXPR(11) static Prong& compoRequested ( Control& control) noexcept { return control._core.registry.requested; } - FFSM2_CONSTEXPR(11) static Short& compoActive ( Control& control) noexcept { return control._core.registry.active; } - FFSM2_CONSTEXPR(11) static Short compoActive (ConstControl& control) noexcept { return control._core.registry.active; } + FFSM2_CONSTEXPR(11) static Prong& compoActive ( Control& control) noexcept { return control._core.registry.active; } + FFSM2_CONSTEXPR(11) static Prong compoActive (ConstControl& control) noexcept { return control._core.registry.active; } #if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(11) static TaskStatus& headStatus ( Control& control) noexcept { return control._core.planData.headStatus; } - FFSM2_CONSTEXPR(11) static TaskStatus& subStatus ( Control& control) noexcept { return control._core.planData.subStatus; } + FFSM2_CONSTEXPR(11) static TaskStatus& headStatus ( Control& control) noexcept { return control._core.planData.headStatus; } + FFSM2_CONSTEXPR(11) static TaskStatus& subStatus ( Control& control) noexcept { return control._core.planData.subStatus; } #endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/development/ffsm2/detail/structure/composite.inl b/development/ffsm2/detail/structure/composite.inl index 4e336f8..8fd9b8e 100644 --- a/development/ffsm2/detail/structure/composite.inl +++ b/development/ffsm2/detail/structure/composite.inl @@ -9,12 +9,12 @@ namespace detail { //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) bool -C_::deepForwardEntryGuard(GuardControl& control) noexcept { - const Short requested = compoRequested(control); - FFSM2_ASSERT(requested < WIDTH); +C_::deepForwardEntryGuard(GuardControl& control) noexcept { + const Prong requested = compoRequested(control); + FFSM2_ASSERT(requested < WIDTH); FFSM2_ASSERT(compoActive(control) < WIDTH); @@ -23,11 +23,11 @@ C_::deepForwardEntryGuard(GuardControl& control) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) bool -C_::deepEntryGuard(GuardControl& control) noexcept { - const Short requested = compoRequested(control); +C_::deepEntryGuard(GuardControl& control) noexcept { + const Prong requested = compoRequested(control); FFSM2_ASSERT(requested < WIDTH); return HeadState::deepEntryGuard(control) || @@ -36,18 +36,18 @@ C_::deepEntryGuard(GuardControl& control) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -C_::deepEnter(PlanControl& control) noexcept { - Short& requested = compoRequested(control); - Short& active = compoActive (control); +C_::deepEnter(PlanControl& control) noexcept { + Prong& requested = compoRequested(control); + Prong& active = compoActive (control); FFSM2_ASSERT(requested < WIDTH); - FFSM2_ASSERT(active == INVALID_SHORT); + FFSM2_ASSERT(active == INVALID_PRONG); active = requested; - requested = INVALID_SHORT; + requested = INVALID_PRONG; HeadState::deepEnter(control); SubStates::wideEnter(control, active); @@ -55,22 +55,22 @@ C_::deepEnter(PlanControl& control) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -C_::deepReenter(PlanControl& /*control*/) noexcept { +C_::deepReenter(PlanControl& FFSM2_UNUSED(control)) noexcept { } //------------------------------------------------------------------------------ // COMMON -template +template FFSM2_CONSTEXPR(14) void -C_::deepPreUpdate(FullControl& control) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); +C_::deepPreUpdate(FullControl& control) noexcept { + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - const Short active = compoActive(control); + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); ScopedRegion region{control}; @@ -79,19 +79,19 @@ C_::deepPreUpdate(FullControl& control) noexcept { HeadState::deepPreUpdate(control); FFSM2_IF_PLANS(headStatus(control) |= h); - FFSM2_IF_PLANS(subStatus(control) |=) + FFSM2_IF_PLANS( subStatus(control) |=) SubStates::widePreUpdate(control, active); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -C_::deepUpdate(FullControl& control) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); +C_::deepUpdate(FullControl& control) noexcept { + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - const Short active = compoActive(control); + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); ScopedRegion region{control}; @@ -100,113 +100,113 @@ C_::deepUpdate(FullControl& control) noexcept { HeadState::deepUpdate(control); FFSM2_IF_PLANS(headStatus(control) |= h); - FFSM2_IF_PLANS(subStatus(control) |=) + FFSM2_IF_PLANS( subStatus(control) |=) SubStates::wideUpdate(control, active); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -C_::deepPostUpdate(FullControl& control) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); +C_::deepPostUpdate(FullControl& control) noexcept { + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - const Short active = compoActive(control); + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); ScopedRegion region{control}; - FFSM2_IF_PLANS(subStatus(control) |=) + FFSM2_IF_PLANS( subStatus (control) |=) SubStates::widePostUpdate(control, active); FFSM2_IF_PLANS(const TaskStatus h =) HeadState::deepPostUpdate(control); - FFSM2_IF_PLANS(headStatus(control) |= h); + FFSM2_IF_PLANS(headStatus (control) |= h); } //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -C_::deepPreReact(FullControl& control, - const TEvent& event) noexcept +C_::deepPreReact(FullControl& control, + const TEvent& event) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - const Short active = compoActive(control); + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); ScopedRegion region{control}; FFSM2_IF_PLANS(const TaskStatus h =) HeadState::deepPreReact(control, event); - FFSM2_IF_PLANS(headStatus(control) |= h); + FFSM2_IF_PLANS(headStatus (control) |= h); - FFSM2_IF_PLANS(subStatus(control) |=) + FFSM2_IF_PLANS( subStatus (control) |=) SubStates::widePreReact(control, event, active); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) void -C_::deepReact(FullControl& control, - const TEvent& event) noexcept +C_::deepReact(FullControl& control, + const TEvent& event) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - const Short active = compoActive(control); + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); ScopedRegion region{control}; FFSM2_IF_PLANS(const TaskStatus h =) - HeadState::deepReact(control, event); + HeadState:: deepReact(control, event); FFSM2_IF_PLANS(headStatus(control) |= h); - FFSM2_IF_PLANS(subStatus(control) |=) - SubStates::wideReact(control, event, active); + FFSM2_IF_PLANS( subStatus(control) |=) + SubStates:: wideReact(control, event, active); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) void -C_::deepPostReact(FullControl& control, - const TEvent& event) noexcept +C_::deepPostReact(FullControl& control, + const TEvent& event) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - const Short active = compoActive(control); + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); ScopedRegion region{control}; - FFSM2_IF_PLANS(subStatus(control) |=) + FFSM2_IF_PLANS( subStatus (control) |=) SubStates::widePostReact(control, event, active); FFSM2_IF_PLANS(const TaskStatus h =) HeadState::deepPostReact(control, event); - FFSM2_IF_PLANS(headStatus(control) |= h); + FFSM2_IF_PLANS(headStatus (control) |= h); } //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -C_::deepQuery(ConstControl& control, - TEvent& event) const noexcept +C_::deepQuery(ConstControl& control, + TEvent& event) const noexcept { - const Short active = compoActive(control); + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); HeadState::deepQuery(control, event); @@ -217,17 +217,17 @@ C_::deepQuery(ConstControl& control, #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -C_::deepUpdatePlans(FullControl& control) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); +C_::deepUpdatePlans(FullControl& control) noexcept { + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - const Short active = compoActive(control); + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); - const TaskStatus s = subStatus(control) | - SubStates::wideUpdatePlans(control, active); + const TaskStatus s = subStatus(control) | + SubStates::wideUpdatePlans (control, active); const bool planExists = control._core.planData.planExists; @@ -239,11 +239,11 @@ C_::deepUpdatePlans(FullControl& control) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) bool -C_::deepForwardExitGuard(GuardControl& control) noexcept { - const Short active = compoActive(control); +C_::deepForwardExitGuard(GuardControl& control) noexcept { + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); FFSM2_ASSERT(compoRequested(control) < WIDTH); @@ -253,11 +253,11 @@ C_::deepForwardExitGuard(GuardControl& control) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) bool -C_::deepExitGuard(GuardControl& control) noexcept { - const Short active = compoActive(control); +C_::deepExitGuard(GuardControl& control) noexcept { + const Prong active = compoActive(control); FFSM2_ASSERT(active < WIDTH); FFSM2_ASSERT(compoRequested(control) < WIDTH); @@ -268,17 +268,17 @@ C_::deepExitGuard(GuardControl& control) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -C_::deepExit(PlanControl& control) noexcept { - Short& active = compoActive(control); +C_::deepExit(PlanControl& control) noexcept { + Prong& active = compoActive (control); FFSM2_ASSERT(active < WIDTH); SubStates::wideExit(control, active); HeadState::deepExit(control); - active = INVALID_SHORT; + active = INVALID_PRONG; #if FFSM2_PLANS_AVAILABLE() Plan plan = control.plan(); @@ -290,12 +290,12 @@ C_::deepExit(PlanControl& control) noexcept { //------------------------------------------------------------------------------ // COMMON -template +template FFSM2_CONSTEXPR(14) void -C_::deepChangeToRequested(PlanControl& control) noexcept { - Short& requested = compoRequested(control); - Short& active = compoActive(control); +C_::deepChangeToRequested(PlanControl& control) noexcept { + Prong& requested = compoRequested(control); + Prong& active = compoActive (control); FFSM2_ASSERT(active < WIDTH); @@ -305,11 +305,11 @@ C_::deepChangeToRequested(PlanControl& control) noexcept { SubStates::wideExit (control, active); active = requested; - requested = INVALID_SHORT; + requested = INVALID_PRONG; SubStates::wideEnter (control, active); } else { - requested = INVALID_SHORT; + requested = INVALID_PRONG; // reconstruction done in S_::reenter() SubStates::wideReenter(control, active); @@ -320,11 +320,11 @@ C_::deepChangeToRequested(PlanControl& control) noexcept { #if FFSM2_SERIALIZATION_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -C_::deepSaveActive(const Registry& registry, - WriteStream& stream) const noexcept +C_::deepSaveActive(const Registry& registry, + WriteStream& stream) const noexcept { stream.template write(registry.active); } @@ -332,14 +332,16 @@ C_::deepSaveActive(const Registry& registry, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -C_::deepLoadRequested(Registry& registry, - ReadStream& stream) const noexcept +C_::deepLoadRequested(Registry& registry, + ReadStream& stream) const noexcept { - registry.requested = stream.template read(); - FFSM2_ASSERT(registry.requested < WIDTH); + Prong& requested = compoRequested(registry); + + requested = stream.template read(); + FFSM2_ASSERT(requested < WIDTH); } #endif diff --git a/development/ffsm2/detail/structure/composite_sub.hpp b/development/ffsm2/detail/structure/composite_sub.hpp deleted file mode 100644 index e9713dd..0000000 --- a/development/ffsm2/detail/structure/composite_sub.hpp +++ /dev/null @@ -1,164 +0,0 @@ -namespace ffsm2 { -namespace detail { - -//////////////////////////////////////////////////////////////////////////////// - -template -struct FFSM2_EMPTY_BASES CS_> - : LHalfCS> - , RHalfCS> -{ - static_assert(sizeof...(TStates) >= 2, ""); - - using Args = TArgs; - using SubStateList = TL_; - - using StateList = typename Args::StateList; - - using ConstControl = ConstControlT; - using Control = ControlT ; - using PlanControl = PlanControlT ; - using FullControl = FullControlT ; - using GuardControl = GuardControlT; - - static constexpr StateID INITIAL_ID = NStateId; - static constexpr Short PRONG_INDEX = NIndex; - static constexpr Short R_PRONG = PRONG_INDEX + sizeof...(TStates) / 2; - - using LHalf = LHalfCS; - - using RHalf = RHalfCS; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(14) bool wideEntryGuard (GuardControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) TaskStatus widePreUpdate ( FullControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus wideUpdate ( FullControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus widePostUpdate ( FullControl& control, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus widePreReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus wideReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus widePostReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) void wideQuery (ConstControl& control, TEvent& event, const Short prong) const noexcept; - -#if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(14) TaskStatus wideUpdatePlans ( FullControl& control, const Short prong) noexcept; -#endif - - FFSM2_CONSTEXPR(14) bool wideExitGuard (GuardControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control, const Short prong) noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(14) void wideChangeToRequested( PlanControl& control, const Short prong) noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -}; - -//////////////////////////////////////////////////////////////////////////////// - -template -struct CS_> - : MaterialT -{ - static constexpr Short PRONG_INDEX = NIndex; - - using Args = TArgs; - - using StateList = typename Args::StateList; - - using ConstControl = ConstControlT; - using Control = ControlT ; - using PlanControl = PlanControlT ; - using FullControl = FullControlT ; - using GuardControl = GuardControlT; - - using Single = MaterialT; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(14) bool wideEntryGuard (GuardControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) TaskStatus widePreUpdate ( FullControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus wideUpdate ( FullControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus widePostUpdate ( FullControl& control, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus widePreReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus wideReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus widePostReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) void wideQuery (ConstControl& control, TEvent& event, const Short prong) const noexcept; - -#if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(14) TaskStatus wideUpdatePlans ( FullControl& control, const Short prong) noexcept; -#endif - - FFSM2_CONSTEXPR(14) bool wideExitGuard (GuardControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control, const Short prong) noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FFSM2_CONSTEXPR(14) void wideChangeToRequested( PlanControl& control, const Short prong) noexcept; - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -}; - -//////////////////////////////////////////////////////////////////////////////// - -} -} - -#include "composite_sub_1.inl" -#include "composite_sub_2.inl" diff --git a/development/ffsm2/detail/structure/composite_sub_1.hpp b/development/ffsm2/detail/structure/composite_sub_1.hpp new file mode 100644 index 0000000..2a109b9 --- /dev/null +++ b/development/ffsm2/detail/structure/composite_sub_1.hpp @@ -0,0 +1,108 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template < + StateID NStateId + , typename TArgs + , Prong NProng + , typename... TStates +> +struct FFSM2_EMPTY_BASES CS_< + NStateId + , TArgs + , NProng + , TL_ + > + : LHalfCS< + NStateId + , TArgs + , NProng + , TL_ + > + , RHalfCS< + NStateId + , TArgs + , NProng + , TL_ + > +{ + static_assert(sizeof...(TStates) >= 2, ""); + + static constexpr Prong PRONG_INDEX = NProng; + + using Args = TArgs; + using SubStateList = TL_; + + using StateList = typename Args::StateList; + + using ConstControl = ConstControlT; + using Control = ControlT ; + using PlanControl = PlanControlT ; + using FullControl = FullControlT ; + using GuardControl = GuardControlT; + + static constexpr StateID INITIAL_ID = NStateId; + static constexpr Prong L_PRONG = PRONG_INDEX; + static constexpr Prong R_PRONG = PRONG_INDEX + sizeof...(TStates) / 2; + + using LHalf = LHalfCS< + INITIAL_ID + , Args + , PRONG_INDEX + , SubStateList + >; + + using RHalf = RHalfCS< + INITIAL_ID + , Args + , PRONG_INDEX + , SubStateList + >; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) bool wideEntryGuard (GuardControl& control, const Prong prong) noexcept; + + FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control, const Prong prong) noexcept; + + FFSM2_CONSTEXPR(14) TaskStatus widePreUpdate ( FullControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus wideUpdate ( FullControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePostUpdate ( FullControl& control, const Prong prong) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus widePreReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus wideReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus widePostReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; + + template + FFSM2_CONSTEXPR(14) void wideQuery (ConstControl& control, TEvent& event, const Prong prong) const noexcept; + +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) TaskStatus wideUpdatePlans ( FullControl& control, const Prong prong) noexcept; +#endif + + FFSM2_CONSTEXPR(14) bool wideExitGuard (GuardControl& control, const Prong prong) noexcept; + + FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control, const Prong prong) noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) void wideChangeToRequested( PlanControl& control, const Prong prong) noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "composite_sub_1.inl" diff --git a/development/ffsm2/detail/structure/composite_sub_1.inl b/development/ffsm2/detail/structure/composite_sub_1.inl index 7b64372..999fe7b 100644 --- a/development/ffsm2/detail/structure/composite_sub_1.inl +++ b/development/ffsm2/detail/structure/composite_sub_1.inl @@ -4,13 +4,13 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// // COMMON -template +template FFSM2_CONSTEXPR(14) bool -CS_>::wideEntryGuard(GuardControl& control, - const Short prong) noexcept +CS_>::wideEntryGuard(GuardControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); if (prong < R_PRONG) return LHalf::wideEntryGuard(control, prong); @@ -20,13 +20,13 @@ CS_>::wideEntryGuard(GuardControl& control, //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideEnter(PlanControl& control, - const Short prong) noexcept +CS_>::wideEnter(PlanControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); if (prong < R_PRONG) LHalf::wideEnter(control, prong); @@ -36,13 +36,13 @@ CS_>::wideEnter(PlanControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideReenter(PlanControl& control, - const Short prong) noexcept +CS_>::wideReenter(PlanControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); if (prong < R_PRONG) LHalf::wideReenter(control, prong); @@ -52,13 +52,13 @@ CS_>::wideReenter(PlanControl& control, //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePreUpdate(FullControl& control, - const Short prong) noexcept +CS_>::widePreUpdate(FullControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); return prong < R_PRONG ? LHalf::widePreUpdate(control, prong) : @@ -67,13 +67,13 @@ CS_>::widePreUpdate(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideUpdate(FullControl& control, - const Short prong) noexcept +CS_>::wideUpdate(FullControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); return prong < R_PRONG ? LHalf::wideUpdate(control, prong) : @@ -82,13 +82,13 @@ CS_>::wideUpdate(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePostUpdate(FullControl& control, - const Short prong) noexcept +CS_>::widePostUpdate(FullControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); return prong < R_PRONG ? LHalf::widePostUpdate(control, prong) : @@ -97,15 +97,15 @@ CS_>::widePostUpdate(FullControl& control, //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePreReact(FullControl& control, - const TEvent& event, - const Short prong) noexcept +CS_>::widePreReact(FullControl& control, + const TEvent& event, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); return prong < R_PRONG ? LHalf::widePreReact(control, event, prong) : @@ -114,15 +114,15 @@ CS_>::widePreReact(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideReact(FullControl& control, - const TEvent& event, - const Short prong) noexcept +CS_>::wideReact(FullControl& control, + const TEvent& event, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); return prong < R_PRONG ? LHalf::wideReact(control, event, prong) : @@ -131,15 +131,15 @@ CS_>::wideReact(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePostReact(FullControl& control, - const TEvent& event, - const Short prong) noexcept +CS_>::widePostReact(FullControl& control, + const TEvent& event, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); return prong < R_PRONG ? LHalf::widePostReact(control, event, prong) : @@ -148,15 +148,15 @@ CS_>::widePostReact(FullControl& control, //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -CS_>::wideQuery(ConstControl& control, - TEvent& event, - const Short prong) const noexcept +CS_>::wideQuery(ConstControl& control, + TEvent& event, + const Prong prong) const noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); return prong < R_PRONG ? LHalf::wideQuery(control, event, prong) : @@ -167,13 +167,13 @@ CS_>::wideQuery(ConstControl& control, #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideUpdatePlans(FullControl& control, - const Short prong) noexcept +CS_>::wideUpdatePlans(FullControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); return prong < R_PRONG ? LHalf::wideUpdatePlans(control, prong) : @@ -186,13 +186,13 @@ CS_>::wideUpdatePlans(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON -template +template FFSM2_CONSTEXPR(14) bool -CS_>::wideExitGuard(GuardControl& control, - const Short prong) noexcept +CS_>::wideExitGuard(GuardControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); if (prong < R_PRONG) return LHalf::wideExitGuard(control, prong); @@ -202,13 +202,13 @@ CS_>::wideExitGuard(GuardControl& control, //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideExit(PlanControl& control, - const Short prong) noexcept +CS_>::wideExit(PlanControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); if (prong < R_PRONG) LHalf::wideExit(control, prong); @@ -219,13 +219,13 @@ CS_>::wideExit(PlanControl& control, //------------------------------------------------------------------------------ // COMMON -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideChangeToRequested(PlanControl& control, - const Short prong) noexcept +CS_>::wideChangeToRequested(PlanControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_ASSERT(prong != INVALID_PRONG); if (prong < R_PRONG) LHalf::wideChangeToRequested(control, prong); diff --git a/development/ffsm2/detail/structure/composite_sub_2.hpp b/development/ffsm2/detail/structure/composite_sub_2.hpp new file mode 100644 index 0000000..1ea4bd9 --- /dev/null +++ b/development/ffsm2/detail/structure/composite_sub_2.hpp @@ -0,0 +1,86 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// + +template < + StateID NStateId + , typename TArgs + , Prong NProng + , typename TState +> +struct CS_< + NStateId + , TArgs + , NProng + , TL_ + > + : MaterialT< + NStateId + , TArgs + , TState + > +{ + static constexpr Prong PRONG_INDEX = NProng; + + using Args = TArgs; + + using StateList = typename Args::StateList; + + using ConstControl = ConstControlT; + using Control = ControlT ; + using PlanControl = PlanControlT ; + using FullControl = FullControlT ; + using GuardControl = GuardControlT; + + using Single = MaterialT< + NStateId + , Args + , TState + >; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) bool wideEntryGuard (GuardControl& control, const Prong prong) noexcept; + + FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control, const Prong prong) noexcept; + + FFSM2_CONSTEXPR(14) TaskStatus widePreUpdate ( FullControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus wideUpdate ( FullControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePostUpdate ( FullControl& control, const Prong prong) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus widePreReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus wideReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus widePostReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; + + template + FFSM2_CONSTEXPR(14) void wideQuery (ConstControl& control, TEvent& event, const Prong prong) const noexcept; + +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) TaskStatus wideUpdatePlans ( FullControl& control, const Prong prong) noexcept; +#endif + + FFSM2_CONSTEXPR(14) bool wideExitGuard (GuardControl& control, const Prong prong) noexcept; + + FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control, const Prong prong) noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) void wideChangeToRequested( PlanControl& control, const Prong prong) noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "composite_sub_2.inl" diff --git a/development/ffsm2/detail/structure/composite_sub_2.inl b/development/ffsm2/detail/structure/composite_sub_2.inl index 48bcc93..6a93422 100644 --- a/development/ffsm2/detail/structure/composite_sub_2.inl +++ b/development/ffsm2/detail/structure/composite_sub_2.inl @@ -4,11 +4,11 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// // COMMON -template +template FFSM2_CONSTEXPR(14) bool -CS_>::wideEntryGuard(GuardControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideEntryGuard(GuardControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -17,11 +17,11 @@ CS_>::wideEntryGuard(GuardControl& control, //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideEnter(PlanControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideEnter(PlanControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -30,11 +30,11 @@ CS_>::wideEnter(PlanControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideReenter(PlanControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideReenter(PlanControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -43,11 +43,11 @@ CS_>::wideReenter(PlanControl& control, //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePreUpdate(FullControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::widePreUpdate(FullControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -56,11 +56,11 @@ CS_>::widePreUpdate(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideUpdate(FullControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideUpdate(FullControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -69,11 +69,11 @@ CS_>::wideUpdate(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePostUpdate(FullControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::widePostUpdate(FullControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -82,13 +82,13 @@ CS_>::widePostUpdate(FullControl& control, //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePreReact(FullControl& control, - const TEvent& event, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::widePreReact(FullControl& control, + const TEvent& event, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -97,13 +97,13 @@ CS_>::widePreReact(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideReact(FullControl& control, - const TEvent& event, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideReact(FullControl& control, + const TEvent& event, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -112,13 +112,13 @@ CS_>::wideReact(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePostReact(FullControl& control, - const TEvent& event, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::widePostReact(FullControl& control, + const TEvent& event, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -127,13 +127,13 @@ CS_>::widePostReact(FullControl& control, //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -CS_>::wideQuery(ConstControl& control, - TEvent& event, - const Short FFSM2_IF_ASSERT(prong)) const noexcept +CS_>::wideQuery(ConstControl& control, + TEvent& event, + const Prong FFSM2_IF_ASSERT(prong)) const noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -144,11 +144,11 @@ CS_>::wideQuery(ConstControl& control, #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideUpdatePlans(FullControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideUpdatePlans(FullControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -161,11 +161,11 @@ CS_>::wideUpdatePlans(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON -template +template FFSM2_CONSTEXPR(14) bool -CS_>::wideExitGuard(GuardControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideExitGuard(GuardControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); @@ -174,11 +174,11 @@ CS_>::wideExitGuard(GuardControl& control, //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideExit(PlanControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideExit(PlanControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { FFSM2_ASSERT(prong == PRONG_INDEX); diff --git a/development/ffsm2/detail/structure/forward.hpp b/development/ffsm2/detail/structure/forward.hpp index 8822392..16dfb8b 100644 --- a/development/ffsm2/detail/structure/forward.hpp +++ b/development/ffsm2/detail/structure/forward.hpp @@ -20,7 +20,7 @@ template struct WrapInfoT; template -struct WrapInfoT< TH> final { +struct WrapInfoT final { using Type = SI_; }; @@ -40,9 +40,28 @@ struct SI_ final { using Head = THead; using StateList = TL_; - static constexpr Short WIDTH = 1; + static constexpr Short WIDTH = 1; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList::SIZE; +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +struct CI_ final { + using Head = THead; + using HeadInfo = SI_; + using SubStates = CSI_>; + using StateList = typename SubStates::StateList; + + static constexpr Short WIDTH = sizeof...(TSubStates); + + static constexpr Long STATE_COUNT = StateList::SIZE; + +#if FFSM2_SERIALIZATION_AVAILABLE() + static constexpr Long WIDTH_BITS = static_cast(bitWidth(WIDTH)); + static constexpr Long ACTIVE_BITS = WIDTH_BITS; +#endif }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -53,7 +72,7 @@ struct CSI_> final { using Remaining = CSI_>; using StateList = Merge; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList::SIZE; }; template @@ -61,58 +80,42 @@ struct CSI_> final { using Initial = WrapInfo; using StateList = typename Initial::StateList; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList::SIZE; }; +// COMMON // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -struct CI_ final { - using Head = THead; - using HeadInfo = SI_; - using SubStates = CSI_>; - using StateList = typename SubStates::StateList; - - static constexpr Short WIDTH = sizeof...(TSubStates); - -#if FFSM2_SERIALIZATION_AVAILABLE() - static constexpr Long WIDTH_BITS = static_cast(bitWidth(WIDTH)); - static constexpr Long ACTIVE_BITS = WIDTH_BITS; -#endif - - static constexpr Long STATE_COUNT = StateList::SIZE; -}; - -// COMMON //////////////////////////////////////////////////////////////////////////////// -template +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload +> struct ArgsT final { - using Context = TContext; + using Config = TConfig; + using Context = typename Config::Context; using PureContext = Undecorate; #if FFSM2_LOG_INTERFACE_AVAILABLE() - using Logger = typename TConfig::LoggerInterface; + using Logger = typename Config::LoggerInterface; #endif using StateList = TStateList; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList ::SIZE; #if FFSM2_SERIALIZATION_AVAILABLE() - static constexpr Short SERIAL_BITS = NSerialBits; + static constexpr Short SERIAL_BITS = NSerialBits; #endif - static constexpr Short SUBSTITUTION_LIMIT = NSubstitutionLimit; + static constexpr Short SUBSTITUTION_LIMIT = Config::SUBSTITUTION_LIMIT; #if FFSM2_PLANS_AVAILABLE() - static constexpr Long TASK_CAPACITY = NTaskCapacity; + static constexpr Long TASK_CAPACITY = NTaskCapacity; #endif using Payload = TPayload; @@ -148,14 +151,14 @@ struct MaterialT_ final { using Type = S_; }; -template -struct MaterialT_ > { - using Type = C_< TA, EmptyT, TS...>; +template +struct MaterialT_ > { + using Type = C_< TA, EmptyT, TS...>; }; template -struct MaterialT_ > { - using Type = C_< TA, TH, TS...>; +struct MaterialT_ > { + using Type = C_< TA, TH, TS...>; }; template @@ -163,30 +166,33 @@ using MaterialT = typename MaterialT_::Type; //------------------------------------------------------------------------------ -template +template < + typename TConfig + , typename TApex +> struct RF_ final { - using Context = typename TConfig::Context; - using Apex = TApex; + using Config = TConfig; + using Context = typename Config::Context; + using Apex = TApex; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - using StateList = typename Apex::StateList; + using StateList = typename Apex::StateList; static constexpr Long STATE_COUNT = Apex::STATE_COUNT; - static constexpr Long SUBSTITUTION_LIMIT = TConfig::SUBSTITUTION_LIMIT; + static constexpr Short SUBSTITUTION_LIMIT = Config::SUBSTITUTION_LIMIT; #if FFSM2_PLANS_AVAILABLE() - static constexpr Long TASK_CAPACITY = TConfig::TASK_CAPACITY != INVALID_LONG ? - TConfig::TASK_CAPACITY : Apex::STATE_COUNT; + static constexpr Long TASK_CAPACITY = Config::TASK_CAPACITY != INVALID_LONG ? + Config::TASK_CAPACITY : Apex::STATE_COUNT; #endif - using Payload = typename TConfig::Payload; - using Transition = TransitionT; + using Payload = typename Config::Payload; + using Transition = TransitionT; #if FFSM2_PLANS_AVAILABLE() - using Task = typename TConfig::Task; + using Task = typename Config::Task; #endif #if FFSM2_SERIALIZATION_AVAILABLE() @@ -194,34 +200,34 @@ struct RF_ final { static constexpr Long SERIAL_BITS = 1 + ACTIVE_BITS; #endif - using Args = ArgsT; + using Args = ArgsT< + TConfig + , StateList + FFSM2_IF_SERIALIZATION(, SERIAL_BITS) + FFSM2_IF_PLANS(, TASK_CAPACITY) + , Payload + >; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - using Instance = InstanceT; + using Instance = InstanceT; - using ConstControl = ConstControlT; - using Control = ControlT ; - using FullControl = FullControlT ; - using GuardControl = GuardControlT; + using ConstControl = ConstControlT; + using Control = ControlT ; + using FullControl = FullControlT ; + using GuardControl = GuardControlT; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - using State = EmptyT; + using State = EmptyT ; template - using StateT = A_; + using StateT = A_; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #if FFSM2_LOG_INTERFACE_AVAILABLE() - using Logger = typename TConfig::LoggerInterface; + using Logger = typename Config::LoggerInterface; #endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/development/ffsm2/detail/structure/state.hpp b/development/ffsm2/detail/structure/state_1.hpp similarity index 90% rename from development/ffsm2/detail/structure/state.hpp rename to development/ffsm2/detail/structure/state_1.hpp index 0d0f8ed..2146971 100644 --- a/development/ffsm2/detail/structure/state.hpp +++ b/development/ffsm2/detail/structure/state_1.hpp @@ -1,19 +1,13 @@ namespace ffsm2 { namespace detail { -//------------------------------------------------------------------------------ - -#if FFSM2_DEBUG_STATE_TYPE_AVAILABLE() || FFSM2_STRUCTURE_REPORT_AVAILABLE() || FFSM2_LOG_INTERFACE_AVAILABLE() - -struct None {}; - -#endif - //////////////////////////////////////////////////////////////////////////////// -template +template < + StateID NStateId + , typename TArgs + , typename THead +> struct S_ : THead { @@ -36,6 +30,7 @@ struct S_ using FullControl = FullControlT ; using GuardControl = GuardControlT; + using Empty = EmptyT; using Head = THead; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -90,18 +85,14 @@ struct S_ #if FFSM2_DEBUG_STATE_TYPE_AVAILABLE() || FFSM2_STRUCTURE_REPORT_AVAILABLE() || FFSM2_LOG_INTERFACE_AVAILABLE() - using Empty = EmptyT; - - static FFSM2_CONSTEXPR(11) bool isBare() noexcept { return IsSameT::Value; } - - FFSM2_IF_TYPEINDEX(const std::type_index TYPE = isBare() ? typeid(None) : typeid(Head)); + FFSM2_IF_TYPEINDEX(const std::type_index TYPE = typeid(Head)); #endif - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #if FFSM2_LOG_INTERFACE_AVAILABLE() + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + template FFSM2_CONSTEXPR(14) void log(TReturn (THost::*)(TParams...), @@ -140,9 +131,9 @@ struct S_ const Method) const noexcept {} -#endif - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#endif }; //////////////////////////////////////////////////////////////////////////////// @@ -150,4 +141,4 @@ struct S_ } } -#include "state.inl" +#include "state_1.inl" diff --git a/development/ffsm2/detail/structure/state.inl b/development/ffsm2/detail/structure/state_1.inl similarity index 74% rename from development/ffsm2/detail/structure/state.inl rename to development/ffsm2/detail/structure/state_1.inl index fbd51fa..23a5ea2 100644 --- a/development/ffsm2/detail/structure/state.inl +++ b/development/ffsm2/detail/structure/state_1.inl @@ -4,10 +4,10 @@ namespace detail { //////////////////////////////////////////////////////////////////////////////// // COMMON -template +template FFSM2_CONSTEXPR(14) bool -S_::deepEntryGuard(GuardControl& control) noexcept { +S_::deepEntryGuard(GuardControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::entryGuard, Method::ENTRY_GUARD); @@ -23,10 +23,10 @@ S_::deepEntryGuard(GuardControl& control) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -S_::deepEnter(PlanControl& control) noexcept { +S_::deepEnter(PlanControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::enter, Method::ENTER); @@ -38,10 +38,10 @@ S_::deepEnter(PlanControl& control) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -S_::deepReenter(PlanControl& control) noexcept { +S_::deepReenter(PlanControl& control) noexcept { FFSM2_IF_PLANS(control._core.planData.verifyEmptyStatus(STATE_ID)); FFSM2_LOG_STATE_METHOD(&Head::reenter, @@ -55,10 +55,10 @@ S_::deepReenter(PlanControl& control) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepPreUpdate(FullControl& control) noexcept { +S_::deepPreUpdate(FullControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::preUpdate, Method::PRE_UPDATE); @@ -72,10 +72,10 @@ S_::deepPreUpdate(FullControl& control) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepUpdate(FullControl& control) noexcept { +S_::deepUpdate(FullControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::update, Method::UPDATE); @@ -89,10 +89,10 @@ S_::deepUpdate(FullControl& control) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepPostUpdate(FullControl& control) noexcept { +S_::deepPostUpdate(FullControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::postUpdate, Method::POST_UPDATE); @@ -106,11 +106,11 @@ S_::deepPostUpdate(FullControl& control) noexcept { //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepPreReact(FullControl& control, +S_::deepPreReact(FullControl& control, const TEvent& event) noexcept { auto method = static_cast(&Head::preReact); @@ -128,11 +128,11 @@ S_::deepPreReact(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepReact(FullControl& control, +S_::deepReact(FullControl& control, const TEvent& event) noexcept { auto method = static_cast(&Head::react); @@ -150,11 +150,11 @@ S_::deepReact(FullControl& control, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepPostReact(FullControl& control, +S_::deepPostReact(FullControl& control, const TEvent& event) noexcept { auto method = static_cast(&Head::postReact); @@ -172,11 +172,11 @@ S_::deepPostReact(FullControl& control, //------------------------------------------------------------------------------ -template +template template FFSM2_CONSTEXPR(14) void -S_::deepQuery(ConstControl& control, +S_::deepQuery(ConstControl& control, TEvent& event) const noexcept { auto method = static_cast(&Head::query); @@ -194,10 +194,10 @@ S_::deepQuery(ConstControl& control, #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepUpdatePlans(FullControl& control) noexcept { +S_::deepUpdatePlans(FullControl& control) noexcept { if (control._core.planData.tasksFailures .get(STATE_ID)) return TaskStatus{TaskStatus::FAILURE}; else @@ -211,10 +211,10 @@ S_::deepUpdatePlans(FullControl& control) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) bool -S_::deepExitGuard(GuardControl& control) noexcept { +S_::deepExitGuard(GuardControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::exitGuard, Method::EXIT_GUARD); @@ -230,10 +230,10 @@ S_::deepExitGuard(GuardControl& control) noexcept { //------------------------------------------------------------------------------ -template +template FFSM2_CONSTEXPR(14) void -S_::deepExit(PlanControl& control) noexcept { +S_::deepExit(PlanControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::exit, Method::EXIT); @@ -254,10 +254,10 @@ S_::deepExit(PlanControl& control) noexcept { #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -S_::wrapPlanSucceeded(FullControl& control) noexcept { +S_::wrapPlanSucceeded(FullControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::planSucceeded, Method::PLAN_SUCCEEDED); @@ -268,10 +268,10 @@ S_::wrapPlanSucceeded(FullControl& control) noexcept { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template +template FFSM2_CONSTEXPR(14) void -S_::wrapPlanFailed(FullControl& control) noexcept { +S_::wrapPlanFailed(FullControl& control) noexcept { FFSM2_LOG_STATE_METHOD(&Head::planFailed, Method::PLAN_FAILED); @@ -282,6 +282,16 @@ S_::wrapPlanFailed(FullControl& control) noexcept { #endif +//------------------------------------------------------------------------------ + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + +//------------------------------------------------------------------------------ + +#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#endif + /////////////////////////////////////////////////////////////////////////////// } diff --git a/development/ffsm2/detail/structure/state_2.hpp b/development/ffsm2/detail/structure/state_2.hpp new file mode 100644 index 0000000..4209b05 --- /dev/null +++ b/development/ffsm2/detail/structure/state_2.hpp @@ -0,0 +1,129 @@ +namespace ffsm2 { +namespace detail { + +//------------------------------------------------------------------------------ + +#if FFSM2_DEBUG_STATE_TYPE_AVAILABLE() || FFSM2_STRUCTURE_REPORT_AVAILABLE() || FFSM2_LOG_INTERFACE_AVAILABLE() + +struct None {}; + +#endif + +//////////////////////////////////////////////////////////////////////////////// + +template < + StateID NStateId + , typename TArgs +> +struct S_> + : EmptyT +{ + static constexpr StateID STATE_ID = NStateId; + + using Context = typename TArgs::Context; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using Logger = typename TArgs::Logger; +#endif + + using ConstControl = ConstControlT; + using ScopedCOrigin = typename ConstControl::Origin; + + using Control = ControlT ; + + using PlanControl = PlanControlT ; + using ScopedOrigin = typename PlanControl::Origin; + + using FullControl = FullControlT ; + using GuardControl = GuardControlT; + + using Empty = EmptyT; + using Head = Empty; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) bool deepEntryGuard (GuardControl& control ) noexcept; + + FFSM2_CONSTEXPR(14) void deepEnter ( PlanControl& control ) noexcept; + FFSM2_CONSTEXPR(14) void deepReenter ( PlanControl& control ) noexcept; + + FFSM2_CONSTEXPR(14) TaskStatus deepPreUpdate ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus deepUpdate ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus deepPostUpdate ( FullControl& control ) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus deepPreReact ( FullControl& control, const TEvent& event) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus deepReact ( FullControl& control, const TEvent& event) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus deepPostReact ( FullControl& control, const TEvent& event) noexcept; + + template + FFSM2_CONSTEXPR(14) void deepQuery (ConstControl& control, TEvent& event) const noexcept; + +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) TaskStatus deepUpdatePlans ( FullControl& control) noexcept; +#endif + + FFSM2_CONSTEXPR(14) bool deepExitGuard (GuardControl& control ) noexcept; + + FFSM2_CONSTEXPR(14) void deepExit ( PlanControl& control ) noexcept; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) void wrapPlanSucceeded ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) void wrapPlanFailed ( FullControl& control ) noexcept; +#endif + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + FFSM2_CONSTEXPR(14) void deepChangeToRequested( Control& ) noexcept {} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#if FFSM2_DEBUG_STATE_TYPE_AVAILABLE() || FFSM2_STRUCTURE_REPORT_AVAILABLE() || FFSM2_LOG_INTERFACE_AVAILABLE() + + FFSM2_IF_TYPEINDEX(const std::type_index TYPE = typeid(None)); + +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + template + FFSM2_CONSTEXPR(14) + void log(TReturn (Empty::*)(TParams...), + Logger&, + const Context&, + const Method) const noexcept + {} + + template + FFSM2_CONSTEXPR(14) + void log(TReturn (Empty::*)(TParams...) const, + Logger&, + const Context&, + const Method) const noexcept + {} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +#endif +}; + +//////////////////////////////////////////////////////////////////////////////// + +} +} + +#include "state_2.inl" diff --git a/development/ffsm2/detail/structure/state_2.inl b/development/ffsm2/detail/structure/state_2.inl new file mode 100644 index 0000000..37006a2 --- /dev/null +++ b/development/ffsm2/detail/structure/state_2.inl @@ -0,0 +1,210 @@ +namespace ffsm2 { +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// +// COMMON + +template +FFSM2_CONSTEXPR(14) +bool +S_>::deepEntryGuard(GuardControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::entryGuard, + Method::ENTRY_GUARD); + + return false; +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +void +S_>::deepEnter(PlanControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::enter, + Method::ENTER); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +S_>::deepReenter(PlanControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::reenter, + Method::REENTER); +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_>::deepPreUpdate(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::preUpdate, + Method::PRE_UPDATE); + + return TaskStatus{}; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_>::deepUpdate(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::update, + Method::UPDATE); + + return TaskStatus{}; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_>::deepPostUpdate(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::postUpdate, + Method::POST_UPDATE); + + return TaskStatus{}; +} + +//------------------------------------------------------------------------------ + +template +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_>::deepPreReact(FullControl& FFSM2_IF_LOG_STATE_METHOD(control), + const TEvent& FFSM2_UNUSED(event)) noexcept +{ + FFSM2_LOG_STATE_METHOD(static_cast(&Empty::preReact), + Method::PRE_REACT); + + return TaskStatus{}; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_>::deepReact(FullControl& FFSM2_IF_LOG_STATE_METHOD(control), + const TEvent& FFSM2_UNUSED(event)) noexcept +{ + FFSM2_LOG_STATE_METHOD(static_cast(&Empty::react), + Method::REACT); + + return TaskStatus{}; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_>::deepPostReact(FullControl& FFSM2_IF_LOG_STATE_METHOD(control), + const TEvent& FFSM2_UNUSED(event)) noexcept +{ + FFSM2_LOG_STATE_METHOD(static_cast(&Empty::postReact), + Method::POST_REACT); + + return TaskStatus{}; +} + +//------------------------------------------------------------------------------ + +template +template +FFSM2_CONSTEXPR(14) +void +S_>::deepQuery(ConstControl& FFSM2_IF_LOG_STATE_METHOD(control), + TEvent& FFSM2_UNUSED(event)) const noexcept +{ + FFSM2_LOG_STATE_METHOD(static_cast(&Empty::query), + Method::QUERY); +} + +//------------------------------------------------------------------------------ + +#if FFSM2_PLANS_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_>::deepUpdatePlans(FullControl& control) noexcept { + if (control._core.planData.tasksFailures .get(STATE_ID)) + return TaskStatus{TaskStatus::FAILURE}; + else + if (control._core.planData.tasksSuccesses.get(STATE_ID)) + return TaskStatus{TaskStatus::SUCCESS}; + else + return TaskStatus{}; +} + +#endif + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +bool +S_>::deepExitGuard(GuardControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::exitGuard, + Method::EXIT_GUARD); + + return false; +} + +//------------------------------------------------------------------------------ + +template +FFSM2_CONSTEXPR(14) +void +S_>::deepExit(PlanControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::exit, + Method::EXIT); +} + +//------------------------------------------------------------------------------ + +#if FFSM2_PLANS_AVAILABLE() + +template +FFSM2_CONSTEXPR(14) +void +S_>::wrapPlanSucceeded(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::planSucceeded, + Method::PLAN_SUCCEEDED); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +template +FFSM2_CONSTEXPR(14) +void +S_>::wrapPlanFailed(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::planFailed, + Method::PLAN_FAILED); + +} + +#endif + +//------------------------------------------------------------------------------ + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + +//------------------------------------------------------------------------------ + +#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#endif + +/////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/development/ffsm2/machine_dev.hpp b/development/ffsm2/machine_dev.hpp index 9b1d4f6..cd0b6fb 100644 --- a/development/ffsm2/machine_dev.hpp +++ b/development/ffsm2/machine_dev.hpp @@ -1,5 +1,5 @@ // FFSM2 (flat state machine for games and interactive applications) -// 2.3.2 (2023-10-25) +// 2.3.3 (2023-12-21) // // Created by Andrew Gresyk // @@ -33,7 +33,7 @@ #define FFSM2_VERSION_MAJOR 2 #define FFSM2_VERSION_MINOR 3 -#define FFSM2_VERSION_PATCH 2 +#define FFSM2_VERSION_PATCH 3 #define FFSM2_VERSION (10000 * FFSM2_VERSION_MAJOR + 100 * FFSM2_VERSION_MINOR + FFSM2_VERSION_PATCH) @@ -58,159 +58,40 @@ #include "detail/shared/bit_stream.hpp" #include "detail/shared/type_list.hpp" -#include "detail/features/common.hpp" -#include "detail/features/logger_interface.hpp" - #include "detail/containers/array.hpp" #include "detail/containers/bit_array.hpp" -#include "detail/containers/task_list.hpp" + +#include "detail/features/transition.hpp" +#include "detail/features/logger_interface.hpp" +#include "detail/features/task.hpp" +#include "detail/features/task_list.hpp" #include "detail/root/registry.hpp" #include "detail/root/plan_data.hpp" -#include "detail/root/plan.hpp" +#include "detail/root/plan_0.hpp" +#include "detail/root/plan_1.hpp" +#include "detail/root/plan_2.hpp" #include "detail/root/core.hpp" -#include "detail/root/control.hpp" - -#include "detail/structure/ancestors.hpp" -#include "detail/structure/state.hpp" +#include "detail/root/control_0.hpp" +#include "detail/root/control_1.hpp" +#include "detail/root/control_2.hpp" +#include "detail/root/control_3.hpp" +#include "detail/root/control_4.hpp" + +#include "detail/structure/base.hpp" +#include "detail/structure/ancestors_1.hpp" +#include "detail/structure/ancestors_2.hpp" +#include "detail/structure/state_1.hpp" +#include "detail/structure/state_2.hpp" #include "detail/structure/forward.hpp" -#include "detail/structure/composite_sub.hpp" +#include "detail/structure/composite_sub_1.hpp" +#include "detail/structure/composite_sub_2.hpp" #include "detail/structure/composite.hpp" -namespace ffsm2 { -namespace detail { - -//////////////////////////////////////////////////////////////////////////////// - -template -struct G_ final { - static constexpr FeatureTag FEATURE_TAG = NFeatureTag; - - using Context = TContext; - using Activation = TActivation; - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using LoggerInterface = LoggerInterfaceT; -#endif - - static constexpr Long SUBSTITUTION_LIMIT = NSubstitutionLimit; - -#if FFSM2_PLANS_AVAILABLE() - static constexpr Long TASK_CAPACITY = NTaskCapacity; -#endif - - using Payload = TPayload; - using Transition = TransitionT; - -#if FFSM2_PLANS_AVAILABLE() - using Task = TaskT; -#endif - - /// @brief Set Context type - /// @tparam T Context type for data shared between states and/or data interface between FSM and external code - template - using ContextT = G_; - - /// @brief Select manual activation strategy - using ManualActivation = G_; - -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif - - /// @brief Set Substitution limit - /// @tparam N Maximum number times 'guard()' methods can substitute their states for others - template - using SubstitutionLimitN = G_; - -#if FFSM2_PLANS_AVAILABLE() - - /// @brief Set Task capacity - /// @tparam N Maximum number of tasks across all plans - template - using TaskCapacityN = G_; - -#endif - - /// @brief Set Transition Payload type - /// @tparam T Utility type for 'TUtility State::utility() const' method - template - using PayloadT = G_; -}; - -//////////////////////////////////////////////////////////////////////////////// - -template -struct M_; - -template -struct M_ > final { - using Cfg = G_; - - static constexpr FeatureTag FEATURE_TAG = NFeatureTag; - - using Context = TContext; - - using Payload = TPayload; - using Transition = TransitionT; - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using LoggerInterface = typename Cfg::LoggerInterface; -#endif - -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // COMMON - - /// @brief Root - /// @tparam THead Head state - /// @tparam TSubStates Sub-states - template - using Root = RF_>; - - /// @brief Headless root - /// @tparam TSubStates Sub-states - template < typename... TSubStates> - using PeerRoot = RF_>; - - // COMMON - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif -}; - -//////////////////////////////////////////////////////////////////////////////// - -} - -/// @brief Type configuration for MachineT<> -using Config = detail::G_; - -/// @brief 'Template namespace' for FSM classes -/// @tparam TConfig 'ConfigT<>' type configuration for MachineT<> -/// @see ConfigT<> -template -using MachineT = detail::M_; - -/// @brief 'Template namespace' for FSM classes parametrized with default types -using Machine = MachineT<>; - -//////////////////////////////////////////////////////////////////////////////// - -} - -#include "detail/root.hpp" +#include "detail/config.hpp" +#include "detail/root_0.hpp" +#include "detail/root_1.hpp" +#include "detail/root_2.hpp" +#include "detail/root_3.hpp" #include "detail/shared/macros_off.hpp" diff --git a/include/ffsm2/machine.hpp b/include/ffsm2/machine.hpp index b179524..ba914cc 100644 --- a/include/ffsm2/machine.hpp +++ b/include/ffsm2/machine.hpp @@ -1,5 +1,5 @@ // FFSM2 (flat state machine for games and interactive applications) -// 2.3.2 (2023-10-25) +// 2.3.3 (2023-12-21) // // Created by Andrew Gresyk // @@ -33,7 +33,7 @@ #define FFSM2_VERSION_MAJOR 2 #define FFSM2_VERSION_MINOR 3 -#define FFSM2_VERSION_PATCH 2 +#define FFSM2_VERSION_PATCH 3 #define FFSM2_VERSION (10000 * FFSM2_VERSION_MAJOR + 100 * FFSM2_VERSION_MINOR + FFSM2_VERSION_PATCH) @@ -49,7 +49,6 @@ #include // __debugbreak() #endif - #define FFSM2_UNUSED(x) #define FFSM2_ATTRIBUTE(A) FFSM2_ATTRIBUTE_##A() @@ -264,16 +263,22 @@ if (auto* const logger = control._core.logger) \ logger->recordMethod(control.context(), STATE_ID, METHOD_ID) + #define FFSM2_IF_LOG_STATE_METHOD(...) __VA_ARGS__ + #elif FFSM2_LOG_INTERFACE_AVAILABLE() #define FFSM2_LOG_STATE_METHOD(METHOD, METHOD_ID) \ if (auto* const logger = control._core.logger) \ log(METHOD, *logger, control.context(), METHOD_ID) + #define FFSM2_IF_LOG_STATE_METHOD(...) __VA_ARGS__ + #else #define FFSM2_LOG_STATE_METHOD(METHOD, METHOD_ID) + #define FFSM2_IF_LOG_STATE_METHOD(...) + #endif namespace ffsm2 { @@ -316,10 +321,8 @@ constexpr FeatureTag FFSM2_FEATURE_TAG = FFSM2_TYPEINDEX_MASK #pragma GCC diagnostic ignored "-Wpedantic" // error : extra ';' #endif - namespace ffsm2 { -struct EmptyContext {}; struct EmptyPayload final {}; struct Automatic; @@ -328,40 +331,39 @@ struct Manual; using Short = uint8_t; static constexpr Short INVALID_SHORT = UINT8_MAX; +using Prong = Short; +static constexpr Prong INVALID_PRONG = INVALID_SHORT; + using Long = uint8_t; static constexpr Long INVALID_LONG = UINT8_MAX; using StateID = Long; static constexpr StateID INVALID_STATE_ID = INVALID_LONG; -template +template < + bool B + , typename TT + , typename TF +> struct ConditionalT final { using Type = TT; }; -template +template < + typename TT + , typename TF +> struct ConditionalT final { using Type = TF; }; -template +template < + bool B + , typename TT + , typename TF +> using Conditional = typename ConditionalT::Type; -template -struct IsSameT final { - static constexpr bool Value = false; -}; - -template -struct IsSameT final { - static constexpr bool Value = true; -}; - template struct RemoveConstT final { using Type = T; @@ -556,7 +558,7 @@ class IteratorT { using Index = typename Container::Index; template - friend class ArrayT; + friend class DynamicArrayT; private: FFSM2_CONSTEXPR(11) IteratorT(Container& container, @@ -598,7 +600,7 @@ class IteratorT { using Index = typename Container::Index; template - friend class ArrayT; + friend class DynamicArrayT; private: FFSM2_CONSTEXPR(11) IteratorT(const Container& container, @@ -726,16 +728,15 @@ class BitReadStreamT final { } } - #if FFSM2_SERIALIZATION_AVAILABLE() namespace ffsm2 { namespace detail { -template +template FFSM2_CONSTEXPR(14) bool -StreamBufferT::operator == (const StreamBuffer& buffer) const noexcept { +StreamBufferT::operator == (const StreamBuffer& buffer) const noexcept { for (Long i = 0; i < BYTE_COUNT; ++i) if (_data[i] != buffer._data[i]) return false; @@ -743,10 +744,10 @@ StreamBufferT::operator == (const StreamBuffer& buffer) const noexcept { return true; } -template +template FFSM2_CONSTEXPR(14) bool -StreamBufferT::operator != (const StreamBuffer& buffer) const noexcept { +StreamBufferT::operator != (const StreamBuffer& buffer) const noexcept { for (Long i = 0; i < BYTE_COUNT; ++i) if (_data[i] != buffer._data[i]) return true; @@ -754,11 +755,11 @@ StreamBufferT::operator != (const StreamBuffer& buffer) const noexcept { return false; } -template +template template FFSM2_CONSTEXPR(14) void -BitWriteStreamT::write(const UBitWidth item) noexcept { +BitWriteStreamT::write(const UBitWidth item) noexcept { constexpr Short BIT_WIDTH = NBitWidth; static_assert(BIT_WIDTH > 0, "STATIC ASSERT"); @@ -784,11 +785,11 @@ BitWriteStreamT::write(const UBitWidth item) noexcept { } } -template +template template FFSM2_CONSTEXPR(14) UBitWidth -BitReadStreamT::read() noexcept { +BitReadStreamT::read() noexcept { constexpr Short BIT_WIDTH = NBitWidth; static_assert(BIT_WIDTH > 0, "STATIC ASSERT"); @@ -823,6 +824,7 @@ BitReadStreamT::read() noexcept { } #endif + #endif namespace ffsm2 { @@ -919,8 +921,8 @@ struct FindImpl {}; template -struct FindImpl - : FindImpl +struct FindImpl + : FindImpl {}; template @@ -947,732 +949,707 @@ constexpr bool contains() noexcept { return detail::Find::VALUE != INV } namespace ffsm2 { +namespace detail { -enum class Method : uint8_t { - NONE, +template +FFSM2_CONSTEXPR(11) +T +filler() noexcept { + return T{}; +} - ENTRY_GUARD, - ENTER, - REENTER, - PRE_UPDATE, - UPDATE, - POST_UPDATE, - PRE_REACT, - REACT, - QUERY, - POST_REACT, - EXIT_GUARD, - EXIT, +template <> +FFSM2_CONSTEXPR(11) +Short +filler() noexcept { + return INVALID_SHORT; +} -#if FFSM2_PLANS_AVAILABLE() - PLAN_SUCCEEDED, - PLAN_FAILED, -#endif +template +class StaticArrayT final { + template + friend class IteratorT; - COUNT -}; +public: + using Iterator = IteratorT< StaticArrayT>; + using CIterator = IteratorT; -#if FFSM2_PLANS_AVAILABLE() + using Item = T; + using Index = UCapacity; -enum class StatusEvent : uint8_t { - SUCCEEDED, - FAILED, + static constexpr Index CAPACITY = NCapacity; - COUNT -}; +public: + FFSM2_CONSTEXPR(14) StaticArrayT() = default; + FFSM2_CONSTEXPR(14) StaticArrayT(const Item filler) noexcept { fill(filler); } -#endif + template + FFSM2_CONSTEXPR(14) Item& operator[] (const N index) noexcept; -#if FFSM2_TYPEINDEX_AVAILABLE() + template + FFSM2_CONSTEXPR(14) const Item& operator[] (const N index) const noexcept; -static -inline -const char* -stateName(const std::type_index stateType) noexcept { - const char* const raw = stateType.name(); + FFSM2_CONSTEXPR(11) Index count() const noexcept { return CAPACITY; } - #if defined(_MSC_VER) + FFSM2_CONSTEXPR(14) void fill(const Item filler) noexcept; + FFSM2_CONSTEXPR(14) void clear() noexcept { fill(filler()); } + FFSM2_CONSTEXPR(14) bool empty() const noexcept; - Short first = - raw[0] == 's' ? 7 : // Struct - raw[0] == 'c' ? 6 : // Class - 0; - return raw + first; + FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator(*this, first()); } + FFSM2_CONSTEXPR(11) CIterator begin() const noexcept { return CIterator(*this, first()); } + FFSM2_CONSTEXPR(11) CIterator cbegin() const noexcept { return CIterator(*this, first()); } - #elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + FFSM2_CONSTEXPR(14) Iterator end() noexcept { return Iterator(*this, limit()); } + FFSM2_CONSTEXPR(11) CIterator end() const noexcept { return CIterator(*this, limit()); } + FFSM2_CONSTEXPR(11) CIterator cend() const noexcept { return CIterator(*this, limit()); } - return raw; +private: + FFSM2_CONSTEXPR(11) Index first() const noexcept { return 0; } + FFSM2_CONSTEXPR(11) Index next(const Index index) const noexcept { return index + 1; } + FFSM2_CONSTEXPR(11) Index limit() const noexcept { return CAPACITY; } - #else +private: + Item _items[CAPACITY] {}; +}; - return raw; +template +struct StaticArrayT final { + using Item = T; - #endif -} + FFSM2_CONSTEXPR(11) StaticArrayT() = default; + FFSM2_CONSTEXPR(11) StaticArrayT(const Item) noexcept {} +}; -#endif +template +class DynamicArrayT final { + template + friend class IteratorT; -static -FFSM2_CONSTEXPR(14) -const char* -methodName(const Method method) noexcept { - switch (method) { - case Method::ENTRY_GUARD: return "entryGuard"; - case Method::ENTER: return "enter"; - case Method::REENTER: return "reenter"; - case Method::PRE_UPDATE: return "preUpdate"; - case Method::UPDATE: return "update"; - case Method::POST_UPDATE: return "postUpdate"; - case Method::PRE_REACT: return "preReact"; - case Method::REACT: return "react"; - case Method::POST_REACT: return "postReact"; - case Method::QUERY: return "query"; - case Method::EXIT_GUARD: return "exitGuard"; - case Method::EXIT: return "exit"; +public: + using Iterator = IteratorT< DynamicArrayT>; + using CIterator = IteratorT; -#if FFSM2_PLANS_AVAILABLE() - case Method::PLAN_SUCCEEDED: return "planSucceeded"; - case Method::PLAN_FAILED: return "planFailed"; -#endif + using Item = T; + using Index = UCapacity; - default: - FFSM2_BREAK(); - return nullptr; - } -} + static constexpr Index CAPACITY = NCapacity; -namespace detail { +public: + template + FFSM2_CONSTEXPR(14) Index emplace(const TArgs &... args) noexcept; -#pragma pack(push, 1) + template + FFSM2_CONSTEXPR(14) Index emplace( TArgs&&... args) noexcept; -#ifdef _MSC_VER - #pragma warning(push) - #pragma warning(disable: 4324) // structure was padded due to alignment specifier -#endif + template + FFSM2_CONSTEXPR(14) Item& operator[] (const N index) noexcept; -struct TransitionBase { - FFSM2_CONSTEXPR(11) - TransitionBase() noexcept = default; + template + FFSM2_CONSTEXPR(14) const Item& operator[] (const N index) const noexcept; - FFSM2_CONSTEXPR(11) - TransitionBase(const StateID destination_) noexcept - : destination{destination_} - {} + FFSM2_CONSTEXPR(11) Index count() const noexcept { return _count; } - FFSM2_CONSTEXPR(11) - TransitionBase(const StateID origin_, - const StateID destination_) noexcept - : origin {origin_} - , destination{destination_} - {} + FFSM2_CONSTEXPR(14) void clear() noexcept { _count = 0; } + FFSM2_CONSTEXPR(11) bool empty() const noexcept { return _count == 0; } - FFSM2_CONSTEXPR(11) - bool - operator == (const TransitionBase& other) const noexcept { - return origin == other.origin && - destination == other.destination && - method == other.method; - } + FFSM2_CONSTEXPR(14) DynamicArrayT& operator += (const Item & item) noexcept; + FFSM2_CONSTEXPR(14) DynamicArrayT& operator += ( Item&& item) noexcept; - FFSM2_CONSTEXPR(11) - bool - operator != (const TransitionBase& other) const noexcept { - return origin != other.origin || - destination != other.destination || - method != other.method; - } + template + FFSM2_CONSTEXPR(14) DynamicArrayT& operator += (const DynamicArrayT& other) noexcept; - FFSM2_CONSTEXPR(11) - explicit - operator bool() const noexcept { - return destination != INVALID_STATE_ID; - } + FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator(*this, first()); } + FFSM2_CONSTEXPR(11) CIterator begin() const noexcept { return CIterator(*this, first()); } + FFSM2_CONSTEXPR(11) CIterator cbegin() const noexcept { return CIterator(*this, first()); } - FFSM2_CONSTEXPR(14) - void - clear() noexcept { - destination = INVALID_STATE_ID; - } + FFSM2_CONSTEXPR(14) Iterator end() noexcept { return Iterator(*this, limit()); } + FFSM2_CONSTEXPR(11) CIterator end() const noexcept { return CIterator(*this, limit()); } + FFSM2_CONSTEXPR(11) CIterator cend() const noexcept { return CIterator(*this, limit()); } - StateID origin = INVALID_STATE_ID; - StateID destination = INVALID_STATE_ID; - Method method = Method::NONE; +private: + FFSM2_CONSTEXPR(11) Index first() const noexcept { return 0; } + FFSM2_CONSTEXPR(11) Index next(const Index index) const noexcept { return index + 1; } + FFSM2_CONSTEXPR(11) Index limit() const noexcept { return _count; } + +private: + Index _count = 0; + Item _items[CAPACITY] {}; }; -#ifdef _MSC_VER - #pragma warning(pop) -#endif +template +class DynamicArrayT final { +public: + using Item = T; + using Index = UCapacity<0>; -template -struct TransitionT final - : TransitionBase -{ - using Payload = TPayload; - using Storage = uint8_t[sizeof(Payload)]; + static constexpr Index CAPACITY = 0; +}; - using TransitionBase::TransitionBase; +} +} - FFSM2_CONSTEXPR(14) - TransitionT() noexcept { - new (&storage) Payload{}; - } +namespace ffsm2 { +namespace detail { - FFSM2_CONSTEXPR(14) - TransitionT(const StateID destination_, - const Payload& payload) noexcept - : TransitionBase{destination_} - , payloadSet{true} - { - new (&storage) Payload{payload}; - } +template +template +FFSM2_CONSTEXPR(14) +T& +StaticArrayT::operator[] (const N index) noexcept { + FFSM2_ASSERT(0 <= index && index < CAPACITY); - FFSM2_CONSTEXPR(14) - TransitionT(const StateID origin_, - const StateID destination_, - const Payload& payload) noexcept - : TransitionBase{origin_, destination_} - , payloadSet{true} - { - new (&storage) Payload{payload}; - } + return _items[static_cast(index)]; +} - FFSM2_CONSTEXPR(11) - bool - operator == (const TransitionT& other) const noexcept { - return TransitionBase::operator == (other) && - (payloadSet == other.payloadSet); - // (!payloadSet && !other.payloadSet || payload == other.payload); - } - - FFSM2_CONSTEXPR(11) - bool - operator != (const TransitionT& other) const noexcept { - return TransitionBase::operator != (other) || - (payloadSet != other.payloadSet); - // (payloadSet |= other.payloadSet || payload != other.payload); - } - - FFSM2_CONSTEXPR(11) - const Payload* - payload() const noexcept { - return payloadSet ? - reinterpret_cast(&storage) : nullptr; - } - -#ifdef _MSC_VER - #pragma warning(push) - #pragma warning(disable: 4324) // structure was padded due to alignment specifier -#endif - - alignas(Payload) Storage storage {}; - -#ifdef _MSC_VER - #pragma warning(pop) -#endif - - bool payloadSet = false; -}; - -template <> -struct TransitionT final - : TransitionBase -{ - using TransitionBase::TransitionBase; -}; - -#pragma pack(pop) +template +template +FFSM2_CONSTEXPR(14) +const T& +StaticArrayT::operator[] (const N index) const noexcept { + FFSM2_ASSERT(0 <= index && index < CAPACITY); + return _items[static_cast(index)]; } -struct Request final { - Short index; -}; - +template +FFSM2_CONSTEXPR(14) +void +StaticArrayT::fill(const Item filler) noexcept { + for (Item& item : _items) + item = filler; } -namespace ffsm2 { - -#if FFSM2_LOG_INTERFACE_AVAILABLE() - -template -struct LoggerInterfaceT { - using Context = TContext; +template +FFSM2_CONSTEXPR(14) +bool +StaticArrayT::empty() const noexcept { + for (const Item& item : _items) + if (item != filler()) + return false; - using Method = ::ffsm2::Method; - using StateID = ::ffsm2::StateID; + return true; +} -#if FFSM2_PLANS_AVAILABLE() - using StatusEvent = ::ffsm2::StatusEvent; -#endif +template +template +FFSM2_CONSTEXPR(14) +typename DynamicArrayT::Index +DynamicArrayT::emplace(const TArgs&... args) noexcept { + FFSM2_ASSERT(_count < CAPACITY); - FFSM2_CONSTEXPR(NO) - virtual - void - recordMethod(const Context& FFSM2_UNUSED(context), - const StateID FFSM2_UNUSED(origin), - const Method FFSM2_UNUSED(method)) noexcept - {} + new (&_items[_count]) Item{args...}; - FFSM2_CONSTEXPR(NO) - virtual - void - recordTransition(const Context& FFSM2_UNUSED(context), - const StateID FFSM2_UNUSED(origin), - const StateID FFSM2_UNUSED(target)) noexcept - {} + return _count++; +} -#if FFSM2_PLANS_AVAILABLE() +template +template +FFSM2_CONSTEXPR(14) +typename DynamicArrayT::Index +DynamicArrayT::emplace(TArgs&&... args) noexcept { + FFSM2_ASSERT(_count < CAPACITY); - FFSM2_CONSTEXPR(NO) - virtual - void - recordTaskStatus(const Context& FFSM2_UNUSED(context), - const StateID FFSM2_UNUSED(origin), - const StatusEvent FFSM2_UNUSED(event)) noexcept - {} + new (&_items[_count]) Item{forward(args)...}; - FFSM2_CONSTEXPR(NO) - virtual - void - recordPlanStatus(const Context& FFSM2_UNUSED(context), - const StatusEvent FFSM2_UNUSED(event)) noexcept - {} + return _count++; +} -#endif +template +template +FFSM2_CONSTEXPR(14) +typename DynamicArrayT::Item& +DynamicArrayT::operator[] (const N index) noexcept { + FFSM2_ASSERT(0 <= index && index < _count); - FFSM2_CONSTEXPR(NO) - virtual - void - recordCancelledPending(const Context& FFSM2_UNUSED(context), - const StateID FFSM2_UNUSED(origin)) noexcept - {} + return _items[static_cast(index)]; +} -}; +template +template +FFSM2_CONSTEXPR(14) +const typename DynamicArrayT::Item& +DynamicArrayT::operator[] (const N index) const noexcept { + FFSM2_ASSERT(0 <= index && index < _count); -#else + return _items[static_cast(index)]; +} -template -using LoggerInterfaceT = void; +template +FFSM2_CONSTEXPR(14) +DynamicArrayT& +DynamicArrayT::operator += (const Item& item) noexcept { + emplace(item); -#endif + return *this; +} -using LoggerInterface = LoggerInterfaceT<>; +template +FFSM2_CONSTEXPR(14) +DynamicArrayT& +DynamicArrayT::operator += (Item&& item) noexcept { + emplace(move(item)); + return *this; } -namespace ffsm2 { -namespace detail { +template +template +FFSM2_CONSTEXPR(14) +DynamicArrayT& +DynamicArrayT::operator += (const DynamicArrayT& other) noexcept { + for (const auto& item : other) + emplace(item); -template -FFSM2_CONSTEXPR(11) -T -filler() noexcept { - return T{}; + return *this; } -template <> -FFSM2_CONSTEXPR(11) -Short -filler() noexcept { - return INVALID_SHORT; +} } -template -class StaticArrayT final { - template - friend class IteratorT; - -public: - using Iterator = IteratorT< StaticArrayT>; - using CIterator = IteratorT; - - using Item = T; - using Index = UCapacity; - - static constexpr Index CAPACITY = NCapacity; - -public: - FFSM2_CONSTEXPR(14) StaticArrayT() = default; - FFSM2_CONSTEXPR(14) StaticArrayT(const Item filler) noexcept { fill(filler); } - - template - FFSM2_CONSTEXPR(14) Item& operator[] (const N index) noexcept; - - template - FFSM2_CONSTEXPR(14) const Item& operator[] (const N index) const noexcept; - - FFSM2_CONSTEXPR(11) Index count() const noexcept { return CAPACITY; } - - FFSM2_CONSTEXPR(14) void fill(const Item filler) noexcept; - FFSM2_CONSTEXPR(14) void clear() noexcept { fill(filler()); } - FFSM2_CONSTEXPR(14) bool empty() const noexcept; - - FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator(*this, first()); } - FFSM2_CONSTEXPR(11) CIterator begin() const noexcept { return CIterator(*this, first()); } - FFSM2_CONSTEXPR(11) CIterator cbegin() const noexcept { return CIterator(*this, first()); } - - FFSM2_CONSTEXPR(14) Iterator end() noexcept { return Iterator(*this, limit()); } - FFSM2_CONSTEXPR(11) CIterator end() const noexcept { return CIterator(*this, limit()); } - FFSM2_CONSTEXPR(11) CIterator cend() const noexcept { return CIterator(*this, limit()); } - -private: - FFSM2_CONSTEXPR(11) Index first() const noexcept { return 0; } - FFSM2_CONSTEXPR(11) Index next(const Index index) const noexcept { return index + 1; } - FFSM2_CONSTEXPR(11) Index limit() const noexcept { return CAPACITY; } - -private: - Item _items[CAPACITY] {}; -}; - -template -struct StaticArrayT final { - using Item = T; - - FFSM2_CONSTEXPR(11) StaticArrayT() = default; - FFSM2_CONSTEXPR(11) StaticArrayT(const Item) noexcept {} -}; +#if FFSM2_PLANS_AVAILABLE() -template -class ArrayT final { - template - friend class IteratorT; +namespace ffsm2 { +namespace detail { +template +class BitArrayT final { public: - using Iterator = IteratorT< ArrayT>; - using CIterator = IteratorT; - - using Item = T; using Index = UCapacity; - static constexpr Index CAPACITY = NCapacity; - -public: - template - FFSM2_CONSTEXPR(14) Index emplace(const TArgs &... args) noexcept; + static constexpr Index CAPACITY = NCapacity; + static constexpr Index UNIT_COUNT = contain(CAPACITY, 8); - template - FFSM2_CONSTEXPR(14) Index emplace( TArgs&&... args) noexcept; + using BitArray = BitArrayT; - template - FFSM2_CONSTEXPR(14) Item& operator[] (const N index) noexcept; +public: + FFSM2_CONSTEXPR(14) BitArrayT() noexcept { clear(); } - template - FFSM2_CONSTEXPR(14) const Item& operator[] (const N index) const noexcept; + FFSM2_CONSTEXPR(14) void set() noexcept; - FFSM2_CONSTEXPR(11) Index count() const noexcept { return _count; } + FFSM2_CONSTEXPR(14) void clear() noexcept; - FFSM2_CONSTEXPR(14) void clear() noexcept { _count = 0; } - FFSM2_CONSTEXPR(11) bool empty() const noexcept { return _count == 0; } + FFSM2_CONSTEXPR(14) bool empty() const noexcept; - FFSM2_CONSTEXPR(14) ArrayT& operator += (const Item & item) noexcept; - FFSM2_CONSTEXPR(14) ArrayT& operator += ( Item&& item) noexcept; + template + FFSM2_CONSTEXPR(14) bool get (const TIndex index) const noexcept; - template - FFSM2_CONSTEXPR(14) ArrayT& operator += (const ArrayT& other) noexcept; + template + FFSM2_CONSTEXPR(14) void set (const TIndex index) noexcept; - FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator(*this, first()); } - FFSM2_CONSTEXPR(11) CIterator begin() const noexcept { return CIterator(*this, first()); } - FFSM2_CONSTEXPR(11) CIterator cbegin() const noexcept { return CIterator(*this, first()); } + template + FFSM2_CONSTEXPR(14) void clear(const TIndex index) noexcept; - FFSM2_CONSTEXPR(14) Iterator end() noexcept { return Iterator(*this, limit()); } - FFSM2_CONSTEXPR(11) CIterator end() const noexcept { return CIterator(*this, limit()); } - FFSM2_CONSTEXPR(11) CIterator cend() const noexcept { return CIterator(*this, limit()); } + FFSM2_CONSTEXPR(14) bool operator & (const BitArray& other) const noexcept; -private: - FFSM2_CONSTEXPR(11) Index first() const noexcept { return 0; } - FFSM2_CONSTEXPR(11) Index next(const Index index) const noexcept { return index + 1; } - FFSM2_CONSTEXPR(11) Index limit() const noexcept { return _count; } + FFSM2_CONSTEXPR(14) void operator &= (const BitArray& other) noexcept; private: - Index _count = 0; - Item _items[CAPACITY] {}; + uint8_t _storage[UNIT_COUNT] {}; }; -template -class ArrayT final { +template <> +class BitArrayT<0> final { public: - using Item = T; - using Index = UCapacity<0>; + FFSM2_CONSTEXPR(14) void clear() noexcept {} - static constexpr Index CAPACITY = 0; + FFSM2_CONSTEXPR(11) bool empty() const noexcept { return true; } }; } } +#endif -namespace ffsm2 { -namespace detail { - -template -template -FFSM2_CONSTEXPR(14) -T& -StaticArrayT::operator[] (const N index) noexcept { - FFSM2_ASSERT(0 <= index && index < CAPACITY); - - return _items[static_cast(index)]; -} +#if FFSM2_PLANS_AVAILABLE() -template -template -FFSM2_CONSTEXPR(14) -const T& -StaticArrayT::operator[] (const N index) const noexcept { - FFSM2_ASSERT(0 <= index && index < CAPACITY); +namespace ffsm2 { +namespace detail { - return _items[static_cast(index)]; +template +FFSM2_CONSTEXPR(14) +void +BitArrayT::set() noexcept { + for (uint8_t& unit : _storage) + unit = UINT8_MAX; } -template +template FFSM2_CONSTEXPR(14) void -StaticArrayT::fill(const Item filler) noexcept { - for (Item& item : _items) - item = filler; +BitArrayT::clear() noexcept { + for (uint8_t& unit : _storage) + unit = uint8_t{0}; } -template +template FFSM2_CONSTEXPR(14) bool -StaticArrayT::empty() const noexcept { - for (const Item& item : _items) - if (item != filler()) +BitArrayT::empty() const noexcept { + for (const uint8_t& unit : _storage) + if (unit != uint8_t{0}) return false; return true; } -template -template +template +template FFSM2_CONSTEXPR(14) -typename ArrayT::Index -ArrayT::emplace(const TArgs&... args) noexcept { - FFSM2_ASSERT(_count < CAPACITY); +bool +BitArrayT::get(const TIndex index) const noexcept { + FFSM2_ASSERT(index < CAPACITY); - new (&_items[_count]) Item{args...}; + const Index unit = static_cast(index) / 8; + const Index bit = static_cast(index) % 8; + const uint8_t mask = 1 << bit; - return _count++; + return (_storage[unit] & mask) != 0; } -template -template +template +template FFSM2_CONSTEXPR(14) -typename ArrayT::Index -ArrayT::emplace(TArgs&&... args) noexcept { - FFSM2_ASSERT(_count < CAPACITY); +void +BitArrayT::set(const TIndex index) noexcept { + FFSM2_ASSERT(index < CAPACITY); - new (&_items[_count]) Item{forward(args)...}; + const Index unit = static_cast(index) / 8; + const Index bit = static_cast(index) % 8; + const uint8_t mask = 1 << bit; - return _count++; + _storage[unit] |= mask; } -template -template +template +template FFSM2_CONSTEXPR(14) -typename ArrayT::Item& -ArrayT::operator[] (const N index) noexcept { - FFSM2_ASSERT(0 <= index && index < CAPACITY); +void +BitArrayT::clear(const TIndex index) noexcept { + FFSM2_ASSERT(index < CAPACITY); - return _items[static_cast(index)]; + const Index unit = static_cast(index) / 8; + const Index bit = static_cast(index) % 8; + const uint8_t mask = 1 << bit; + + _storage[unit] &= ~mask; } -template -template +template FFSM2_CONSTEXPR(14) -const typename ArrayT::Item& -ArrayT::operator[] (const N index) const noexcept { - FFSM2_ASSERT(0 <= index && index < CAPACITY); +bool +BitArrayT::operator & (const BitArray& other) const noexcept { + for (Index i = 0; i < UNIT_COUNT; ++i) + if ((_storage[i] & other._storage[i]) == 0) + return false; - return _items[static_cast(index)]; + return true; } -template +template FFSM2_CONSTEXPR(14) -ArrayT& -ArrayT::operator += (const Item& item) noexcept { - emplace(item); +void +BitArrayT::operator &= (const BitArray& other) noexcept { + for (Index i = 0; i < UNIT_COUNT; ++i) + _storage[i] &= other._storage[i]; +} - return *this; +} } -template -FFSM2_CONSTEXPR(14) -ArrayT& -ArrayT::operator += (Item&& item) noexcept { - emplace(move(item)); +#endif - return *this; -} +namespace ffsm2 { -template -template -FFSM2_CONSTEXPR(14) -ArrayT& -ArrayT::operator += (const ArrayT& other) noexcept { - for (const auto& item : other) - emplace(item); +enum class Method : uint8_t { + NONE, - return *this; -} + ENTRY_GUARD, + ENTER, + REENTER, + PRE_UPDATE, + UPDATE, + POST_UPDATE, + PRE_REACT, + REACT, + QUERY, + POST_REACT, + EXIT_GUARD, + EXIT, -} -} +//#if FFSM2_PLANS_AVAILABLE() + PLAN_SUCCEEDED, + PLAN_FAILED, +//#endif + + COUNT +}; #if FFSM2_PLANS_AVAILABLE() -namespace ffsm2 { +enum class StatusEvent : uint8_t { + SUCCEEDED, + FAILED, + + COUNT +}; + +#endif + +static +FFSM2_CONSTEXPR(14) +const char* +methodName(const Method method) noexcept { + switch (method) { + case Method::ENTRY_GUARD: return "entryGuard"; + case Method::ENTER: return "enter"; + case Method::REENTER: return "reenter"; + case Method::PRE_UPDATE: return "preUpdate"; + case Method::UPDATE: return "update"; + case Method::POST_UPDATE: return "postUpdate"; + case Method::PRE_REACT: return "preReact"; + case Method::REACT: return "react"; + case Method::POST_REACT: return "postReact"; + case Method::QUERY: return "query"; + case Method::EXIT_GUARD: return "exitGuard"; + case Method::EXIT: return "exit"; + +//#if FFSM2_PLANS_AVAILABLE() + case Method::PLAN_SUCCEEDED: return "planSucceeded"; + case Method::PLAN_FAILED: return "planFailed"; +//#endif + + default: + FFSM2_BREAK(); + return nullptr; + } +} + namespace detail { -template -class BitArrayT final { -public: - using Index = UCapacity; +#pragma pack(push, 1) - static constexpr Index CAPACITY = NCapacity; - static constexpr Index UNIT_COUNT = contain(CAPACITY, 8); +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable: 4324) // structure was padded due to alignment specifier +#endif - using BitArray = BitArrayT; +struct TransitionBase { + FFSM2_CONSTEXPR(11) + TransitionBase() noexcept = default; -public: - FFSM2_CONSTEXPR(14) BitArrayT() noexcept { clear(); } + FFSM2_CONSTEXPR(11) + TransitionBase(const StateID destination_) noexcept + : destination{destination_} + {} - FFSM2_CONSTEXPR(14) void set() noexcept; + FFSM2_CONSTEXPR(11) + TransitionBase(const StateID origin_, + const StateID destination_) noexcept + : origin {origin_} + , destination{destination_} + {} - FFSM2_CONSTEXPR(14) void clear() noexcept; + FFSM2_CONSTEXPR(11) + bool + operator == (const TransitionBase& other) const noexcept { + return origin == other.origin && + destination == other.destination && + method == other.method; + } - FFSM2_CONSTEXPR(14) bool empty() const noexcept; + FFSM2_CONSTEXPR(11) + bool + operator != (const TransitionBase& other) const noexcept { + return origin != other.origin || + destination != other.destination || + method != other.method; + } - template - FFSM2_CONSTEXPR(14) bool get (const TIndex index) const noexcept; + FFSM2_CONSTEXPR(11) + explicit + operator bool() const noexcept { + return destination != INVALID_STATE_ID; + } - template - FFSM2_CONSTEXPR(14) void set (const TIndex index) noexcept; + FFSM2_CONSTEXPR(14) + void + clear() noexcept { + destination = INVALID_STATE_ID; + } - template - FFSM2_CONSTEXPR(14) void clear(const TIndex index) noexcept; + StateID origin = INVALID_STATE_ID; + StateID destination = INVALID_STATE_ID; + Method method = Method::NONE; +}; + +#ifdef _MSC_VER + #pragma warning(pop) +#endif + +template +struct TransitionT final + : TransitionBase +{ + using Payload = TPayload; + using Storage = uint8_t[sizeof(Payload)]; + + using TransitionBase::TransitionBase; + + FFSM2_CONSTEXPR(14) + TransitionT() noexcept { + new (&storage) Payload{}; + } + + FFSM2_CONSTEXPR(14) + TransitionT(const StateID destination_, + const Payload& payload) noexcept + : TransitionBase{destination_} + , payloadSet{true} + { + new (&storage) Payload{payload}; + } + + FFSM2_CONSTEXPR(14) + TransitionT(const StateID origin_, + const StateID destination_, + const Payload& payload) noexcept + : TransitionBase{origin_, destination_} + , payloadSet{true} + { + new (&storage) Payload{payload}; + } + + FFSM2_CONSTEXPR(11) + bool + operator == (const TransitionT& other) const noexcept { + return TransitionBase::operator == (other) && + (payloadSet == other.payloadSet); + // (!payloadSet && !other.payloadSet || payload == other.payload); + } + + FFSM2_CONSTEXPR(11) + bool + operator != (const TransitionT& other) const noexcept { + return TransitionBase::operator != (other) || + (payloadSet != other.payloadSet); + // (payloadSet |= other.payloadSet || payload != other.payload); + } + + FFSM2_CONSTEXPR(11) + const Payload* + payload() const noexcept { + return payloadSet ? + reinterpret_cast(&storage) : nullptr; + } + +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable: 4324) // structure was padded due to alignment specifier +#endif - FFSM2_CONSTEXPR(14) bool operator & (const BitArray& other) const noexcept; + alignas(Payload) Storage storage {}; - FFSM2_CONSTEXPR(14) void operator &= (const BitArray& other) noexcept; +#ifdef _MSC_VER + #pragma warning(pop) +#endif -private: - uint8_t _storage[UNIT_COUNT] {}; + bool payloadSet = false; }; template <> -class BitArrayT<0> final { -public: - FFSM2_CONSTEXPR(14) void clear() noexcept {} - - FFSM2_CONSTEXPR(11) bool empty() const noexcept { return true; } +struct TransitionT final + : TransitionBase +{ + using TransitionBase::TransitionBase; }; -} -} +#pragma pack(pop) -#endif +} +struct Request final { + Short index; +}; -#if FFSM2_PLANS_AVAILABLE() +} namespace ffsm2 { -namespace detail { -template -FFSM2_CONSTEXPR(14) -void -BitArrayT::set() noexcept { - for (uint8_t& unit : _storage) - unit = UINT8_MAX; -} +struct FFSM2_EMPTY_BASES EmptyContext {}; -template -FFSM2_CONSTEXPR(14) -void -BitArrayT::clear() noexcept { - for (uint8_t& unit : _storage) - unit = uint8_t{0}; -} +#if FFSM2_LOG_INTERFACE_AVAILABLE() -template -FFSM2_CONSTEXPR(14) -bool -BitArrayT::empty() const noexcept { - for (const uint8_t& unit : _storage) - if (unit != uint8_t{0}) - return false; +template < + FeatureTag NFeatureTag = FFSM2_FEATURE_TAG + , typename TContext = EmptyContext +> +struct LoggerInterfaceT { + using Context = TContext; - return true; -} + using Method = ::ffsm2::Method; + using StateID = ::ffsm2::StateID; -template -template -FFSM2_CONSTEXPR(14) -bool -BitArrayT::get(const TIndex index) const noexcept { - FFSM2_ASSERT(index < CAPACITY); +#if FFSM2_PLANS_AVAILABLE() + using StatusEvent = ::ffsm2::StatusEvent; +#endif - const Index unit = static_cast(index) / 8; - const Index bit = static_cast(index) % 8; - const uint8_t mask = 1 << bit; + FFSM2_CONSTEXPR(NO) + virtual + void + recordMethod(const Context& FFSM2_UNUSED(context), + const StateID FFSM2_UNUSED(origin), + const Method FFSM2_UNUSED(method)) noexcept + {} - return (_storage[unit] & mask) != 0; -} + FFSM2_CONSTEXPR(NO) + virtual + void + recordTransition(const Context& FFSM2_UNUSED(context), + const StateID FFSM2_UNUSED(origin), + const StateID FFSM2_UNUSED(target)) noexcept + {} -template -template -FFSM2_CONSTEXPR(14) -void -BitArrayT::set(const TIndex index) noexcept { - FFSM2_ASSERT(index < CAPACITY); +#if FFSM2_PLANS_AVAILABLE() - const Index unit = static_cast(index) / 8; - const Index bit = static_cast(index) % 8; - const uint8_t mask = 1 << bit; + FFSM2_CONSTEXPR(NO) + virtual + void + recordTaskStatus(const Context& FFSM2_UNUSED(context), + const StateID FFSM2_UNUSED(origin), + const StatusEvent FFSM2_UNUSED(event)) noexcept + {} - _storage[unit] |= mask; -} + FFSM2_CONSTEXPR(NO) + virtual + void + recordPlanStatus(const Context& FFSM2_UNUSED(context), + const StatusEvent FFSM2_UNUSED(event)) noexcept + {} -template -template -FFSM2_CONSTEXPR(14) -void -BitArrayT::clear(const TIndex index) noexcept { - FFSM2_ASSERT(index < CAPACITY); +#endif - const Index unit = static_cast(index) / 8; - const Index bit = static_cast(index) % 8; - const uint8_t mask = 1 << bit; + FFSM2_CONSTEXPR(NO) + virtual + void + recordCancelledPending(const Context& FFSM2_UNUSED(context), + const StateID FFSM2_UNUSED(origin)) noexcept + {} - _storage[unit] &= ~mask; -} +}; -template -FFSM2_CONSTEXPR(14) -bool -BitArrayT::operator & (const BitArray& other) const noexcept { - for (Index i = 0; i < UNIT_COUNT; ++i) - if ((_storage[i] & other._storage[i]) == 0) - return false; +#else - return true; -} +template < + FeatureTag NFeatureTag = FFSM2_FEATURE_TAG + , typename TContext = EmptyContext +> +using LoggerInterfaceT = void; -template -FFSM2_CONSTEXPR(14) -void -BitArrayT::operator &= (const BitArray& other) noexcept { - for (Index i = 0; i < UNIT_COUNT; ++i) - _storage[i] &= other._storage[i]; -} +#endif -} -} +using LoggerInterface = LoggerInterfaceT<>; -#endif +} #if FFSM2_PLANS_AVAILABLE() @@ -1766,6 +1743,16 @@ struct TaskT final #pragma pack(pop) +} +} + +#endif + +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + template class TaskListT { public: @@ -1809,27 +1796,26 @@ class TaskListT {}; } } - #if FFSM2_PLANS_AVAILABLE() namespace ffsm2 { namespace detail { -template +template FFSM2_CONSTEXPR(14) void -TaskListT::clear() noexcept { +TaskListT::clear() noexcept { _vacantHead = 0; _vacantTail = 0; _last = 0; _count = 0; } -template -template +template +template FFSM2_CONSTEXPR(14) Long -TaskListT::emplace(TA&&... args) noexcept { +TaskListT::emplace(TA_&&... args) noexcept { FFSM2_ASSERT(_last <= CAPACITY); if (_count < CAPACITY) { @@ -1867,7 +1853,7 @@ TaskListT::emplace(TA&&... args) noexcept { _vacantTail = INVALID; } - new (&item) Item{forward(args)...}; + new (&item) Item{forward(args)...}; ++_count; FFSM2_IF_ASSERT(verifyStructure()); @@ -1884,10 +1870,10 @@ TaskListT::emplace(TA&&... args) noexcept { } } -template +template FFSM2_CONSTEXPR(14) void -TaskListT::remove(const Index i) noexcept { +TaskListT::remove(const Index i) noexcept { FFSM2_ASSERT(i < CAPACITY && _count); Item& item = _items[i]; @@ -1921,19 +1907,19 @@ TaskListT::remove(const Index i) noexcept { FFSM2_IF_ASSERT(verifyStructure()); } -template +template FFSM2_CONSTEXPR(14) -typename TaskListT::Item& -TaskListT::operator[] (const Index i) noexcept { +typename TaskListT::Item& +TaskListT::operator[] (const Index i) noexcept { FFSM2_IF_ASSERT(verifyStructure()); return _items[i]; } -template +template FFSM2_CONSTEXPR(11) -const typename TaskListT::Item& -TaskListT::operator[] (const Index i) const noexcept { +const typename TaskListT::Item& +TaskListT::operator[] (const Index i) const noexcept { FFSM2_IF_ASSERT(verifyStructure()); return _items[i]; @@ -1941,9 +1927,9 @@ TaskListT::operator[] (const Index i) const noexcept { #if FFSM2_ASSERT_AVAILABLE() -template +template void -TaskListT::verifyStructure(const Index occupied) const noexcept { +TaskListT::verifyStructure(const Index occupied) const noexcept { if (_count < CAPACITY) { FFSM2_ASSERT(_vacantHead < CAPACITY); FFSM2_ASSERT(_vacantTail < CAPACITY); @@ -1987,27 +1973,34 @@ TaskListT::verifyStructure(const Index occupied) const noexcept { } #endif + #endif namespace ffsm2 { namespace detail { -template +template < + typename + , typename + FFSM2_IF_SERIALIZATION(, Long) + FFSM2_IF_PLANS(, Long) + , typename +> struct ArgsT; struct Registry final { - FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return active != INVALID_SHORT; } + FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return active != INVALID_SHORT; } + + FFSM2_CONSTEXPR(14) bool isActive (const StateID stateId) const noexcept { + return stateId == 0 ? + active != INVALID_SHORT : + active == stateId; + } - FFSM2_CONSTEXPR(14) void clearRequests () noexcept { requested = INVALID_SHORT; } - FFSM2_CONSTEXPR(14) void clear () noexcept { requested = INVALID_SHORT; active = INVALID_SHORT; } + FFSM2_CONSTEXPR(14) void clearRequests () noexcept { requested = INVALID_SHORT; } + FFSM2_CONSTEXPR(14) void clear () noexcept { requested = INVALID_SHORT; active = INVALID_SHORT; } - FFSM2_CONSTEXPR(11) bool empty () const noexcept { return requested == INVALID_SHORT && active == INVALID_SHORT; } + FFSM2_CONSTEXPR(11) bool empty () const noexcept { return requested == INVALID_SHORT && active == INVALID_SHORT; } Short requested = INVALID_SHORT; Short active = INVALID_SHORT; @@ -2044,8 +2037,6 @@ FFSM2_CONSTEXPR(14) TaskStatus& operator |= (TaskStatus& l, const TaskStatus r) #if FFSM2_PLANS_AVAILABLE() -#pragma pack(push, 1) - struct TaskLink final { Long prev = INVALID_LONG; Long next = INVALID_LONG; @@ -2058,47 +2049,47 @@ struct Bounds final { FFSM2_CONSTEXPR(14) void clear() noexcept { first = INVALID_LONG; last = INVALID_LONG; } }; -#pragma pack(pop) - -template +template < + typename + , typename + FFSM2_IF_SERIALIZATION(, Long) + , Long + , typename +> struct ArgsT; template struct PlanDataT; -template -struct PlanDataT> final +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + , Long NTaskCapacity + , typename TPayload +> +struct PlanDataT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , TPayload + > + > final { - using StateList = TStateList; - using Payload = TPayload; + using StateList = TStateList; + using Payload = TPayload; - static constexpr Long STATE_COUNT = StateList::SIZE; - static constexpr Short TASK_CAPACITY = NTaskCapacity; + static constexpr Long STATE_COUNT = StateList ::SIZE; + static constexpr Long TASK_CAPACITY = NTaskCapacity; - using Task = TaskT ; - using Tasks = TaskListT ; - using TaskLinks = StaticArrayT; - using Payloads = StaticArrayT; + using Task = TaskT ; + using Tasks = TaskListT ; + using TaskLinks = StaticArrayT; + using Payloads = StaticArrayT; - using TasksBits = BitArrayT; + using TasksBits = BitArrayT < STATE_COUNT>; Tasks tasks; TaskLinks taskLinks; @@ -2124,30 +2115,32 @@ struct PlanDataT -struct PlanDataT> final +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + , Long NTaskCapacity +> +struct PlanDataT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , void + > + > final { - using StateList = TStateList; + using StateList = TStateList; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList ::SIZE; static constexpr Long TASK_CAPACITY = NTaskCapacity; - using Task = TaskT; - using Tasks = TaskListT ; - using TaskLinks = StaticArrayT; + using Task = TaskT ; + using Tasks = TaskListT ; + using TaskLinks = StaticArrayT; - using TasksBits = BitArrayT; + using TasksBits = BitArrayT < STATE_COUNT>; Tasks tasks; TaskLinks taskLinks; @@ -2176,7 +2169,6 @@ struct PlanDataT rhs.result ? - lhs.result : rhs.result; + lhs.result : rhs.result; lhs = TaskStatus{result}; @@ -2222,20 +2214,20 @@ operator |= (TaskStatus& lhs, #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clearTaskStatus(const StateID stateId) noexcept { +PlanDataT>::clearTaskStatus(const StateID stateId) noexcept { if (stateId != INVALID_STATE_ID) { tasksSuccesses.clear(stateId); tasksFailures .clear(stateId); } } -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::verifyEmptyStatus(const StateID FFSM2_IF_ASSERT(stateId)) const noexcept { +PlanDataT>::verifyEmptyStatus(const StateID FFSM2_IF_ASSERT(stateId)) const noexcept { #if FFSM2_ASSERT_AVAILABLE() if (stateId != INVALID_STATE_ID) { @@ -2246,18 +2238,18 @@ PlanDataT>::veri #endif } -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clearRegionStatuses() noexcept { +PlanDataT>::clearRegionStatuses() noexcept { headStatus.clear(); - subStatus .clear(); + subStatus.clear(); } -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clear() noexcept { +PlanDataT>::clear() noexcept { tasks .clear(); taskLinks .clear(); taskPayloads .clear(); @@ -2273,10 +2265,10 @@ PlanDataT>::clea #if FFSM2_ASSERT_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) Long -PlanDataT>::verifyPlan() const noexcept { +PlanDataT>::verifyPlan() const noexcept { Long length = 0; const Bounds& bounds = tasksBounds; @@ -2314,20 +2306,20 @@ PlanDataT>::veri #endif -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clearTaskStatus(const StateID stateId) noexcept { +PlanDataT>::clearTaskStatus(const StateID stateId) noexcept { if (stateId != INVALID_STATE_ID) { tasksSuccesses.clear(stateId); tasksFailures .clear(stateId); } } -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::verifyEmptyStatus(const StateID FFSM2_IF_ASSERT(stateId)) const noexcept { +PlanDataT>::verifyEmptyStatus(const StateID FFSM2_IF_ASSERT(stateId)) const noexcept { #if FFSM2_ASSERT_AVAILABLE() if (stateId != INVALID_STATE_ID) { @@ -2338,18 +2330,18 @@ PlanDataT>::ver #endif } -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clearRegionStatuses() noexcept { +PlanDataT>::clearRegionStatuses() noexcept { headStatus.clear(); subStatus .clear(); } -template +template FFSM2_CONSTEXPR(14) void -PlanDataT>::clear() noexcept { +PlanDataT>::clear() noexcept { tasks .clear(); taskLinks .clear(); @@ -2363,10 +2355,10 @@ PlanDataT>::cle #if FFSM2_ASSERT_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) Long -PlanDataT>::verifyPlan() const noexcept { +PlanDataT>::verifyPlan() const noexcept { Long length = 0; const Bounds& bounds = tasksBounds; @@ -2408,11 +2400,11 @@ PlanDataT>::ver } } +#if FFSM2_PLANS_AVAILABLE() + namespace ffsm2 { namespace detail { -#if FFSM2_PLANS_AVAILABLE() - template class CPlanT { template @@ -2444,50 +2436,154 @@ class CPlanT { using Task = typename PlanData::Task; using TaskLinks = typename PlanData::TaskLinks; - struct IteratorT final { - FFSM2_CONSTEXPR(14) IteratorT(const CPlanT& plan) noexcept; + struct Iterator final { + FFSM2_CONSTEXPR(14) Iterator(const CPlanT& plan) noexcept; + + FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; + + FFSM2_CONSTEXPR(14) void operator ++() noexcept; + + FFSM2_CONSTEXPR(11) const Task& operator *() const noexcept { return _plan._planData.tasks[_curr]; } + FFSM2_CONSTEXPR(11) const Task* operator ->() const noexcept { return &_plan._planData.tasks[_curr]; } + + FFSM2_CONSTEXPR(14) Long next() const noexcept; + + const CPlanT& _plan; + Long _curr; + Long _next; + }; + +private: + FFSM2_CONSTEXPR(11) CPlanT(const PlanData& planData) noexcept + : _planData{planData} + , _bounds{planData.tasksBounds} + {} + + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index(); } + +public: + FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; + + /// @brief Begin iteration over plan tasks + /// @return CIterator to the first task + FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator{*this}; } + + /// @brief Iteration terminator + /// @return Dummy Iterator + FFSM2_CONSTEXPR(14) Iterator end () noexcept { return Iterator{*this}; } + + /// @brief First task + /// @return First task + FFSM2_CONSTEXPR(14) const Task& first() const noexcept; + + /// @brief Last task + /// @return Last task + FFSM2_CONSTEXPR(14) const Task& last() const noexcept; + +private: + const PlanData& _planData; + const Bounds& _bounds; +}; + +} +} + +#endif + +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + +template +FFSM2_CONSTEXPR(14) +CPlanT::Iterator::Iterator(const CPlanT& plan) noexcept + : _plan{plan} + , _curr{plan._bounds.first} +{ + _next = next(); +} + +template +FFSM2_CONSTEXPR(14) +CPlanT::Iterator::operator bool() const noexcept { + FFSM2_ASSERT(_curr < CPlanT::TASK_CAPACITY || + _curr == INVALID_LONG); + + return _curr < CPlanT::TASK_CAPACITY; +} + +template +FFSM2_CONSTEXPR(14) +void +CPlanT::Iterator::operator ++() noexcept { + _curr = _next; + _next = next(); +} + +template +FFSM2_CONSTEXPR(14) +Long +CPlanT::Iterator::next() const noexcept { + if (_curr < CPlanT::TASK_CAPACITY) { + const TaskLink& link = _plan._planData.taskLinks[_curr]; + + return link.next; + } else { + FFSM2_ASSERT(_curr == INVALID_LONG); + + return INVALID_LONG; + } +} - FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; +template +FFSM2_CONSTEXPR(14) +CPlanT::operator bool() const noexcept { + FFSM2_ASSERT(_bounds.first < TASK_CAPACITY && + _bounds.last < TASK_CAPACITY || + _bounds.last == INVALID_LONG); - FFSM2_CONSTEXPR(14) void operator ++() noexcept; + return _bounds.first < TASK_CAPACITY; +} - FFSM2_CONSTEXPR(11) const Task& operator *() const noexcept { return _plan._planData.tasks[_curr]; } - FFSM2_CONSTEXPR(11) const Task* operator ->() const noexcept { return &_plan._planData.tasks[_curr]; } +template +FFSM2_CONSTEXPR(14) +const typename CPlanT::Task& +CPlanT::first() const noexcept { + FFSM2_ASSERT(_bounds.first < TASK_CAPACITY); - FFSM2_CONSTEXPR(14) Long next() const noexcept; + return _planData.tasks[_bounds.first]; +} - const CPlanT& _plan; - Long _curr; - Long _next; - }; +template +FFSM2_CONSTEXPR(14) +const typename CPlanT::Task& +CPlanT::last() const noexcept { + FFSM2_ASSERT(_bounds.last < TASK_CAPACITY); -private: - FFSM2_CONSTEXPR(11) CPlanT(const PlanData& planData) noexcept - : _planData{planData} - , _bounds{planData.tasksBounds} - {} + return _planData.tasks[_bounds.last]; +} - template - static constexpr StateID stateId() noexcept { return index(); } +} +} -public: - FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; +#endif - FFSM2_CONSTEXPR(14) IteratorT first() noexcept { return IteratorT{*this}; } +#if FFSM2_PLANS_AVAILABLE() -private: - const PlanData& _planData; - const Bounds& _bounds; -}; +namespace ffsm2 { +namespace detail { template -class PlanBaseT { +class PlanT { using Args = TArgs; using Context = typename Args::Context; using StateList = typename Args::StateList; - static constexpr Long STATE_COUNT = StateList::SIZE; - static constexpr Long TASK_CAPACITY = Args::TASK_CAPACITY; + static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long TASK_CAPACITY = Args::TASK_CAPACITY; public: using PlanData = PlanDataT; @@ -2497,7 +2593,7 @@ class PlanBaseT { using TaskIndex = typename TaskLinks::Index; struct CIterator final { - FFSM2_CONSTEXPR(14) CIterator(const PlanBaseT& plan) noexcept; + FFSM2_CONSTEXPR(14) CIterator(const PlanT& plan) noexcept; FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; @@ -2508,13 +2604,13 @@ class PlanBaseT { FFSM2_CONSTEXPR(14) Long next() const noexcept; - const PlanBaseT& _plan; + const PlanT& _plan; Long _curr; Long _next; }; - struct IteratorT final { - FFSM2_CONSTEXPR(14) IteratorT(PlanBaseT& plan) noexcept; + struct Iterator final { + FFSM2_CONSTEXPR(14) Iterator(PlanT& plan) noexcept; FFSM2_CONSTEXPR(14) explicit operator bool() const noexcept; @@ -2527,16 +2623,17 @@ class PlanBaseT { FFSM2_CONSTEXPR(14) Long next() const noexcept; - PlanBaseT& _plan; + PlanT& _plan; Long _curr; Long _next; }; protected: - FFSM2_CONSTEXPR(11) PlanBaseT(PlanData& planData) noexcept; + FFSM2_CONSTEXPR(11) PlanT(PlanData& planData) noexcept; - template - static constexpr StateID stateId() noexcept { return index(); } + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index(); } FFSM2_CONSTEXPR(14) bool append(const StateID origin, const StateID destination) noexcept; @@ -2551,245 +2648,83 @@ class PlanBaseT { /// @brief Clear all tasks from the plan FFSM2_CONSTEXPR(14) void clear() noexcept; - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @param origin Origin state identifier - /// @param destination Destination state identifier + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @param `origin` Origin state identifier + /// @param `destination` Destination state identifier /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - FFSM2_CONSTEXPR(14) bool change(const StateID origin, const StateID destination) noexcept { return append(origin , destination) ; } + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + FFSM2_CONSTEXPR(14) bool change(const StateID origin, + const StateID destination) noexcept { return append(origin , destination) ; } - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @tparam TOrigin Origin state type - /// @param destination Destination state identifier + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @tparam `TOrigin` Origin state type + /// @param `destination` Destination state identifier /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary template - FFSM2_CONSTEXPR(14) bool change(const StateID destination) noexcept { return change(stateId(), destination) ; } + FFSM2_CONSTEXPR(14) bool change(const StateID destination) noexcept { return change(stateId(), destination) ; } - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @tparam TOrigin Origin state type - /// @tparam TDestination Destination state type + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @tparam `TOrigin` Origin state type + /// @tparam `TDestination` Destination state type /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary template FFSM2_CONSTEXPR(14) bool change() noexcept { return change(stateId(), stateId()); } /// @brief Begin iteration over plan tasks - /// @return IteratorT to the first task - FFSM2_CONSTEXPR(14) IteratorT first() noexcept { return IteratorT{*this}; } + /// @return Iterator to the first task + FFSM2_CONSTEXPR(14) Iterator begin() noexcept { return Iterator{*this}; } /// @brief Begin iteration over plan tasks /// @return CIterator to the first task - FFSM2_CONSTEXPR(11) CIterator first() const noexcept { return CIterator{*this}; } - -private: - FFSM2_CONSTEXPR(14) void remove(const Long task) noexcept; - -protected: - PlanData& _planData; - Bounds& _bounds; -}; - -template -class PlanT; - -template -class PlanT> final - : public PlanBaseT> -{ - template - friend class R_; - - template - friend class PlanControlT; - - template - friend class FullControlT; - - template - friend class GuardControlT; + FFSM2_CONSTEXPR(11) CIterator begin() const noexcept { return CIterator{*this}; } - using Args = ArgsT; + /// @brief Iteration terminator + /// @return Dummy Iterator + FFSM2_CONSTEXPR(14) Iterator end() noexcept { return Iterator{*this}; } - using Payload = typename Args::Payload; - - using PlanBase = PlanBaseT; - - using PlanBase::PlanBase; - - using PlanBase::linkTask; - - FFSM2_CONSTEXPR(14) bool append(const StateID origin, - const StateID destination, - const Payload& payload) noexcept; + /// @brief Iteration terminator + /// @return Dummy CIterator + FFSM2_CONSTEXPR(11) CIterator end() const noexcept { return CIterator{*this}; } -public: + /// @brief First task + /// @return First task + FFSM2_CONSTEXPR(14) Task& first() noexcept; - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @param origin Origin state identifier - /// @param destination Destination state identifier - /// @param payload Payload - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - FFSM2_CONSTEXPR(14) bool changeWith(const StateID origin, const StateID destination, const Payload& payload) noexcept { return append(origin , destination , payload ); } + /// @brief First task + /// @return First task + FFSM2_CONSTEXPR(14) const Task& first() const noexcept; - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @tparam TOrigin Origin state type - /// @param destination Destination state identifier - /// @param payload Payload - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - template - FFSM2_CONSTEXPR(14) bool changeWith( const StateID destination, const Payload& payload) noexcept { return append(PlanBase::template stateId(), destination , payload ); } + /// @brief Last task + /// @return Last task + FFSM2_CONSTEXPR(14) Task& last() noexcept; - /// @brief Add a task to transition from 'origin' to 'destination' if 'origin' completes with 'success()' - /// @tparam TOrigin Origin state type - /// @tparam TDestination Destination state type - /// @param payload Payload - /// @return Seccess if FSM total number of tasks is below task capacity - /// @note use 'Config::TaskCapacityN<>' to increase task capacity if necessary - template - FFSM2_CONSTEXPR(14) bool changeWith( const Payload& payload) noexcept { return append(PlanBase::template stateId(), PlanBase::template stateId(), payload ); } + /// @brief Last task + /// @return Last task + FFSM2_CONSTEXPR(14) const Task& last() const noexcept; private: - using PlanBase::_planData; -}; - -template -class PlanT> final - : public PlanBaseT> -{ - template - friend class R_; - - template - friend class PlanControlT; - - template - friend class FullControlT; - - template - friend class GuardControlT; - - using Args = ArgsT; - - using PlanBase = PlanBaseT; + FFSM2_CONSTEXPR(14) void remove(const Long task) noexcept; - using PlanBase::PlanBase; +protected: + PlanData& _planData; + Bounds& _bounds; }; -#endif - } } - -namespace ffsm2 { -namespace detail { +#endif #if FFSM2_PLANS_AVAILABLE() -template -FFSM2_CONSTEXPR(14) -CPlanT::IteratorT::IteratorT(const CPlanT& plan) noexcept - : _plan{plan} - , _curr{plan._bounds.first} -{ - _next = next(); -} - -template -FFSM2_CONSTEXPR(14) -CPlanT::IteratorT::operator bool() const noexcept { - FFSM2_ASSERT(_curr < CPlanT::TASK_CAPACITY || - _curr == INVALID_LONG); - - return _curr < CPlanT::TASK_CAPACITY; -} - -template -FFSM2_CONSTEXPR(14) -void -CPlanT::IteratorT::operator ++() noexcept { - _curr = _next; - _next = next(); -} - -template -FFSM2_CONSTEXPR(14) -Long -CPlanT::IteratorT::next() const noexcept { - if (_curr < CPlanT::TASK_CAPACITY) { - const TaskLink& link = _plan._planData.taskLinks[_curr]; - - return link.next; - } else { - FFSM2_ASSERT(_curr == INVALID_LONG); - - return INVALID_LONG; - } -} - -template -FFSM2_CONSTEXPR(14) -CPlanT::operator bool() const noexcept { - FFSM2_ASSERT(_bounds.first < TASK_CAPACITY && - _bounds.last < TASK_CAPACITY || - _bounds.last == INVALID_LONG); - - return _bounds.first < TASK_CAPACITY; -} +namespace ffsm2 { +namespace detail { template FFSM2_CONSTEXPR(14) -PlanBaseT::CIterator::CIterator(const PlanBaseT& plan) noexcept +PlanT::CIterator::CIterator(const PlanT& plan) noexcept : _plan{plan} , _curr{plan._bounds.first} , _next{next()} @@ -2797,17 +2732,17 @@ PlanBaseT::CIterator::CIterator(const PlanBaseT& plan) noexcept template FFSM2_CONSTEXPR(14) -PlanBaseT::CIterator::operator bool() const noexcept { - FFSM2_ASSERT(_curr < PlanBaseT::TASK_CAPACITY || +PlanT::CIterator::operator bool() const noexcept { + FFSM2_ASSERT(_curr < PlanT::TASK_CAPACITY || _curr == INVALID_LONG); - return _curr < PlanBaseT::TASK_CAPACITY; + return _curr < PlanT::TASK_CAPACITY; } template FFSM2_CONSTEXPR(14) void -PlanBaseT::CIterator::operator ++() noexcept { +PlanT::CIterator::operator ++() noexcept { _curr = _next; _next = next(); } @@ -2815,8 +2750,8 @@ PlanBaseT::CIterator::operator ++() noexcept { template FFSM2_CONSTEXPR(14) Long -PlanBaseT::CIterator::next() const noexcept { - if (_curr < PlanBaseT::TASK_CAPACITY) { +PlanT::CIterator::next() const noexcept { + if (_curr < PlanT::TASK_CAPACITY) { const TaskLink& link = _plan._planData.taskLinks[_curr]; return link.next; @@ -2829,7 +2764,7 @@ PlanBaseT::CIterator::next() const noexcept { template FFSM2_CONSTEXPR(14) -PlanBaseT::IteratorT::IteratorT(PlanBaseT& plan) noexcept +PlanT::Iterator::Iterator(PlanT& plan) noexcept : _plan{plan} , _curr{plan._bounds.first} , _next{next()} @@ -2837,17 +2772,17 @@ PlanBaseT::IteratorT::IteratorT(PlanBaseT& plan) noexcept template FFSM2_CONSTEXPR(14) -PlanBaseT::IteratorT::operator bool() const noexcept { - FFSM2_ASSERT(_curr < PlanBaseT::TASK_CAPACITY || +PlanT::Iterator::operator bool() const noexcept { + FFSM2_ASSERT(_curr < PlanT::TASK_CAPACITY || _curr == INVALID_LONG); - return _curr < PlanBaseT::TASK_CAPACITY; + return _curr < PlanT::TASK_CAPACITY; } template FFSM2_CONSTEXPR(14) void -PlanBaseT::IteratorT::operator ++() noexcept { +PlanT::Iterator::operator ++() noexcept { _curr = _next; _next = next(); } @@ -2855,8 +2790,8 @@ PlanBaseT::IteratorT::operator ++() noexcept { template FFSM2_CONSTEXPR(14) Long -PlanBaseT::IteratorT::next() const noexcept { - if (_curr < PlanBaseT::TASK_CAPACITY) { +PlanT::Iterator::next() const noexcept { + if (_curr < PlanT::TASK_CAPACITY) { const TaskLink& link = _plan._planData.taskLinks[_curr]; return link.next; @@ -2869,7 +2804,7 @@ PlanBaseT::IteratorT::next() const noexcept { template FFSM2_CONSTEXPR(11) -PlanBaseT::PlanBaseT(PlanData& planData) noexcept +PlanT::PlanT(PlanData& planData) noexcept : _planData{planData} , _bounds{planData.tasksBounds} {} @@ -2877,8 +2812,8 @@ PlanBaseT::PlanBaseT(PlanData& planData) noexcept template FFSM2_CONSTEXPR(14) bool -PlanBaseT::append(const StateID origin, - const StateID destination) noexcept +PlanT::append(const StateID origin, + const StateID destination) noexcept { if (_planData.tasks.count() < TASK_CAPACITY) { _planData.planExists = true; @@ -2891,7 +2826,7 @@ PlanBaseT::append(const StateID origin, template FFSM2_CONSTEXPR(14) bool -PlanBaseT::linkTask(const Long index) noexcept { +PlanT::linkTask(const Long index) noexcept { if (index != Tasks::INVALID) { if (_bounds.first == INVALID_LONG) { FFSM2_ASSERT(_bounds.last == INVALID_LONG); @@ -2925,7 +2860,7 @@ PlanBaseT::linkTask(const Long index) noexcept { template FFSM2_CONSTEXPR(14) void -PlanBaseT::clearTasks() noexcept { +PlanT::clearTasks() noexcept { if (_bounds.first < TaskLinks::CAPACITY) { FFSM2_ASSERT(_bounds.last < TaskLinks::CAPACITY); @@ -2955,82 +2890,253 @@ PlanBaseT::clearTasks() noexcept { } } -template -FFSM2_CONSTEXPR(14) -PlanBaseT::operator bool() const noexcept { - FFSM2_ASSERT(_bounds.first < TASK_CAPACITY && - _bounds.last < TASK_CAPACITY || - _bounds.last == INVALID_LONG); +template +FFSM2_CONSTEXPR(14) +PlanT::operator bool() const noexcept { + FFSM2_ASSERT(_bounds.first < TASK_CAPACITY && + _bounds.last < TASK_CAPACITY || + _bounds.last == INVALID_LONG); + + return _bounds.first < TASK_CAPACITY; +} + +template +FFSM2_CONSTEXPR(14) +void +PlanT::clear() noexcept { + clearTasks(); + + for (StateID i = 0; + i < STATE_COUNT; + ++i) + { + _planData.tasksSuccesses.clear(i); + _planData.tasksFailures .clear(i); + } +} + +template +FFSM2_CONSTEXPR(14) +void +PlanT::remove(const Long index) noexcept { + FFSM2_ASSERT(_planData.planExists); + FFSM2_ASSERT(_bounds.first < TaskLinks::CAPACITY); + FFSM2_ASSERT(_bounds.last < TaskLinks::CAPACITY); + + FFSM2_ASSERT(index < TaskLinks::CAPACITY); + + TaskLink& link = _planData.taskLinks[index]; + + if (link.prev < TaskLinks::CAPACITY) { + TaskLink& prev = _planData.taskLinks[link.prev]; + prev.next = link.next; + } else { + FFSM2_ASSERT(_bounds.first == index); + _bounds.first = link.next; + } + + if (link.next < TaskLinks::CAPACITY) { + TaskLink& next = _planData.taskLinks[link.next]; + next.prev = link.prev; + } else { + FFSM2_ASSERT(_bounds.last == index); + _bounds.last = link.prev; + } + + link.prev = INVALID_LONG; + link.next = INVALID_LONG; + + _planData.tasks.remove(index); +} + +} +} + +#endif + +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { + +template +class PayloadPlanT; + +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + , Long NTaskCapacity + , typename TPayload +> +class PayloadPlanT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , TPayload + > + > final + : public PlanT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , TPayload + > + > +{ + template + friend class R_; + + template + friend class PlanControlT; + + template + friend class FullControlT; + + template + friend class GuardControlT; + + using Args = ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , TPayload + >; + + using Payload = typename Args::Payload; + + static constexpr Long TASK_CAPACITY = Args::TASK_CAPACITY; + + using PlanBase = PlanT; + + using PlanBase::PlanBase; + + using PlanBase::linkTask; + + FFSM2_CONSTEXPR(14) bool append(const StateID origin, + const StateID destination, + const Payload& payload) noexcept; + +public: + + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @param `origin` Origin state identifier + /// @param `destination` Destination state identifier + /// @param `payload` Payload + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + FFSM2_CONSTEXPR(14) bool changeWith (const StateID origin, + const StateID destination, + const Payload& payload) noexcept { return append(origin , destination , payload ); } + + /// @brief Append a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @tparam `TOrigin` Origin state type + /// @param `destination` Destination state identifier + /// @param `payload` Payload + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + template + FFSM2_CONSTEXPR(14) bool changeWith (const StateID destination, + const Payload& payload) noexcept { return append(PlanBase::template stateId(), destination , payload ); } + + /// @brief Prepend a task to transition from `origin` to `destination` if `origin` completes with `success()` + /// @tparam `TOrigin` Origin state type + /// @tparam `TDestination` Destination state type + /// @param `payload` Payload + /// @return Seccess if FSM total number of tasks is below task capacity + /// @note use `Config::TaskCapacityN<>` to increase task capacity if necessary + template + FFSM2_CONSTEXPR(14) bool changeWith (const Payload& payload) noexcept { return append(PlanBase::template stateId(), PlanBase::template stateId(), payload ); } - return _bounds.first < TASK_CAPACITY; -} +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif -template -FFSM2_CONSTEXPR(14) -void -PlanBaseT::clear() noexcept { - clearTasks(); +private: + using PlanBase::_planData; +}; - for (Short i = 0; - i < STATE_COUNT; - ++i) - { - _planData.tasksSuccesses.clear(i); - _planData.tasksFailures .clear(i); - } -} +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + , Long NTaskCapacity +> +class PayloadPlanT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , void + > + > final + : public PlanT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , void + > + > +{ + template + friend class R_; -template -FFSM2_CONSTEXPR(14) -void -PlanBaseT::remove(const Long index) noexcept { - FFSM2_ASSERT(_planData.planExists); - FFSM2_ASSERT(_bounds.first < TaskLinks::CAPACITY); - FFSM2_ASSERT(_bounds.last < TaskLinks::CAPACITY); + template + friend class PlanControlT; - FFSM2_ASSERT(index < TaskLinks::CAPACITY); + template + friend class FullControlT; - TaskLink& link = _planData.taskLinks[index]; + template + friend class GuardControlT; - if (link.prev < TaskLinks::CAPACITY) { - TaskLink& prev = _planData.taskLinks[link.prev]; - prev.next = link.next; - } else { - FFSM2_ASSERT(_bounds.first == index); - _bounds.first = link.next; - } + using Args = ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + , NTaskCapacity + , void + >; - if (link.next < TaskLinks::CAPACITY) { - TaskLink& next = _planData.taskLinks[link.next]; - next.prev = link.prev; - } else { - FFSM2_ASSERT(_bounds.last == index); - _bounds.last = link.prev; - } + using PlanBase = PlanT; - link.prev = INVALID_LONG; - link.next = INVALID_LONG; + using PlanBase::PlanBase; +}; - _planData.tasks.remove(index); } +} + +#endif + +#if FFSM2_PLANS_AVAILABLE() + +namespace ffsm2 { +namespace detail { -template +template FFSM2_CONSTEXPR(14) bool -PlanT>::append(const StateID origin, - const StateID destination, - const Payload& payload) noexcept +PayloadPlanT>::append(const StateID origin, + const StateID destination, + const Payload& payload) noexcept { _planData.planExists = true; return linkTask(_planData.tasks.emplace(origin, destination, payload)); } -#endif - } } +#endif + namespace ffsm2 { namespace detail { @@ -3065,15 +3171,14 @@ struct CoreT { Context context; Registry registry; - FFSM2_IF_PLANS(PlanData planData); Transition request; + FFSM2_IF_PLANS(PlanData planData); FFSM2_IF_LOG_INTERFACE(Logger* logger); }; } } - namespace ffsm2 { namespace detail { @@ -3098,13 +3203,9 @@ FFSM2_CONSTEXPR(11) CoreT::CoreT(const CoreT& other) noexcept : context {other.context } , registry{other.registry} -#if FFSM2_PLANS_AVAILABLE() - , planData{other.planData} -#endif , request {other.request } -#if FFSM2_LOG_INTERFACE_AVAILABLE() - , logger {other.logger } -#endif + FFSM2_IF_PLANS (, planData {other.planData }) + FFSM2_IF_LOG_INTERFACE (, logger {other.logger }) {} template @@ -3112,13 +3213,9 @@ FFSM2_CONSTEXPR(11) CoreT::CoreT(CoreT&& other) noexcept : context {move(other.context )} , registry{move(other.registry)} -#if FFSM2_PLANS_AVAILABLE() - , planData{move(other.planData)} -#endif , request {move(other.request )} -#if FFSM2_LOG_INTERFACE_AVAILABLE() - , logger {move(other.logger )} -#endif + FFSM2_IF_PLANS (, planData {move(other.planData )}) + FFSM2_IF_LOG_INTERFACE (, logger {move(other.logger )}) {} } @@ -3181,10 +3278,11 @@ class ConstControlT { FFSM2_CONSTEXPR(11) StateID stateId() const noexcept { return _originId; } /// @brief Get state identifier for a state type - /// @tparam TState State type + /// @tparam `TState` State type /// @return Numeric state identifier template - static constexpr StateID stateId() noexcept { return index(); } + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index(); } /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) /// @return context @@ -3201,12 +3299,12 @@ class ConstControlT { FFSM2_CONSTEXPR(11) const Transition& request() const noexcept { return _core.request; } /// @brief Check if a state is active - /// @param stateId State identifier + /// @param `stateId` State identifier /// @return State active status FFSM2_CONSTEXPR(11) bool isActive (const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } /// @brief Check if a state is active - /// @tparam TState State type + /// @tparam `TState` State type /// @return State active status template FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return isActive(stateId()); } @@ -3215,14 +3313,16 @@ class ConstControlT { /// @brief Access read-only plan /// @return Plan + /// @see `FFSM2_ENABLE_PLANS` FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } #endif #if FFSM2_TRANSITION_HISTORY_AVAILABLE() - /// @brief Get transitions processed during last 'update()', 'react()' or 'replayTransition()' + /// @brief Get transitions processed during last `update()`, `react()` or `replayTransition()` /// @return Array of last transition requests + /// @see `FFSM2_ENABLE_TRANSITION_HISTORY` FFSM2_CONSTEXPR(11) const Transition& previousTransitions() const noexcept { return _core.previousTransition; } #endif @@ -3232,6 +3332,37 @@ class ConstControlT { StateID _originId = INVALID_STATE_ID; }; +} +} + +namespace ffsm2 { +namespace detail { + +template +FFSM2_CONSTEXPR(14) +ConstControlT::Origin::Origin(ConstControlT& control_, + const StateID stateId_) noexcept + : control{control_} + , prevId{control._originId} +{ + FFSM2_ASSERT(stateId_ < StateList::SIZE || + stateId_ == INVALID_STATE_ID); // specific + + control._originId = stateId_; +} + +template +FFSM2_CONSTEXPR(20) +ConstControlT::Origin::~Origin() noexcept { + control._originId = prevId; +} + +} +} + +namespace ffsm2 { +namespace detail { + template class ControlT { template @@ -3262,16 +3393,16 @@ class ControlT { #endif struct Origin final { - FFSM2_CONSTEXPR(14) Origin(ControlT& control_, - const StateID stateId_) noexcept; + FFSM2_CONSTEXPR(14) Origin(ControlT& control_, + const StateID stateId_) noexcept; - FFSM2_CONSTEXPR(20) ~Origin() noexcept; + FFSM2_CONSTEXPR(20) ~Origin() noexcept; ControlT& control; const StateID prevId; }; - FFSM2_CONSTEXPR(11) ControlT(Core& core) noexcept + FFSM2_CONSTEXPR(11) ControlT(Core& core) noexcept : _core{core} {} @@ -3283,62 +3414,65 @@ class ControlT { /// @brief Get current state's identifier /// @return Numeric state identifier - constexpr StateID stateId() const noexcept { return _originId; } + FFSM2_CONSTEXPR(11) StateID stateId() const noexcept { return _originId; } /// @brief Get state identifier for a state type - /// @tparam TState State type + /// @tparam `TState` State type /// @return Numeric state identifier template - static constexpr StateID stateId() noexcept { return index(); } + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index(); } /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) /// @return context - /// @see Control::context() - FFSM2_CONSTEXPR(14) Context& _() noexcept { return _core.context; } + /// @see `Control::context()` + FFSM2_CONSTEXPR(14) Context& _() noexcept { return _core.context; } /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) /// @return context - /// @see Control::context() - FFSM2_CONSTEXPR(11) const Context& _() const noexcept { return _core.context; } + /// @see `Control::context()` + FFSM2_CONSTEXPR(11) const Context& _() const noexcept { return _core.context; } /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) /// @return context - /// @see Control::_() - FFSM2_CONSTEXPR(14) Context& context() noexcept { return _core.context; } + /// @see `Control::_()` + FFSM2_CONSTEXPR(14) Context& context() noexcept { return _core.context; } /// @brief Access FSM context (data shared between states and/or data interface between FSM and external code) /// @return context - /// @see Control::_() - FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } + /// @see `Control::_()` + FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } /// @brief Inspect current transition request /// @return Transition requests - FFSM2_CONSTEXPR(11) const Transition& request() const noexcept { return _core.request; } + FFSM2_CONSTEXPR(11) const Transition& request() const noexcept { return _core.request; } /// @brief Check if a state is active - /// @param stateId State identifier + /// @param `stateId` State identifier /// @return State active status - FFSM2_CONSTEXPR(11) bool isActive (const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } + FFSM2_CONSTEXPR(11) bool isActive (const StateID stateId_) const noexcept { return _core.registry.isActive(stateId_); } /// @brief Check if a state is active - /// @tparam TState State type + /// @tparam `TState` State type /// @return State active status template - FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return isActive(stateId()); } + FFSM2_CONSTEXPR(11) bool isActive () const noexcept { return isActive(stateId()); } #if FFSM2_PLANS_AVAILABLE() /// @brief Access read-only plan /// @return Plan - FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } #endif #if FFSM2_TRANSITION_HISTORY_AVAILABLE() - /// @brief Get transitions processed during last 'update()', 'react()' or 'replayTransition()' + /// @brief Get transitions processed during last `update()`, `react()` or `replayTransition()` /// @return Array of last transition requests - FFSM2_CONSTEXPR(11) const Transition& previousTransitions() const noexcept { return _core.previousTransition; } + /// @see `FFSM2_ENABLE_TRANSITION_HISTORY` + FFSM2_CONSTEXPR(11) const Transition& previousTransitions() const noexcept { return _core.previousTransition; } #endif @@ -3347,6 +3481,37 @@ class ControlT { StateID _originId = INVALID_STATE_ID; }; +} +} + +namespace ffsm2 { +namespace detail { + +template +FFSM2_CONSTEXPR(14) +ControlT::Origin::Origin(ControlT& control_, + const StateID stateId_) noexcept + : control{control_} + , prevId{control._originId} +{ + FFSM2_ASSERT(stateId_ < StateList::SIZE || + stateId_ == INVALID_STATE_ID); // specific + + control._originId = stateId_; +} + +template +FFSM2_CONSTEXPR(20) +ControlT::Origin::~Origin() noexcept { + control._originId = prevId; +} + +} +} + +namespace ffsm2 { +namespace detail { + template class PlanControlT : public ControlT @@ -3364,12 +3529,13 @@ class PlanControlT friend class RV_; protected: - using Control = ControlT; + using Control = ControlT; using typename Control::StateList; + using typename Control::Core; - using Transition = typename Core::Transition; + using Transition = typename Core::Transition; #if FFSM2_PLANS_AVAILABLE() using typename Control::PlanData; @@ -3393,19 +3559,20 @@ class PlanControlT FFSM2_CONSTEXPR(14) void resetRegion() noexcept; public: - using Control::isActive; #if FFSM2_PLANS_AVAILABLE() using typename Control::CPlan; - using Plan = PlanT; + using Plan = PayloadPlanT; /// @brief Access plan /// @return Plan - FFSM2_CONSTEXPR(14) Plan plan() noexcept { return Plan{_core.planData}; } + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) Plan plan() noexcept { return Plan{_core.planData}; } /// @brief Access read-only plan /// @return Read-only plan + /// @see `FFSM2_ENABLE_PLANS` FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } #endif @@ -3418,9 +3585,51 @@ class PlanControlT using Control::_core; const Transition& _currentTransition; + TaskStatus _taskStatus; }; +} +} + +namespace ffsm2 { +namespace detail { + +template +FFSM2_CONSTEXPR(14) +PlanControlT::Region::Region(PlanControlT& control_) noexcept + : control {control_} +{ + control.setRegion(); +} + +template +FFSM2_CONSTEXPR(20) +PlanControlT::Region::~Region() noexcept { + control.resetRegion(); +} + +template +FFSM2_CONSTEXPR(14) +void +PlanControlT::setRegion() noexcept +{ +} + +template +FFSM2_CONSTEXPR(14) +void +PlanControlT::resetRegion() noexcept +{ + _taskStatus.clear(); +} + +} +} + +namespace ffsm2 { +namespace detail { + template class FullControlBaseT : public PlanControlT @@ -3456,14 +3665,12 @@ class FullControlBaseT public: using PlanControl::context; - using PlanControl::isActive; - /// @brief Transition into a state - /// @param stateId State identifier + /// @param `stateId` State identifier FFSM2_CONSTEXPR(14) void changeTo(const StateID stateId_) noexcept; /// @brief Transition into a state - /// @tparam TState State type + /// @tparam `TState` State type template FFSM2_CONSTEXPR(14) void changeTo() noexcept { changeTo (PlanControl::template stateId()); } @@ -3473,35 +3680,41 @@ class FullControlBaseT #if FFSM2_PLANS_AVAILABLE() /// @brief Succeed a plan task for the current state - FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed (_originId ); } + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed (_originId ); } /// @brief Succeed a plan task for a state - /// @param stateId State ID - FFSM2_CONSTEXPR(14) void succeed(const StateID stateId_) noexcept; + /// @param `stateId` State identifier + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void succeed(const StateID stateId_) noexcept; /// @brief Succeed a plan task for a state - /// @tparam TState State type + /// @tparam `TState` State type + /// @see `FFSM2_ENABLE_PLANS` template - FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed (PlanControl::template stateId()); } + FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed (PlanControl::template stateId()); } /// @brief Fail a plan task for the current state - FFSM2_CONSTEXPR(14) void fail () noexcept { fail (_originId ); } + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void fail () noexcept { fail (_originId ); } /// @brief Fail a plan task for a state /// @param stateId State ID - FFSM2_CONSTEXPR(14) void fail (const StateID stateId_) noexcept; + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void fail (const StateID stateId_) noexcept; /// @brief Fail a plan task for a state - /// @tparam TState State type + /// @tparam `TState` State type + /// @see `FFSM2_ENABLE_PLANS` template - FFSM2_CONSTEXPR(14) void fail () noexcept { fail (PlanControl::template stateId()); } + FFSM2_CONSTEXPR(14) void fail () noexcept { fail (PlanControl::template stateId()); } #endif protected: using PlanControl::_core; - using PlanControl::_originId; + using PlanControl::_taskStatus; bool _locked = false; @@ -3510,27 +3723,31 @@ class FullControlBaseT template class FullControlT; -template -class FullControlT> - : public FullControlBaseT> +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload +> +class FullControlT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + > + : public FullControlBaseT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + > { template friend struct S_; @@ -3541,13 +3758,13 @@ class FullControlT friend class R_; - using Args = ArgsT; + using Args = ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + >; protected: using FullControlBase = FullControlBaseT; @@ -3581,14 +3798,14 @@ class FullControlT FFSM2_CONSTEXPR(14) void changeWith(const Payload& payload) noexcept { changeWith(FullControlBase::template stateId(), payload ); } @@ -3597,85 +3814,37 @@ class FullControlT -class FullControlT> - : public FullControlBaseT> -{ - template - friend struct S_; - - template - friend struct C_; - - template - friend class R_; - - using Args = ArgsT; - -protected: - using FullControlBase = FullControlBaseT; - - using typename FullControlBase::Origin; - -#if FFSM2_PLANS_AVAILABLE() - using typename FullControlBase::Plan; - using typename FullControlBase::TasksBits; -#endif - - using FullControlBase::FullControlBase; - -#if FFSM2_PLANS_AVAILABLE() - - template - FFSM2_CONSTEXPR(14) void updatePlan(TState& headState, - const TaskStatus subStatus) noexcept; - -#endif - -public: - using FullControlBase::isActive; - using FullControlBase::changeTo; - - FFSM2_IF_PLANS(using FullControlBase::plan); - -protected: - FFSM2_IF_PLANS(using FullControlBase::_core); using FullControlBase::_taskStatus; -}; -template -class GuardControlT final - : public FullControlT + using FullControlBase::_locked; +}; + +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + FFSM2_IF_PLANS(, Long NTaskCapacity) +> +class FullControlT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + > + : public FullControlBaseT< + ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + > { template friend struct S_; @@ -3686,117 +3855,52 @@ class GuardControlT final template friend class R_; - using FullControl = FullControlT; + using Args = ArgsT< + TConfig + , TStateList + FFSM2_IF_SERIALIZATION(, NSerialBits) + FFSM2_IF_PLANS(, NTaskCapacity) + , void + >; - using typename FullControl::Context; - using typename FullControl::Core; +protected: + using FullControlBase = FullControlBaseT; - using typename FullControl::Transition; + using typename FullControlBase::Origin; #if FFSM2_PLANS_AVAILABLE() - using typename FullControl::PlanData; + using typename FullControlBase::Plan; + using typename FullControlBase::TasksBits; #endif -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename FullControl::Logger; -#endif + using FullControlBase::FullControlBase; - FFSM2_CONSTEXPR(11) GuardControlT(Core& core, - const Transition& currentTransition, - const Transition& pendingTransition) noexcept - : FullControl{core, currentTransition} - , _pendingTransition{pendingTransition} - {} +#if FFSM2_PLANS_AVAILABLE() -public: - using FullControl::context; + template + FFSM2_CONSTEXPR(14) void updatePlan(TState& headState, + const TaskStatus subStatus) noexcept; - /// @brief Get pending transition request - /// @return Pending transition request - FFSM2_CONSTEXPR(11) const Transition& pendingTransition() const noexcept { return _pendingTransition; } +#endif - /// @brief Cancel pending transition request - /// (can be used to substitute a transition into the current state with a different one) - FFSM2_CONSTEXPR(14) void cancelPendingTransition() noexcept; +public: + using FullControlBase::isActive; + using FullControlBase::changeTo; -private: - using FullControl::_core; - using FullControl::_originId; + FFSM2_IF_PLANS(using FullControlBase::plan); - const Transition& _pendingTransition; - bool _cancelled = false; +protected: + FFSM2_IF_PLANS(using FullControlBase::_core); + + using FullControlBase::_taskStatus; }; } } - namespace ffsm2 { namespace detail { -template -FFSM2_CONSTEXPR(14) -ConstControlT::Origin::Origin(ConstControlT& control_, - const StateID stateId_) noexcept - : control{control_} - , prevId{control._originId} -{ - FFSM2_ASSERT(stateId_ < StateList::SIZE || stateId_ == INVALID_STATE_ID); - control._originId = stateId_; -} - -template -FFSM2_CONSTEXPR(20) -ConstControlT::Origin::~Origin() noexcept { - control._originId = prevId; -} - -template -FFSM2_CONSTEXPR(14) -ControlT::Origin::Origin(ControlT& control_, - const StateID stateId_) noexcept - : control{control_} - , prevId{control._originId} -{ - FFSM2_ASSERT(stateId_ < StateList::SIZE || stateId_ == INVALID_STATE_ID); - control._originId = stateId_; -} - -template -FFSM2_CONSTEXPR(20) -ControlT::Origin::~Origin() noexcept { - control._originId = prevId; -} - -template -FFSM2_CONSTEXPR(14) -PlanControlT::Region::Region(PlanControlT& control_) noexcept - : control {control_} -{ - control.setRegion(); -} - -template -FFSM2_CONSTEXPR(20) -PlanControlT::Region::~Region() noexcept { - control.resetRegion(); -} - -template -FFSM2_CONSTEXPR(14) -void -PlanControlT::setRegion() noexcept -{ -} - -template -FFSM2_CONSTEXPR(14) -void -PlanControlT::resetRegion() noexcept -{ - _taskStatus.clear(); -} - template FFSM2_CONSTEXPR(14) FullControlBaseT::Lock::Lock(FullControlBaseT& control_) noexcept @@ -3852,12 +3956,12 @@ FullControlBaseT::fail(const StateID stateId_) noexcept { #if FFSM2_PLANS_AVAILABLE() -template +template template FFSM2_CONSTEXPR(14) void -FullControlT>::updatePlan(TState& headState, - const TaskStatus subStatus) noexcept +FullControlT>::updatePlan(TState& headState, + const TaskStatus subStatus) noexcept { FFSM2_ASSERT(subStatus); @@ -3871,7 +3975,7 @@ FullControlT>::u TasksBits successesToClear; successesToClear.set(); - for (auto it = p.first(); + for (auto it = p.begin(); it && isActive(it->origin); ++it) { @@ -3904,11 +4008,11 @@ FullControlT>::u #endif -template +template FFSM2_CONSTEXPR(14) void -FullControlT>::changeWith(const StateID stateId_, - const Payload& payload) noexcept +FullControlT>::changeWith(const StateID stateId_, + const Payload& payload) noexcept { if (!_locked) { _core.request = Transition{_originId, stateId_, payload}; @@ -3919,12 +4023,12 @@ FullControlT +template template FFSM2_CONSTEXPR(14) void -FullControlT>::updatePlan(TState& headState, - const TaskStatus subStatus) noexcept +FullControlT>::updatePlan(TState& headState, + const TaskStatus subStatus) noexcept { FFSM2_ASSERT(subStatus); @@ -3938,7 +4042,7 @@ FullControlT>:: TasksBits successesToClear; successesToClear.set(); - for (auto it = p.first(); + for (auto it = p.begin(); it && isActive(it->origin); ++it) { @@ -3968,6 +4072,73 @@ FullControlT>:: #endif +} +} + +namespace ffsm2 { +namespace detail { + +template +class GuardControlT final + : public FullControlT +{ + template + friend struct S_; + + template + friend struct C_; + + template + friend class R_; + + using FullControl = FullControlT; + + using typename FullControl::Core; + using typename FullControl::Context; + + using typename FullControl::Transition; + +#if FFSM2_PLANS_AVAILABLE() + using typename FullControl::PlanData; +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename FullControl::Logger; +#endif + + FFSM2_CONSTEXPR(11) GuardControlT(Core& core, + const Transition& currentTransition, + const Transition& pendingTransition) noexcept + : FullControl{core, currentTransition} + , _pendingTransition{pendingTransition} + {} + +public: + using FullControl::context; + + /// @brief Get pending transition request + /// @return Pending transition request + FFSM2_CONSTEXPR(11) const Transition& pendingTransition() const noexcept { return _pendingTransition; } + + /// @brief Cancel pending transition request + /// (can be used to substitute a transition into the current state with a different one) + FFSM2_CONSTEXPR(14) void cancelPendingTransition() noexcept; + +private: + using FullControl::_core; + using FullControl::_originId; + + const Transition& _pendingTransition; + + bool _cancelled = false; +}; + +} +} + +namespace ffsm2 { +namespace detail { + template FFSM2_CONSTEXPR(14) void @@ -3998,7 +4169,7 @@ class B_ { using PlanControl = PlanControlT ; #if FFSM2_PLANS_AVAILABLE() - using Plan = PlanT; + using Plan = PayloadPlanT ; #endif using FullControl = FullControlT ; @@ -4035,34 +4206,47 @@ class B_ { FFSM2_CONSTEXPR(14) void exit ( PlanControl& ) noexcept {} - template - static constexpr StateID stateId() noexcept { return index(); } + template + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index() ; } }; +} +} + +namespace ffsm2 { +namespace detail { + template struct A_; +template +using EmptyT = A_>; + template struct FFSM2_EMPTY_BASES A_ : TFirst , A_ { - using typename TFirst::Context; + using First = TFirst; + using typename First::Context; - using typename TFirst::StateList; + using typename First::StateList; - using typename TFirst::ConstControl; - using typename TFirst::Control; - using typename TFirst::PlanControl; + using typename First::ConstControl; + using typename First::Control; + using typename First::PlanControl; #if FFSM2_PLANS_AVAILABLE() - using typename TFirst::Plan; + using typename First::Plan; #endif - using typename TFirst::FullControl; - using typename TFirst::GuardControl; + using typename First::FullControl; + using typename First::GuardControl; + + using First::stateId; - using TFirst::stateId; + using Rest = A_; FFSM2_CONSTEXPR(14) void wideEntryGuard(GuardControl& control) noexcept; @@ -4095,26 +4279,147 @@ struct FFSM2_EMPTY_BASES A_ }; +} +} + +namespace ffsm2 { +namespace detail { + +template +FFSM2_CONSTEXPR(14) +void +A_::wideEntryGuard(GuardControl& control) noexcept { + First:: entryGuard(control); + Rest ::wideEntryGuard(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::wideEnter(PlanControl& control) noexcept { + First:: enter(control); + Rest ::wideEnter(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::wideReenter(PlanControl& control) noexcept { + First:: reenter(control); + Rest ::wideReenter(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::widePreUpdate(FullControl& control) noexcept { + First:: preUpdate(control); + Rest ::widePreUpdate(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::wideUpdate(FullControl& control) noexcept { + First:: update(control); + Rest ::wideUpdate(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::widePostUpdate(FullControl& control) noexcept { + Rest ::widePostUpdate(control); + First:: postUpdate(control); +} + +template +template +FFSM2_CONSTEXPR(14) +void +A_::widePreReact(const TEvent& event, + FullControl& control) noexcept +{ + First:: preReact(event, control); + Rest ::widePreReact(event, control); +} + +template +template +FFSM2_CONSTEXPR(14) +void +A_::wideReact(const TEvent& event, + FullControl& control) noexcept +{ + First:: react(event, control); + Rest ::wideReact(event, control); +} + +template +template +FFSM2_CONSTEXPR(14) +void +A_::widePostReact(const TEvent& event, + FullControl& control) noexcept +{ + Rest ::widePostReact(event, control); + First:: postReact(event, control); +} + +template +template +FFSM2_CONSTEXPR(14) +void +A_::wideQuery(TEvent& event, + ConstControl& control) const noexcept +{ + First:: query(event, control); + Rest ::wideQuery(event, control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::wideExitGuard(GuardControl& control) noexcept { + Rest ::wideExitGuard(control); + First:: exitGuard(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::wideExit(PlanControl& control) noexcept { + Rest ::wideExit(control); + First:: exit(control); +} + +} +} + +namespace ffsm2 { +namespace detail { + template struct A_ : TFirst { - using typename TFirst::Context; + using First = TFirst; + using typename First::Context; - using typename TFirst::StateList; + using typename First::StateList; - using typename TFirst::ConstControl; - using typename TFirst::Control; - using typename TFirst::PlanControl; + using typename First::ConstControl; + using typename First::Control; + using typename First::PlanControl; #if FFSM2_PLANS_AVAILABLE() - using typename TFirst::Plan; + using typename First::Plan; #endif - using typename TFirst::FullControl; - using typename TFirst::GuardControl; + using typename First::FullControl; + using typename First::GuardControl; - using TFirst::stateId; + using First::stateId; #if FFSM2_UTILITY_THEORY_AVAILABLE() #endif @@ -4184,226 +4489,489 @@ struct A_ }; -template -using EmptyT = A_>; - } } - namespace ffsm2 { namespace detail { -template +template +FFSM2_CONSTEXPR(14) +void +A_::wideEntryGuard(GuardControl& control) noexcept { + First:: entryGuard(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::wideEnter(PlanControl& control) noexcept { + First:: enter(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::wideReenter(PlanControl& control) noexcept { + First:: reenter(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::widePreUpdate(FullControl& control) noexcept { + First:: preUpdate(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::wideUpdate(FullControl& control) noexcept { + First:: update(control); +} + +template +FFSM2_CONSTEXPR(14) +void +A_::widePostUpdate(FullControl& control) noexcept { + First:: postUpdate(control); +} + +template +template +FFSM2_CONSTEXPR(14) +void +A_::widePreReact(const TEvent& event, + FullControl& control) noexcept +{ + First:: preReact(event, control); +} + +template +template +FFSM2_CONSTEXPR(14) +void +A_::wideReact(const TEvent& event, + FullControl& control) noexcept +{ + First:: react(event, control); +} + +template +template +FFSM2_CONSTEXPR(14) +void +A_::widePostReact(const TEvent& event, + FullControl& control) noexcept +{ + First:: postReact(event, control); +} + +template +template +FFSM2_CONSTEXPR(14) +void +A_::wideQuery(TEvent& event, + ConstControl& control) const noexcept +{ + First:: query(event, control); +} + +template FFSM2_CONSTEXPR(14) void -A_::wideEntryGuard(GuardControl& control) noexcept { - TF :: entryGuard( control); - A_::wideEntryGuard( control); +A_::wideExitGuard(GuardControl& control) noexcept { + First:: exitGuard(control); } -template +template FFSM2_CONSTEXPR(14) void -A_::wideEnter(PlanControl& control) noexcept { - TF :: enter( control); - A_::wideEnter( control); +A_::wideExit(PlanControl& control) noexcept { + First:: exit(control); +} + +} +} + +namespace ffsm2 { +namespace detail { + +template < + StateID NStateId + , typename TArgs + , typename THead +> +struct S_ + : THead +{ + static constexpr StateID STATE_ID = NStateId; + + using Context = typename TArgs::Context; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using Logger = typename TArgs::Logger; +#endif + + using ConstControl = ConstControlT; + using ScopedCOrigin = typename ConstControl::Origin; + + using Control = ControlT ; + + using PlanControl = PlanControlT ; + using ScopedOrigin = typename PlanControl::Origin; + + using FullControl = FullControlT ; + using GuardControl = GuardControlT; + + using Empty = EmptyT; + using Head = THead; + + FFSM2_CONSTEXPR(14) bool deepEntryGuard (GuardControl& control ) noexcept; + + FFSM2_CONSTEXPR(14) void deepEnter ( PlanControl& control ) noexcept; + FFSM2_CONSTEXPR(14) void deepReenter ( PlanControl& control ) noexcept; + + FFSM2_CONSTEXPR(14) TaskStatus deepPreUpdate ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus deepUpdate ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus deepPostUpdate ( FullControl& control ) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus deepPreReact ( FullControl& control, const TEvent& event) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus deepReact ( FullControl& control, const TEvent& event) noexcept; + + template + FFSM2_CONSTEXPR(14) TaskStatus deepPostReact ( FullControl& control, const TEvent& event) noexcept; + + template + FFSM2_CONSTEXPR(14) void deepQuery (ConstControl& control, TEvent& event) const noexcept; + +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) TaskStatus deepUpdatePlans ( FullControl& control) noexcept; +#endif + + FFSM2_CONSTEXPR(14) bool deepExitGuard (GuardControl& control ) noexcept; + + FFSM2_CONSTEXPR(14) void deepExit ( PlanControl& control ) noexcept; + +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) void wrapPlanSucceeded ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) void wrapPlanFailed ( FullControl& control ) noexcept; +#endif + + FFSM2_CONSTEXPR(14) void deepChangeToRequested( Control& ) noexcept {} + +#if FFSM2_DEBUG_STATE_TYPE_AVAILABLE() || FFSM2_STRUCTURE_REPORT_AVAILABLE() || FFSM2_LOG_INTERFACE_AVAILABLE() + + FFSM2_IF_TYPEINDEX(const std::type_index TYPE = typeid(Head)); + +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + + template + FFSM2_CONSTEXPR(14) + void log(TReturn (THost::*)(TParams...), + Logger& logger, + const Context& context, + const Method method) const noexcept + { + logger.recordMethod(context, STATE_ID, method); + } + + template + FFSM2_CONSTEXPR(14) + void log(TReturn (THost::*)(TParams...) const, + Logger& logger, + const Context& context, + const Method method) const noexcept + { + logger.recordMethod(context, STATE_ID, method); + } + + template + FFSM2_CONSTEXPR(14) + void log(TReturn (Empty::*)(TParams...), + Logger&, + const Context&, + const Method) const noexcept + {} + + template + FFSM2_CONSTEXPR(14) + void log(TReturn (Empty::*)(TParams...) const, + Logger&, + const Context&, + const Method) const noexcept + {} + +#endif +}; + +} +} + +namespace ffsm2 { +namespace detail { + +template +FFSM2_CONSTEXPR(14) +bool +S_::deepEntryGuard(GuardControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::entryGuard, + Method::ENTRY_GUARD); + + ScopedOrigin origin{control, STATE_ID}; + + const bool cancelledBefore = control._cancelled; + + Head::wideEntryGuard(control); + Head:: entryGuard(control); + + return !cancelledBefore && control._cancelled; } -template +template FFSM2_CONSTEXPR(14) void -A_::wideReenter(PlanControl& control) noexcept { - TF :: Reenter( control); - A_::wideReenter( control); +S_::deepEnter(PlanControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::enter, + Method::ENTER); + + ScopedOrigin origin{control, STATE_ID}; + + Head::wideEnter(control); + Head:: enter(control); } -template +template FFSM2_CONSTEXPR(14) void -A_::widePreUpdate(FullControl& control) noexcept { - TF :: preUpdate( control); - A_::widePreUpdate( control); +S_::deepReenter(PlanControl& control) noexcept { + FFSM2_IF_PLANS(control._core.planData.verifyEmptyStatus(STATE_ID)); + + FFSM2_LOG_STATE_METHOD(&Head::reenter, + Method::REENTER); + + ScopedOrigin origin{control, STATE_ID}; + + Head::wideReenter(control); + Head:: reenter(control); +} + +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_::deepPreUpdate(FullControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::preUpdate, + Method::PRE_UPDATE); + + ScopedOrigin origin{control, STATE_ID}; + + Head::widePreUpdate(control); + Head:: preUpdate(control); + + return control._taskStatus; +} + +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_::deepUpdate(FullControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::update, + Method::UPDATE); + + ScopedOrigin origin{control, STATE_ID}; + + Head::wideUpdate(control); + Head:: update(control); + + return control._taskStatus; +} + +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_::deepPostUpdate(FullControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::postUpdate, + Method::POST_UPDATE); + + ScopedOrigin origin{control, STATE_ID}; + + Head:: postUpdate(control); + Head::widePostUpdate(control); + + return control._taskStatus; } -template -FFSM2_CONSTEXPR(14) -void -A_::wideUpdate(FullControl& control) noexcept { - TF :: update( control); - A_::wideUpdate( control); -} +template +template +FFSM2_CONSTEXPR(14) +TaskStatus +S_::deepPreReact(FullControl& control, + const TEvent& event) noexcept +{ + auto method = static_cast(&Head::preReact); + + FFSM2_LOG_STATE_METHOD(method, + Method::PRE_REACT); + + ScopedOrigin origin{control, STATE_ID}; + + Head::widePreReact(event, control); + (this->*method) (event, control); -template -FFSM2_CONSTEXPR(14) -void -A_::widePostUpdate(FullControl& control) noexcept { - A_::widePostUpdate( control); - TF :: postUpdate( control); + return control._taskStatus; } -template +template template FFSM2_CONSTEXPR(14) -void -A_::widePreReact(const TEvent& event, - FullControl& control) noexcept +TaskStatus +S_::deepReact(FullControl& control, + const TEvent& event) noexcept { - TF :: preReact( event, control); - A_::widePreReact( event, control); -} + auto method = static_cast(&Head::react); -template -template -FFSM2_CONSTEXPR(14) -void -A_::wideReact(const TEvent& event, - FullControl& control) noexcept -{ - TF :: react( event, control); - A_::wideReact( event, control); + FFSM2_LOG_STATE_METHOD(method, + Method::REACT); + + ScopedOrigin origin{control, STATE_ID}; + + Head::wideReact(event, control); + (this->*method)(event, control); + + return control._taskStatus; } -template +template template FFSM2_CONSTEXPR(14) -void -A_::widePostReact(const TEvent& event, - FullControl& control) noexcept +TaskStatus +S_::deepPostReact(FullControl& control, + const TEvent& event) noexcept { - A_::widePostReact( event, control); - TF :: postReact( event, control); + auto method = static_cast(&Head::postReact); + + FFSM2_LOG_STATE_METHOD(method, + Method::POST_REACT); + + ScopedOrigin origin{control, STATE_ID}; + + (this->*method) (event, control); + Head::widePostReact(event, control); + + return control._taskStatus; } -template +template template FFSM2_CONSTEXPR(14) void -A_::wideQuery(TEvent& event, - ConstControl& control) const noexcept +S_::deepQuery(ConstControl& control, + TEvent& event) const noexcept { - A_::wideQuery( event, control); - TF :: query( event, control); -} + auto method = static_cast(&Head::query); -template -FFSM2_CONSTEXPR(14) -void -A_::wideExitGuard(GuardControl& control) noexcept { - A_::wideExitGuard( control); - TF :: exitGuard( control); -} + FFSM2_LOG_STATE_METHOD(method, + Method::QUERY); -template -FFSM2_CONSTEXPR(14) -void -A_::wideExit(PlanControl& control) noexcept { - A_::wideExit( control); - TF :: exit( control); -} + ScopedCOrigin origin{control, STATE_ID}; -} + (this->*method)(event, control); + Head::wideQuery(event, control); } -namespace ffsm2 { -namespace detail { +#if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) -void -A_::wideEntryGuard(GuardControl& control) noexcept { - TF:: entryGuard( control); +TaskStatus +S_::deepUpdatePlans(FullControl& control) noexcept { + if (control._core.planData.tasksFailures .get(STATE_ID)) + return TaskStatus{TaskStatus::FAILURE}; + else + if (control._core.planData.tasksSuccesses.get(STATE_ID)) + return TaskStatus{TaskStatus::SUCCESS}; + else + return TaskStatus{}; } -template -FFSM2_CONSTEXPR(14) -void -A_::wideEnter(PlanControl& control) noexcept { - TF:: enter( control); -} +#endif -template +template FFSM2_CONSTEXPR(14) -void -A_::wideReenter(PlanControl& control) noexcept { - TF:: reenter( control); -} +bool +S_::deepExitGuard(GuardControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::exitGuard, + Method::EXIT_GUARD); -template -FFSM2_CONSTEXPR(14) -void -A_::widePreUpdate(FullControl& control) noexcept { - TF:: preUpdate( control); -} + ScopedOrigin origin{control, STATE_ID}; -template -FFSM2_CONSTEXPR(14) -void -A_::wideUpdate(FullControl& control) noexcept { - TF:: update( control); -} + const bool cancelledBefore = control._cancelled; -template -FFSM2_CONSTEXPR(14) -void -A_::widePostUpdate(FullControl& control) noexcept { - TF:: postUpdate( control); -} + Head::wideExitGuard(control); + Head:: exitGuard(control); -template -template -FFSM2_CONSTEXPR(14) -void -A_::widePreReact(const TEvent& event, - FullControl& control) noexcept -{ - TF:: preReact( event, control); + return !cancelledBefore && control._cancelled; } -template -template +template FFSM2_CONSTEXPR(14) void -A_::wideReact(const TEvent& event, - FullControl& control) noexcept -{ - TF:: react( event, control); -} +S_::deepExit(PlanControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::exit, + Method::EXIT); -template -template -FFSM2_CONSTEXPR(14) -void -A_::widePostReact(const TEvent& event, - FullControl& control) noexcept -{ - TF:: postReact( event, control); -} + ScopedOrigin origin{control, STATE_ID}; -template -template -FFSM2_CONSTEXPR(14) -void -A_::wideQuery(TEvent& event, - ConstControl& control) const noexcept -{ - TF:: query( event, control); + // if you see.. + // VS - error C2039: 'exit': is not a member of 'Blah' + // Clang - error : no member named 'exit' in 'Blah' + // + // .. inherit state 'Blah' from ffsm2::Machine::Instance::State + Head:: exit(control); + Head::wideExit(control); + + FFSM2_IF_PLANS(control._core.planData.clearTaskStatus(STATE_ID)); } -template +#if FFSM2_PLANS_AVAILABLE() + +template FFSM2_CONSTEXPR(14) void -A_::wideExitGuard(GuardControl& control) noexcept { - TF:: exitGuard( control); +S_::wrapPlanSucceeded(FullControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::planSucceeded, + Method::PLAN_SUCCEEDED); + + ScopedOrigin origin{control, STATE_ID}; + + Head::planSucceeded(control); } -template +template FFSM2_CONSTEXPR(14) void -A_::wideExit(PlanControl& control) noexcept { - TF:: exit( control); +S_::wrapPlanFailed(FullControl& control) noexcept { + FFSM2_LOG_STATE_METHOD(&Head::planFailed, + Method::PLAN_FAILED); + + ScopedOrigin origin{control, STATE_ID}; + + Head::planFailed(control); } +#endif + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + +#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#endif + } } @@ -4416,11 +4984,12 @@ struct None {}; #endif -template -struct S_ - : THead +template < + StateID NStateId + , typename TArgs +> +struct S_> + : EmptyT { static constexpr StateID STATE_ID = NStateId; @@ -4441,7 +5010,8 @@ struct S_ using FullControl = FullControlT ; using GuardControl = GuardControlT; - using Head = THead; + using Empty = EmptyT; + using Head = Empty; FFSM2_CONSTEXPR(14) bool deepEntryGuard (GuardControl& control ) noexcept; @@ -4481,36 +5051,12 @@ struct S_ #if FFSM2_DEBUG_STATE_TYPE_AVAILABLE() || FFSM2_STRUCTURE_REPORT_AVAILABLE() || FFSM2_LOG_INTERFACE_AVAILABLE() - using Empty = EmptyT; - - static FFSM2_CONSTEXPR(11) bool isBare() noexcept { return IsSameT::Value; } - - FFSM2_IF_TYPEINDEX(const std::type_index TYPE = isBare() ? typeid(None) : typeid(Head)); + FFSM2_IF_TYPEINDEX(const std::type_index TYPE = typeid(None)); #endif #if FFSM2_LOG_INTERFACE_AVAILABLE() - template - FFSM2_CONSTEXPR(14) - void log(TReturn (THost::*)(TParams...), - Logger& logger, - const Context& context, - const Method method) const noexcept - { - logger.recordMethod(context, STATE_ID, method); - } - - template - FFSM2_CONSTEXPR(14) - void log(TReturn (THost::*)(TParams...) const, - Logger& logger, - const Context& context, - const Method method) const noexcept - { - logger.recordMethod(context, STATE_ID, method); - } - template FFSM2_CONSTEXPR(14) void log(TReturn (Empty::*)(TParams...), @@ -4528,190 +5074,126 @@ struct S_ {} #endif - }; } } - namespace ffsm2 { namespace detail { -template +template FFSM2_CONSTEXPR(14) bool -S_::deepEntryGuard(GuardControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::entryGuard, +S_>::deepEntryGuard(GuardControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::entryGuard, Method::ENTRY_GUARD); - ScopedOrigin origin{control, STATE_ID}; - - const bool cancelledBefore = control._cancelled; - - Head::wideEntryGuard(control); - Head:: entryGuard(control); - - return !cancelledBefore && control._cancelled; + return false; } -template +template FFSM2_CONSTEXPR(14) void -S_::deepEnter(PlanControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::enter, +S_>::deepEnter(PlanControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::enter, Method::ENTER); - - ScopedOrigin origin{control, STATE_ID}; - - Head::wideEnter(control); - Head:: enter(control); } -template +template FFSM2_CONSTEXPR(14) void -S_::deepReenter(PlanControl& control) noexcept { - FFSM2_IF_PLANS(control._core.planData.verifyEmptyStatus(STATE_ID)); - - FFSM2_LOG_STATE_METHOD(&Head::reenter, +S_>::deepReenter(PlanControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::reenter, Method::REENTER); - - ScopedOrigin origin{control, STATE_ID}; - - Head::wideReenter(control); - Head:: reenter(control); } -template +template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepPreUpdate(FullControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::preUpdate, +S_>::deepPreUpdate(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::preUpdate, Method::PRE_UPDATE); - ScopedOrigin origin{control, STATE_ID}; - - Head::widePreUpdate(control); - Head:: preUpdate(control); - - return control._taskStatus; + return TaskStatus{}; } -template +template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepUpdate(FullControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::update, +S_>::deepUpdate(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::update, Method::UPDATE); - ScopedOrigin origin{control, STATE_ID}; - - Head::wideUpdate(control); - Head:: update(control); - - return control._taskStatus; + return TaskStatus{}; } -template +template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepPostUpdate(FullControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::postUpdate, +S_>::deepPostUpdate(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::postUpdate, Method::POST_UPDATE); - ScopedOrigin origin{control, STATE_ID}; - - Head:: postUpdate(control); - Head::widePostUpdate(control); - - return control._taskStatus; + return TaskStatus{}; } -template +template template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepPreReact(FullControl& control, - const TEvent& event) noexcept +S_>::deepPreReact(FullControl& FFSM2_IF_LOG_STATE_METHOD(control), + const TEvent& FFSM2_UNUSED(event)) noexcept { - auto method = static_cast(&Head::preReact); - - FFSM2_LOG_STATE_METHOD(method, + FFSM2_LOG_STATE_METHOD(static_cast(&Empty::preReact), Method::PRE_REACT); - ScopedOrigin origin{control, STATE_ID}; - - Head::widePreReact(event, control); - (this->*method) (event, control); - - return control._taskStatus; + return TaskStatus{}; } -template +template template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepReact(FullControl& control, - const TEvent& event) noexcept +S_>::deepReact(FullControl& FFSM2_IF_LOG_STATE_METHOD(control), + const TEvent& FFSM2_UNUSED(event)) noexcept { - auto method = static_cast(&Head::react); - - FFSM2_LOG_STATE_METHOD(method, + FFSM2_LOG_STATE_METHOD(static_cast(&Empty::react), Method::REACT); - ScopedOrigin origin{control, STATE_ID}; - - Head::wideReact(event, control); - (this->*method)(event, control); - - return control._taskStatus; + return TaskStatus{}; } -template +template template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepPostReact(FullControl& control, - const TEvent& event) noexcept +S_>::deepPostReact(FullControl& FFSM2_IF_LOG_STATE_METHOD(control), + const TEvent& FFSM2_UNUSED(event)) noexcept { - auto method = static_cast(&Head::postReact); - - FFSM2_LOG_STATE_METHOD(method, + FFSM2_LOG_STATE_METHOD(static_cast(&Empty::postReact), Method::POST_REACT); - ScopedOrigin origin{control, STATE_ID}; - - (this->*method) (event, control); - Head::widePostReact(event, control); - - return control._taskStatus; + return TaskStatus{}; } -template +template template FFSM2_CONSTEXPR(14) void -S_::deepQuery(ConstControl& control, - TEvent& event) const noexcept +S_>::deepQuery(ConstControl& FFSM2_IF_LOG_STATE_METHOD(control), + TEvent& FFSM2_UNUSED(event)) const noexcept { - auto method = static_cast(&Head::query); - - FFSM2_LOG_STATE_METHOD(method, + FFSM2_LOG_STATE_METHOD(static_cast(&Empty::query), Method::QUERY); - - ScopedCOrigin origin{control, STATE_ID}; - - (this->*method)(event, control); - Head::wideQuery(event, control); } #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) TaskStatus -S_::deepUpdatePlans(FullControl& control) noexcept { +S_>::deepUpdatePlans(FullControl& control) noexcept { if (control._core.planData.tasksFailures .get(STATE_ID)) return TaskStatus{TaskStatus::FAILURE}; else @@ -4723,71 +5205,51 @@ S_::deepUpdatePlans(FullControl& control) noexcept { #endif -template +template FFSM2_CONSTEXPR(14) bool -S_::deepExitGuard(GuardControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::exitGuard, +S_>::deepExitGuard(GuardControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::exitGuard, Method::EXIT_GUARD); - ScopedOrigin origin{control, STATE_ID}; - - const bool cancelledBefore = control._cancelled; - - Head::wideExitGuard(control); - Head:: exitGuard(control); - - return !cancelledBefore && control._cancelled; + return false; } -template +template FFSM2_CONSTEXPR(14) void -S_::deepExit(PlanControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::exit, +S_>::deepExit(PlanControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::exit, Method::EXIT); - - ScopedOrigin origin{control, STATE_ID}; - - // if you see.. - // VS - error C2039: 'exit': is not a member of 'Blah' - // Clang - error : no member named 'exit' in 'Blah' - // - // .. inherit state 'Blah' from ffsm2::Machine::Instance::State - Head:: exit(control); - Head::wideExit(control); - - FFSM2_IF_PLANS(control._core.planData.clearTaskStatus(STATE_ID)); } #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -S_::wrapPlanSucceeded(FullControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::planSucceeded, +S_>::wrapPlanSucceeded(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::planSucceeded, Method::PLAN_SUCCEEDED); - - ScopedOrigin origin{control, STATE_ID}; - - Head::planSucceeded(control); } -template +template FFSM2_CONSTEXPR(14) void -S_::wrapPlanFailed(FullControl& control) noexcept { - FFSM2_LOG_STATE_METHOD(&Head::planFailed, +S_>::wrapPlanFailed(FullControl& FFSM2_IF_LOG_STATE_METHOD(control)) noexcept { + FFSM2_LOG_STATE_METHOD(&Empty::planFailed, Method::PLAN_FAILED); - ScopedOrigin origin{control, STATE_ID}; - - Head::planFailed(control); } #endif +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + +#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#endif + } } @@ -4807,7 +5269,7 @@ template struct WrapInfoT; template -struct WrapInfoT< TH> final { +struct WrapInfoT final { using Type = SI_; }; @@ -4824,9 +5286,26 @@ struct SI_ final { using Head = THead; using StateList = TL_; - static constexpr Short WIDTH = 1; + static constexpr Short WIDTH = 1; + + static constexpr Long STATE_COUNT = StateList::SIZE; +}; + +template +struct CI_ final { + using Head = THead; + using HeadInfo = SI_; + using SubStates = CSI_>; + using StateList = typename SubStates::StateList; + + static constexpr Short WIDTH = sizeof...(TSubStates); + + static constexpr Long STATE_COUNT = StateList::SIZE; - static constexpr Long STATE_COUNT = StateList::SIZE; +#if FFSM2_SERIALIZATION_AVAILABLE() + static constexpr Long WIDTH_BITS = static_cast(bitWidth(WIDTH)); + static constexpr Long ACTIVE_BITS = WIDTH_BITS; +#endif }; template @@ -4835,7 +5314,7 @@ struct CSI_> final { using Remaining = CSI_>; using StateList = Merge; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList::SIZE; }; template @@ -4843,53 +5322,37 @@ struct CSI_> final { using Initial = WrapInfo; using StateList = typename Initial::StateList; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList::SIZE; }; -template -struct CI_ final { - using Head = THead; - using HeadInfo = SI_; - using SubStates = CSI_>; - using StateList = typename SubStates::StateList; - - static constexpr Short WIDTH = sizeof...(TSubStates); - -#if FFSM2_SERIALIZATION_AVAILABLE() - static constexpr Long WIDTH_BITS = static_cast(bitWidth(WIDTH)); - static constexpr Long ACTIVE_BITS = WIDTH_BITS; -#endif - - static constexpr Long STATE_COUNT = StateList::SIZE; -}; - -template +template < + typename TConfig + , typename TStateList + FFSM2_IF_SERIALIZATION(, Long NSerialBits) + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload +> struct ArgsT final { - using Context = TContext; + using Config = TConfig; + using Context = typename Config::Context; using PureContext = Undecorate; #if FFSM2_LOG_INTERFACE_AVAILABLE() - using Logger = typename TConfig::LoggerInterface; + using Logger = typename Config::LoggerInterface; #endif using StateList = TStateList; - static constexpr Long STATE_COUNT = StateList::SIZE; + static constexpr Long STATE_COUNT = StateList ::SIZE; #if FFSM2_SERIALIZATION_AVAILABLE() - static constexpr Short SERIAL_BITS = NSerialBits; + static constexpr Short SERIAL_BITS = NSerialBits; #endif - static constexpr Short SUBSTITUTION_LIMIT = NSubstitutionLimit; + static constexpr Short SUBSTITUTION_LIMIT = Config::SUBSTITUTION_LIMIT; #if FFSM2_PLANS_AVAILABLE() - static constexpr Long TASK_CAPACITY = NTaskCapacity; + static constexpr Long TASK_CAPACITY = NTaskCapacity; #endif using Payload = TPayload; @@ -4921,41 +5384,44 @@ struct MaterialT_ final { using Type = S_; }; -template -struct MaterialT_ > { - using Type = C_< TA, EmptyT, TS...>; +template +struct MaterialT_ > { + using Type = C_< TA, EmptyT, TS...>; }; template -struct MaterialT_ > { - using Type = C_< TA, TH, TS...>; +struct MaterialT_ > { + using Type = C_< TA, TH, TS...>; }; template using MaterialT = typename MaterialT_::Type; -template +template < + typename TConfig + , typename TApex +> struct RF_ final { - using Context = typename TConfig::Context; - using Apex = TApex; + using Config = TConfig; + using Context = typename Config::Context; + using Apex = TApex; - using StateList = typename Apex::StateList; + using StateList = typename Apex::StateList; static constexpr Long STATE_COUNT = Apex::STATE_COUNT; - static constexpr Long SUBSTITUTION_LIMIT = TConfig::SUBSTITUTION_LIMIT; + static constexpr Short SUBSTITUTION_LIMIT = Config::SUBSTITUTION_LIMIT; #if FFSM2_PLANS_AVAILABLE() - static constexpr Long TASK_CAPACITY = TConfig::TASK_CAPACITY != INVALID_LONG ? - TConfig::TASK_CAPACITY : Apex::STATE_COUNT; + static constexpr Long TASK_CAPACITY = Config::TASK_CAPACITY != INVALID_LONG ? + Config::TASK_CAPACITY : Apex::STATE_COUNT; #endif - using Payload = typename TConfig::Payload; - using Transition = TransitionT; + using Payload = typename Config::Payload; + using Transition = TransitionT; #if FFSM2_PLANS_AVAILABLE() - using Task = typename TConfig::Task; + using Task = typename Config::Task; #endif #if FFSM2_SERIALIZATION_AVAILABLE() @@ -4963,28 +5429,28 @@ struct RF_ final { static constexpr Long SERIAL_BITS = 1 + ACTIVE_BITS; #endif - using Args = ArgsT; + using Args = ArgsT< + TConfig + , StateList + FFSM2_IF_SERIALIZATION(, SERIAL_BITS) + FFSM2_IF_PLANS(, TASK_CAPACITY) + , Payload + >; - using Instance = InstanceT; + using Instance = InstanceT; - using ConstControl = ConstControlT; - using Control = ControlT ; - using FullControl = FullControlT ; - using GuardControl = GuardControlT; + using ConstControl = ConstControlT; + using Control = ControlT ; + using FullControl = FullControlT ; + using GuardControl = GuardControlT; - using State = EmptyT; + using State = EmptyT ; template - using StateT = A_; + using StateT = A_; #if FFSM2_LOG_INTERFACE_AVAILABLE() - using Logger = typename TConfig::LoggerInterface; + using Logger = typename Config::LoggerInterface; #endif template @@ -5028,25 +5494,35 @@ using RHalfCS = typename RHalfCST::Type; namespace ffsm2 { namespace detail { -template -struct FFSM2_EMPTY_BASES CS_> - : LHalfCS> - , RHalfCS> +template < + StateID NStateId + , typename TArgs + , Prong NProng + , typename... TStates +> +struct FFSM2_EMPTY_BASES CS_< + NStateId + , TArgs + , NProng + , TL_ + > + : LHalfCS< + NStateId + , TArgs + , NProng + , TL_ + > + , RHalfCS< + NStateId + , TArgs + , NProng + , TL_ + > { static_assert(sizeof...(TStates) >= 2, ""); + static constexpr Prong PRONG_INDEX = NProng; + using Args = TArgs; using SubStateList = TL_; @@ -5059,319 +5535,55 @@ struct FFSM2_EMPTY_BASES CS_; static constexpr StateID INITIAL_ID = NStateId; - static constexpr Short PRONG_INDEX = NIndex; - static constexpr Short R_PRONG = PRONG_INDEX + sizeof...(TStates) / 2; - - using LHalf = LHalfCS; - - using RHalf = RHalfCS; - - FFSM2_CONSTEXPR(14) bool wideEntryGuard (GuardControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) TaskStatus widePreUpdate ( FullControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus wideUpdate ( FullControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus widePostUpdate ( FullControl& control, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus widePreReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus wideReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) TaskStatus widePostReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; - - template - FFSM2_CONSTEXPR(14) void wideQuery (ConstControl& control, TEvent& event, const Short prong) const noexcept; - -#if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(14) TaskStatus wideUpdatePlans ( FullControl& control, const Short prong) noexcept; -#endif - - FFSM2_CONSTEXPR(14) bool wideExitGuard (GuardControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideChangeToRequested( PlanControl& control, const Short prong) noexcept; - -}; - -template -struct CS_> - : MaterialT -{ - static constexpr Short PRONG_INDEX = NIndex; - - using Args = TArgs; - - using StateList = typename Args::StateList; - - using ConstControl = ConstControlT; - using Control = ControlT ; - using PlanControl = PlanControlT ; - using FullControl = FullControlT ; - using GuardControl = GuardControlT; + static constexpr Prong L_PRONG = PRONG_INDEX; + static constexpr Prong R_PRONG = PRONG_INDEX + sizeof...(TStates) / 2; - using Single = MaterialT; + using LHalf = LHalfCS< + INITIAL_ID + , Args + , PRONG_INDEX + , SubStateList + >; - FFSM2_CONSTEXPR(14) bool wideEntryGuard (GuardControl& control, const Short prong) noexcept; + using RHalf = RHalfCS< + INITIAL_ID + , Args + , PRONG_INDEX + , SubStateList + >; - FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control, const Short prong) noexcept; + FFSM2_CONSTEXPR(14) bool wideEntryGuard (GuardControl& control, const Prong prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus widePreUpdate ( FullControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus wideUpdate ( FullControl& control, const Short prong) noexcept; - FFSM2_CONSTEXPR(14) TaskStatus widePostUpdate ( FullControl& control, const Short prong) noexcept; + FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control, const Prong prong) noexcept; - template - FFSM2_CONSTEXPR(14) TaskStatus widePreReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePreUpdate ( FullControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus wideUpdate ( FullControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePostUpdate ( FullControl& control, const Prong prong) noexcept; template - FFSM2_CONSTEXPR(14) TaskStatus wideReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePreReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; template - FFSM2_CONSTEXPR(14) TaskStatus widePostReact ( FullControl& control, const TEvent& event, const Short prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus wideReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; template - FFSM2_CONSTEXPR(14) void wideQuery (ConstControl& control, TEvent& event, const Short prong) const noexcept; - -#if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(14) TaskStatus wideUpdatePlans ( FullControl& control, const Short prong) noexcept; -#endif - - FFSM2_CONSTEXPR(14) bool wideExitGuard (GuardControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control, const Short prong) noexcept; - - FFSM2_CONSTEXPR(14) void wideChangeToRequested( PlanControl& control, const Short prong) noexcept; - -}; - -} -} - - -namespace ffsm2 { -namespace detail { - -template -FFSM2_CONSTEXPR(14) -bool -CS_>::wideEntryGuard(GuardControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - if (prong < R_PRONG) - return LHalf::wideEntryGuard(control, prong); - else - return RHalf::wideEntryGuard(control, prong); -} - -template -FFSM2_CONSTEXPR(14) -void -CS_>::wideEnter(PlanControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - if (prong < R_PRONG) - LHalf::wideEnter(control, prong); - else - RHalf::wideEnter(control, prong); -} - -template -FFSM2_CONSTEXPR(14) -void -CS_>::wideReenter(PlanControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - if (prong < R_PRONG) - LHalf::wideReenter(control, prong); - else - RHalf::wideReenter(control, prong); -} - -template -FFSM2_CONSTEXPR(14) -TaskStatus -CS_>::widePreUpdate(FullControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - return prong < R_PRONG ? - LHalf::widePreUpdate(control, prong) : - RHalf::widePreUpdate(control, prong); -} - -template -FFSM2_CONSTEXPR(14) -TaskStatus -CS_>::wideUpdate(FullControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - return prong < R_PRONG ? - LHalf::wideUpdate(control, prong) : - RHalf::wideUpdate(control, prong); -} - -template -FFSM2_CONSTEXPR(14) -TaskStatus -CS_>::widePostUpdate(FullControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - return prong < R_PRONG ? - LHalf::widePostUpdate(control, prong) : - RHalf::widePostUpdate(control, prong); -} - -template -template -FFSM2_CONSTEXPR(14) -TaskStatus -CS_>::widePreReact(FullControl& control, - const TEvent& event, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - return prong < R_PRONG ? - LHalf::widePreReact(control, event, prong) : - RHalf::widePreReact(control, event, prong); -} - -template -template -FFSM2_CONSTEXPR(14) -TaskStatus -CS_>::wideReact(FullControl& control, - const TEvent& event, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - return prong < R_PRONG ? - LHalf::wideReact(control, event, prong) : - RHalf::wideReact(control, event, prong); -} - -template -template -FFSM2_CONSTEXPR(14) -TaskStatus -CS_>::widePostReact(FullControl& control, - const TEvent& event, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - return prong < R_PRONG ? - LHalf::widePostReact(control, event, prong) : - RHalf::widePostReact(control, event, prong); -} - -template -template -FFSM2_CONSTEXPR(14) -void -CS_>::wideQuery(ConstControl& control, - TEvent& event, - const Short prong) const noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - return prong < R_PRONG ? - LHalf::wideQuery(control, event, prong) : - RHalf::wideQuery(control, event, prong); -} - -#if FFSM2_PLANS_AVAILABLE() - -template -FFSM2_CONSTEXPR(14) -TaskStatus -CS_>::wideUpdatePlans(FullControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); - - return prong < R_PRONG ? - LHalf::wideUpdatePlans(control, prong) : - RHalf::wideUpdatePlans(control, prong); -} - -#endif + FFSM2_CONSTEXPR(14) TaskStatus widePostReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; -template -FFSM2_CONSTEXPR(14) -bool -CS_>::wideExitGuard(GuardControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); + template + FFSM2_CONSTEXPR(14) void wideQuery (ConstControl& control, TEvent& event, const Prong prong) const noexcept; - if (prong < R_PRONG) - return LHalf::wideExitGuard(control, prong); - else - return RHalf::wideExitGuard(control, prong); -} +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) TaskStatus wideUpdatePlans ( FullControl& control, const Prong prong) noexcept; +#endif -template -FFSM2_CONSTEXPR(14) -void -CS_>::wideExit(PlanControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_CONSTEXPR(14) bool wideExitGuard (GuardControl& control, const Prong prong) noexcept; - if (prong < R_PRONG) - LHalf::wideExit(control, prong); - else - RHalf::wideExit(control, prong); -} + FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control, const Prong prong) noexcept; -template -FFSM2_CONSTEXPR(14) -void -CS_>::wideChangeToRequested(PlanControl& control, - const Short prong) noexcept -{ - FFSM2_ASSERT(prong != INVALID_SHORT); + FFSM2_CONSTEXPR(14) void wideChangeToRequested( PlanControl& control, const Prong prong) noexcept; - if (prong < R_PRONG) - LHalf::wideChangeToRequested(control, prong); - else - RHalf::wideChangeToRequested(control, prong); -} +}; } } @@ -5379,159 +5591,204 @@ CS_>::wideChangeToRequested(PlanControl& control, namespace ffsm2 { namespace detail { -template +template FFSM2_CONSTEXPR(14) bool -CS_>::wideEntryGuard(GuardControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideEntryGuard(GuardControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepEntryGuard(control); + if (prong < R_PRONG) + return LHalf::wideEntryGuard(control, prong); + else + return RHalf::wideEntryGuard(control, prong); } -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideEnter(PlanControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideEnter(PlanControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - Single::deepEnter(control); + if (prong < R_PRONG) + LHalf::wideEnter(control, prong); + else + RHalf::wideEnter(control, prong); } -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideReenter(PlanControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideReenter(PlanControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - Single::deepReenter(control); + if (prong < R_PRONG) + LHalf::wideReenter(control, prong); + else + RHalf::wideReenter(control, prong); } -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePreUpdate(FullControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::widePreUpdate(FullControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepPreUpdate(control); + return prong < R_PRONG ? + LHalf::widePreUpdate(control, prong) : + RHalf::widePreUpdate(control, prong); } -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideUpdate(FullControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideUpdate(FullControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepUpdate(control); + return prong < R_PRONG ? + LHalf::wideUpdate(control, prong) : + RHalf::wideUpdate(control, prong); } -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePostUpdate(FullControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::widePostUpdate(FullControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepPostUpdate(control); + return prong < R_PRONG ? + LHalf::widePostUpdate(control, prong) : + RHalf::widePostUpdate(control, prong); } -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePreReact(FullControl& control, - const TEvent& event, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::widePreReact(FullControl& control, + const TEvent& event, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepPreReact(control, event); + return prong < R_PRONG ? + LHalf::widePreReact(control, event, prong) : + RHalf::widePreReact(control, event, prong); } -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideReact(FullControl& control, - const TEvent& event, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideReact(FullControl& control, + const TEvent& event, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepReact(control, event); + return prong < R_PRONG ? + LHalf::wideReact(control, event, prong) : + RHalf::wideReact(control, event, prong); } -template +template template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::widePostReact(FullControl& control, - const TEvent& event, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::widePostReact(FullControl& control, + const TEvent& event, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepPostReact(control, event); + return prong < R_PRONG ? + LHalf::widePostReact(control, event, prong) : + RHalf::widePostReact(control, event, prong); } -template +template template FFSM2_CONSTEXPR(14) void -CS_>::wideQuery(ConstControl& control, - TEvent& event, - const Short FFSM2_IF_ASSERT(prong)) const noexcept +CS_>::wideQuery(ConstControl& control, + TEvent& event, + const Prong prong) const noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepQuery(control, event); + return prong < R_PRONG ? + LHalf::wideQuery(control, event, prong) : + RHalf::wideQuery(control, event, prong); } #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) TaskStatus -CS_>::wideUpdatePlans(FullControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideUpdatePlans(FullControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepUpdatePlans(control); + return prong < R_PRONG ? + LHalf::wideUpdatePlans(control, prong) : + RHalf::wideUpdatePlans(control, prong); } #endif -template +template FFSM2_CONSTEXPR(14) bool -CS_>::wideExitGuard(GuardControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideExitGuard(GuardControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - return Single::deepExitGuard(control); + if (prong < R_PRONG) + return LHalf::wideExitGuard(control, prong); + else + return RHalf::wideExitGuard(control, prong); } -template +template FFSM2_CONSTEXPR(14) void -CS_>::wideExit(PlanControl& control, - const Short FFSM2_IF_ASSERT(prong)) noexcept +CS_>::wideExit(PlanControl& control, + const Prong prong) noexcept { - FFSM2_ASSERT(prong == PRONG_INDEX); + FFSM2_ASSERT(prong != INVALID_PRONG); - Single::deepExit(control); + if (prong < R_PRONG) + LHalf::wideExit(control, prong); + else + RHalf::wideExit(control, prong); +} + +template +FFSM2_CONSTEXPR(14) +void +CS_>::wideChangeToRequested(PlanControl& control, + const Prong prong) noexcept +{ + FFSM2_ASSERT(prong != INVALID_PRONG); + + if (prong < R_PRONG) + LHalf::wideChangeToRequested(control, prong); + else + RHalf::wideChangeToRequested(control, prong); } } @@ -5540,1206 +5797,1092 @@ CS_>::wideExit(PlanControl& control, namespace ffsm2 { namespace detail { -template -struct FFSM2_EMPTY_BASES C_ - : S_ - , CS_<0, TArgs, 0, TL_> +template < + StateID NStateId + , typename TArgs + , Prong NProng + , typename TState +> +struct CS_< + NStateId + , TArgs + , NProng + , TL_ + > + : MaterialT< + NStateId + , TArgs + , TState + > { - using Args = TArgs; + static constexpr Prong PRONG_INDEX = NProng; - using HeadState = S_; - using SubStates = CS_<0, Args, 0, TL_>; + using Args = TArgs; using StateList = typename Args::StateList; using ConstControl = ConstControlT; using Control = ControlT ; - using ScopedOrigin = typename Control::Origin; - using PlanControl = PlanControlT ; - using ScopedRegion = typename PlanControl::Region; - -#if FFSM2_PLANS_AVAILABLE() - using Plan = typename PlanControl::Plan; -#endif - using FullControl = FullControlT ; - using ControlLock = typename FullControl::Lock; - using GuardControl = GuardControlT; -#if FFSM2_PLANS_AVAILABLE() - using PlanData = typename Control::PlanData; -#endif - - using Head = THead; - using Info = CI_; - - static constexpr Short WIDTH = Info::WIDTH; - -#if FFSM2_SERIALIZATION_AVAILABLE() - static constexpr Short WIDTH_BITS = Info::WIDTH_BITS; -#endif - - FFSM2_CONSTEXPR(11) static Short& compoRequested ( Control& control) noexcept { return control._core.registry.requested; } - - FFSM2_CONSTEXPR(11) static Short& compoActive ( Control& control) noexcept { return control._core.registry.active; } - FFSM2_CONSTEXPR(11) static Short compoActive (ConstControl& control) noexcept { return control._core.registry.active; } - -#if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(11) static TaskStatus& headStatus ( Control& control) noexcept { return control._core.planData.headStatus; } - FFSM2_CONSTEXPR(11) static TaskStatus& subStatus ( Control& control) noexcept { return control._core.planData.subStatus; } -#endif + using Single = MaterialT< + NStateId + , Args + , TState + >; - FFSM2_CONSTEXPR(14) bool deepForwardEntryGuard (GuardControl& control ) noexcept; - FFSM2_CONSTEXPR(14) bool deepEntryGuard (GuardControl& control ) noexcept; + FFSM2_CONSTEXPR(14) bool wideEntryGuard (GuardControl& control, const Prong prong) noexcept; - FFSM2_CONSTEXPR(14) void deepEnter ( PlanControl& control ) noexcept; - FFSM2_CONSTEXPR(14) void deepReenter ( PlanControl& control ) noexcept; + FFSM2_CONSTEXPR(14) void wideEnter ( PlanControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) void wideReenter ( PlanControl& control, const Prong prong) noexcept; - FFSM2_CONSTEXPR(14) void deepPreUpdate ( FullControl& control ) noexcept; - FFSM2_CONSTEXPR(14) void deepUpdate ( FullControl& control ) noexcept; - FFSM2_CONSTEXPR(14) void deepPostUpdate ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePreUpdate ( FullControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus wideUpdate ( FullControl& control, const Prong prong) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePostUpdate ( FullControl& control, const Prong prong) noexcept; template - FFSM2_CONSTEXPR(14) void deepPreReact ( FullControl& control, const TEvent& event) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePreReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; template - FFSM2_CONSTEXPR(14) void deepReact ( FullControl& control, const TEvent& event) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus wideReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; template - FFSM2_CONSTEXPR(14) void deepPostReact ( FullControl& control, const TEvent& event) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus widePostReact ( FullControl& control, const TEvent& event, const Prong prong) noexcept; template - FFSM2_CONSTEXPR(14) void deepQuery (ConstControl& control, TEvent& event) const noexcept; + FFSM2_CONSTEXPR(14) void wideQuery (ConstControl& control, TEvent& event, const Prong prong) const noexcept; #if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(14) void deepUpdatePlans ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) TaskStatus wideUpdatePlans ( FullControl& control, const Prong prong) noexcept; #endif - FFSM2_CONSTEXPR(14) bool deepForwardExitGuard (GuardControl& control ) noexcept; - FFSM2_CONSTEXPR(14) bool deepExitGuard (GuardControl& control ) noexcept; - - FFSM2_CONSTEXPR(14) void deepExit ( PlanControl& control ) noexcept; - - FFSM2_CONSTEXPR(14) void deepChangeToRequested ( PlanControl& control ) noexcept; + FFSM2_CONSTEXPR(14) bool wideExitGuard (GuardControl& control, const Prong prong) noexcept; -#if FFSM2_SERIALIZATION_AVAILABLE() - using WriteStream = typename Args::WriteStream; - using ReadStream = typename Args::ReadStream; + FFSM2_CONSTEXPR(14) void wideExit ( PlanControl& control, const Prong prong) noexcept; - FFSM2_CONSTEXPR(14) void deepSaveActive (const Registry& registry, WriteStream& stream) const noexcept; - FFSM2_CONSTEXPR(14) void deepLoadRequested ( Registry& registry, ReadStream& stream) const noexcept; -#endif + FFSM2_CONSTEXPR(14) void wideChangeToRequested( PlanControl& control, const Prong prong) noexcept; }; } } - namespace ffsm2 { namespace detail { -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif - -template -FFSM2_CONSTEXPR(14) -bool -C_::deepForwardEntryGuard(GuardControl& control) noexcept { - const Short requested = compoRequested(control); - FFSM2_ASSERT(requested < WIDTH); - - FFSM2_ASSERT(compoActive(control) < WIDTH); - - return SubStates::wideEntryGuard(control, requested); -} - -template +template FFSM2_CONSTEXPR(14) bool -C_::deepEntryGuard(GuardControl& control) noexcept { - const Short requested = compoRequested(control); - FFSM2_ASSERT(requested < WIDTH); +CS_>::wideEntryGuard(GuardControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); - return HeadState::deepEntryGuard(control) || - SubStates::wideEntryGuard(control, requested); + return Single::deepEntryGuard(control); } -template +template FFSM2_CONSTEXPR(14) void -C_::deepEnter(PlanControl& control) noexcept { - Short& requested = compoRequested(control); - Short& active = compoActive (control); - - FFSM2_ASSERT(requested < WIDTH); - FFSM2_ASSERT(active == INVALID_SHORT); - - active = requested; - requested = INVALID_SHORT; +CS_>::wideEnter(PlanControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); - HeadState::deepEnter(control); - SubStates::wideEnter(control, active); + Single::deepEnter(control); } -template +template FFSM2_CONSTEXPR(14) void -C_::deepReenter(PlanControl& /*control*/) noexcept { +CS_>::wideReenter(PlanControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); + + Single::deepReenter(control); } -template +template FFSM2_CONSTEXPR(14) -void -C_::deepPreUpdate(FullControl& control) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); - - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); - - ScopedRegion region{control}; - - FFSM2_IF_PLANS(const TaskStatus h =) - HeadState::deepPreUpdate(control); - FFSM2_IF_PLANS(headStatus(control) |= h); +TaskStatus +CS_>::widePreUpdate(FullControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); - FFSM2_IF_PLANS(subStatus(control) |=) - SubStates::widePreUpdate(control, active); + return Single::deepPreUpdate(control); } -template +template FFSM2_CONSTEXPR(14) -void -C_::deepUpdate(FullControl& control) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); - - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); - - ScopedRegion region{control}; - - FFSM2_IF_PLANS(const TaskStatus h =) - HeadState::deepUpdate(control); - FFSM2_IF_PLANS(headStatus(control) |= h); +TaskStatus +CS_>::wideUpdate(FullControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); - FFSM2_IF_PLANS(subStatus(control) |=) - SubStates::wideUpdate(control, active); + return Single::deepUpdate(control); } -template +template FFSM2_CONSTEXPR(14) -void -C_::deepPostUpdate(FullControl& control) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); - - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); - - ScopedRegion region{control}; - - FFSM2_IF_PLANS(subStatus(control) |=) - SubStates::widePostUpdate(control, active); +TaskStatus +CS_>::widePostUpdate(FullControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); - FFSM2_IF_PLANS(const TaskStatus h =) - HeadState::deepPostUpdate(control); - FFSM2_IF_PLANS(headStatus(control) |= h); + return Single::deepPostUpdate(control); } -template +template template FFSM2_CONSTEXPR(14) -void -C_::deepPreReact(FullControl& control, - const TEvent& event) noexcept +TaskStatus +CS_>::widePreReact(FullControl& control, + const TEvent& event, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); - - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); - - ScopedRegion region{control}; - - FFSM2_IF_PLANS(const TaskStatus h =) - HeadState::deepPreReact(control, event); - FFSM2_IF_PLANS(headStatus(control) |= h); + FFSM2_ASSERT(prong == PRONG_INDEX); - FFSM2_IF_PLANS(subStatus(control) |=) - SubStates::widePreReact(control, event, active); + return Single::deepPreReact(control, event); } -template +template template FFSM2_CONSTEXPR(14) -void -C_::deepReact(FullControl& control, - const TEvent& event) noexcept +TaskStatus +CS_>::wideReact(FullControl& control, + const TEvent& event, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); - - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); - - ScopedRegion region{control}; - - FFSM2_IF_PLANS(const TaskStatus h =) - HeadState::deepReact(control, event); - FFSM2_IF_PLANS(headStatus(control) |= h); + FFSM2_ASSERT(prong == PRONG_INDEX); - FFSM2_IF_PLANS(subStatus(control) |=) - SubStates::wideReact(control, event, active); + return Single::deepReact(control, event); } -template +template template FFSM2_CONSTEXPR(14) -void -C_::deepPostReact(FullControl& control, - const TEvent& event) noexcept +TaskStatus +CS_>::widePostReact(FullControl& control, + const TEvent& event, + const Prong FFSM2_IF_ASSERT(prong)) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); - - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); - - ScopedRegion region{control}; - - FFSM2_IF_PLANS(subStatus(control) |=) - SubStates::widePostReact(control, event, active); + FFSM2_ASSERT(prong == PRONG_INDEX); - FFSM2_IF_PLANS(const TaskStatus h =) - HeadState::deepPostReact(control, event); - FFSM2_IF_PLANS(headStatus(control) |= h); + return Single::deepPostReact(control, event); } -template +template template FFSM2_CONSTEXPR(14) void -C_::deepQuery(ConstControl& control, - TEvent& event) const noexcept +CS_>::wideQuery(ConstControl& control, + TEvent& event, + const Prong FFSM2_IF_ASSERT(prong)) const noexcept { - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); + FFSM2_ASSERT(prong == PRONG_INDEX); - HeadState::deepQuery(control, event); - SubStates::wideQuery(control, event, active); + return Single::deepQuery(control, event); } #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) -void -C_::deepUpdatePlans(FullControl& control) noexcept { - FFSM2_ASSERT(compoRequested(control) == INVALID_SHORT); - - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); - - const TaskStatus s = subStatus(control) | - SubStates::wideUpdatePlans(control, active); - - const bool planExists = control._core.planData.planExists; +TaskStatus +CS_>::wideUpdatePlans(FullControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); - if (s && planExists) - control.updatePlan(static_cast(*this), s); + return Single::deepUpdatePlans(control); } #endif -template +template FFSM2_CONSTEXPR(14) bool -C_::deepForwardExitGuard(GuardControl& control) noexcept { - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); - - FFSM2_ASSERT(compoRequested(control) < WIDTH); +CS_>::wideExitGuard(GuardControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); - return SubStates::wideExitGuard(control, active); + return Single::deepExitGuard(control); } -template +template FFSM2_CONSTEXPR(14) -bool -C_::deepExitGuard(GuardControl& control) noexcept { - const Short active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); +void +CS_>::wideExit(PlanControl& control, + const Prong FFSM2_IF_ASSERT(prong)) noexcept +{ + FFSM2_ASSERT(prong == PRONG_INDEX); - FFSM2_ASSERT(compoRequested(control) < WIDTH); + Single::deepExit(control); +} - return HeadState::deepExitGuard(control) || - SubStates::wideExitGuard(control, active); +} } -template -FFSM2_CONSTEXPR(14) -void -C_::deepExit(PlanControl& control) noexcept { - Short& active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); +namespace ffsm2 { +namespace detail { - SubStates::wideExit(control, active); - HeadState::deepExit(control); +template < + typename TArgs + , typename THead + , typename... TSubStates +> +struct FFSM2_EMPTY_BASES C_ + : S_ + , CS_< + 0 + , TArgs + , 0 + , TL_ + > +{ + using Args = TArgs; + + using HeadState = S_; + using SubStates = CS_<0, Args, 0, TL_>; + + using StateList = typename Args::StateList; - active = INVALID_SHORT; + using ConstControl = ConstControlT; + using Control = ControlT ; + using ScopedOrigin = typename Control::Origin; + + using PlanControl = PlanControlT ; + using ScopedRegion = typename PlanControl::Region; #if FFSM2_PLANS_AVAILABLE() - Plan plan = control.plan(); - plan.clear(); + using Plan = typename PlanControl::Plan; #endif -} - -template -FFSM2_CONSTEXPR(14) -void -C_::deepChangeToRequested(PlanControl& control) noexcept { - Short& requested = compoRequested(control); - Short& active = compoActive(control); - FFSM2_ASSERT(active < WIDTH); + using FullControl = FullControlT ; + using ControlLock = typename FullControl::Lock; - FFSM2_ASSERT(requested < WIDTH); + using GuardControl = GuardControlT; - if (requested != active) { - SubStates::wideExit (control, active); +#if FFSM2_PLANS_AVAILABLE() + using PlanData = typename Control::PlanData; +#endif - active = requested; - requested = INVALID_SHORT; + using Head = THead; + using Info = CI_; - SubStates::wideEnter (control, active); - } else { - requested = INVALID_SHORT; + static constexpr Short WIDTH = Info::WIDTH; - // reconstruction done in S_::reenter() - SubStates::wideReenter(control, active); - } -} +#if FFSM2_SERIALIZATION_AVAILABLE() + static constexpr Short WIDTH_BITS = Info::WIDTH_BITS; +#endif #if FFSM2_SERIALIZATION_AVAILABLE() + FFSM2_CONSTEXPR(11) static Prong compoRequested (const Registry& registry) noexcept { return registry.requested; } + FFSM2_CONSTEXPR(11) static Prong& compoRequested ( Registry& registry) noexcept { return registry.requested; } +#endif -template -FFSM2_CONSTEXPR(14) -void -C_::deepSaveActive(const Registry& registry, - WriteStream& stream) const noexcept -{ - stream.template write(registry.active); -} + FFSM2_CONSTEXPR(11) static Prong& compoRequested ( Control& control) noexcept { return control._core.registry.requested; } -template -FFSM2_CONSTEXPR(14) -void -C_::deepLoadRequested(Registry& registry, - ReadStream& stream) const noexcept -{ - registry.requested = stream.template read(); - FFSM2_ASSERT(registry.requested < WIDTH); -} + FFSM2_CONSTEXPR(11) static Prong& compoActive ( Control& control) noexcept { return control._core.registry.active; } + FFSM2_CONSTEXPR(11) static Prong compoActive (ConstControl& control) noexcept { return control._core.registry.active; } +#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(11) static TaskStatus& headStatus ( Control& control) noexcept { return control._core.planData.headStatus; } + FFSM2_CONSTEXPR(11) static TaskStatus& subStatus ( Control& control) noexcept { return control._core.planData.subStatus; } #endif -} -} -namespace ffsm2 { -namespace detail { + FFSM2_CONSTEXPR(14) bool deepForwardEntryGuard (GuardControl& control ) noexcept; + FFSM2_CONSTEXPR(14) bool deepEntryGuard (GuardControl& control ) noexcept; -template -struct G_ final { - static constexpr FeatureTag FEATURE_TAG = NFeatureTag; + FFSM2_CONSTEXPR(14) void deepEnter ( PlanControl& control ) noexcept; + FFSM2_CONSTEXPR(14) void deepReenter ( PlanControl& control ) noexcept; - using Context = TContext; - using Activation = TActivation; + FFSM2_CONSTEXPR(14) void deepPreUpdate ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) void deepUpdate ( FullControl& control ) noexcept; + FFSM2_CONSTEXPR(14) void deepPostUpdate ( FullControl& control ) noexcept; -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using LoggerInterface = LoggerInterfaceT; -#endif + template + FFSM2_CONSTEXPR(14) void deepPreReact ( FullControl& control, const TEvent& event) noexcept; - static constexpr Long SUBSTITUTION_LIMIT = NSubstitutionLimit; + template + FFSM2_CONSTEXPR(14) void deepReact ( FullControl& control, const TEvent& event) noexcept; -#if FFSM2_PLANS_AVAILABLE() - static constexpr Long TASK_CAPACITY = NTaskCapacity; -#endif + template + FFSM2_CONSTEXPR(14) void deepPostReact ( FullControl& control, const TEvent& event) noexcept; - using Payload = TPayload; - using Transition = TransitionT; + template + FFSM2_CONSTEXPR(14) void deepQuery (ConstControl& control, TEvent& event) const noexcept; #if FFSM2_PLANS_AVAILABLE() - using Task = TaskT; + FFSM2_CONSTEXPR(14) void deepUpdatePlans ( FullControl& control ) noexcept; #endif - /// @brief Set Context type - /// @tparam T Context type for data shared between states and/or data interface between FSM and external code - template - using ContextT = G_; - - /// @brief Select manual activation strategy - using ManualActivation = G_; - -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif + FFSM2_CONSTEXPR(14) bool deepForwardExitGuard (GuardControl& control ) noexcept; + FFSM2_CONSTEXPR(14) bool deepExitGuard (GuardControl& control ) noexcept; - /// @brief Set Substitution limit - /// @tparam N Maximum number times 'guard()' methods can substitute their states for others - template - using SubstitutionLimitN = G_; + FFSM2_CONSTEXPR(14) void deepExit ( PlanControl& control ) noexcept; -#if FFSM2_PLANS_AVAILABLE() + FFSM2_CONSTEXPR(14) void deepChangeToRequested ( PlanControl& control ) noexcept; - /// @brief Set Task capacity - /// @tparam N Maximum number of tasks across all plans - template - using TaskCapacityN = G_; +#if FFSM2_SERIALIZATION_AVAILABLE() + using WriteStream = typename Args::WriteStream; + using ReadStream = typename Args::ReadStream; + FFSM2_CONSTEXPR(14) void deepSaveActive (const Registry& registry, WriteStream& stream) const noexcept; + FFSM2_CONSTEXPR(14) void deepLoadRequested ( Registry& registry, ReadStream& stream) const noexcept; #endif - /// @brief Set Transition Payload type - /// @tparam T Utility type for 'TUtility State::utility() const' method - template - using PayloadT = G_; }; -template -struct M_; +} +} -template -struct M_ > final { - using Cfg = G_; +namespace ffsm2 { +namespace detail { - static constexpr FeatureTag FEATURE_TAG = NFeatureTag; +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif - using Context = TContext; +template +FFSM2_CONSTEXPR(14) +bool +C_::deepForwardEntryGuard(GuardControl& control) noexcept { + const Prong requested = compoRequested(control); + FFSM2_ASSERT(requested < WIDTH); - using Payload = TPayload; - using Transition = TransitionT; + FFSM2_ASSERT(compoActive(control) < WIDTH); -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using LoggerInterface = typename Cfg::LoggerInterface; -#endif + return SubStates::wideEntryGuard(control, requested); +} -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif +template +FFSM2_CONSTEXPR(14) +bool +C_::deepEntryGuard(GuardControl& control) noexcept { + const Prong requested = compoRequested(control); + FFSM2_ASSERT(requested < WIDTH); - /// @brief Root - /// @tparam THead Head state - /// @tparam TSubStates Sub-states - template - using Root = RF_>; + return HeadState::deepEntryGuard(control) || + SubStates::wideEntryGuard(control, requested); +} - /// @brief Headless root - /// @tparam TSubStates Sub-states - template < typename... TSubStates> - using PeerRoot = RF_>; +template +FFSM2_CONSTEXPR(14) +void +C_::deepEnter(PlanControl& control) noexcept { + Prong& requested = compoRequested(control); + Prong& active = compoActive (control); -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif -}; + FFSM2_ASSERT(requested < WIDTH); + FFSM2_ASSERT(active == INVALID_PRONG); + + active = requested; + requested = INVALID_PRONG; + HeadState::deepEnter(control); + SubStates::wideEnter(control, active); } -/// @brief Type configuration for MachineT<> -using Config = detail::G_; +template +FFSM2_CONSTEXPR(14) +void +C_::deepReenter(PlanControl& FFSM2_UNUSED(control)) noexcept { +} -/// @brief 'Template namespace' for FSM classes -/// @tparam TConfig 'ConfigT<>' type configuration for MachineT<> -/// @see ConfigT<> -template -using MachineT = detail::M_; +template +FFSM2_CONSTEXPR(14) +void +C_::deepPreUpdate(FullControl& control) noexcept { + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); -/// @brief 'Template namespace' for FSM classes parametrized with default types -using Machine = MachineT<>; + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); + + ScopedRegion region{control}; + + FFSM2_IF_PLANS(const TaskStatus h =) + HeadState::deepPreUpdate(control); + FFSM2_IF_PLANS(headStatus(control) |= h); + FFSM2_IF_PLANS( subStatus(control) |=) + SubStates::widePreUpdate(control, active); } +template +FFSM2_CONSTEXPR(14) +void +C_::deepUpdate(FullControl& control) noexcept { + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); -namespace ffsm2 { -namespace detail { + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class R_ { -public: - static constexpr FeatureTag FEATURE_TAG = TConfig::FEATURE_TAG; + ScopedRegion region{control}; - using Context = typename TConfig::Context; - using Payload = typename TConfig::Payload; + FFSM2_IF_PLANS(const TaskStatus h =) + HeadState::deepUpdate(control); + FFSM2_IF_PLANS(headStatus(control) |= h); -protected: - using Forward = RF_; - using StateList = typename Forward::StateList; + FFSM2_IF_PLANS( subStatus(control) |=) + SubStates::wideUpdate(control, active); +} - using Args = typename Forward::Args; - using PureContext = typename Args::PureContext; +template +FFSM2_CONSTEXPR(14) +void +C_::deepPostUpdate(FullControl& control) noexcept { + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - static_assert(Args::STATE_COUNT < static_cast(-1), "Too many states in the FSM. Change 'Short' type."); - static_assert(Args::STATE_COUNT == static_cast(StateList::SIZE), "STATE_COUNT != StateList::SIZE"); + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); - using Core = CoreT; + ScopedRegion region{control}; - using Apex = MaterialT<0, Args, TApex>; + FFSM2_IF_PLANS( subStatus (control) |=) + SubStates::widePostUpdate(control, active); - using ConstControl = ConstControlT; - using Control = ControlT ; - using PlanControl = PlanControlT ; - using FullControl = FullControlT ; - using GuardControl = GuardControlT; + FFSM2_IF_PLANS(const TaskStatus h =) + HeadState::deepPostUpdate(control); + FFSM2_IF_PLANS(headStatus (control) |= h); +} - static constexpr Long SUBSTITUTION_LIMIT = Forward::SUBSTITUTION_LIMIT; +template +template +FFSM2_CONSTEXPR(14) +void +C_::deepPreReact(FullControl& control, + const TEvent& event) noexcept +{ + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); -#if FFSM2_PLANS_AVAILABLE() - using PlanData = PlanDataT; -#endif + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); -#if FFSM2_SERIALIZATION_AVAILABLE() - using WriteStream = typename Args::WriteStream; - using ReadStream = typename Args::ReadStream; -#endif + ScopedRegion region{control}; -public: - /// @brief Transition - using Transition = typename Core::Transition; + FFSM2_IF_PLANS(const TaskStatus h =) + HeadState::deepPreReact(control, event); + FFSM2_IF_PLANS(headStatus (control) |= h); -#if FFSM2_PLANS_AVAILABLE() - using CPlan = CPlanT; - using Plan = PlanT; + FFSM2_IF_PLANS( subStatus (control) |=) + SubStates::widePreReact(control, event, active); +} - static constexpr Long TASK_CAPACITY = Forward::TASK_CAPACITY; -#endif +template +template +FFSM2_CONSTEXPR(14) +void +C_::deepReact(FullControl& control, + const TEvent& event) noexcept +{ + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using Logger = typename TConfig::LoggerInterface; -#endif + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); -public: + ScopedRegion region{control}; - FFSM2_CONSTEXPR(11) explicit R_(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + FFSM2_IF_PLANS(const TaskStatus h =) + HeadState:: deepReact(control, event); + FFSM2_IF_PLANS(headStatus(control) |= h); - FFSM2_CONSTEXPR(11) explicit R_(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + FFSM2_IF_PLANS( subStatus(control) |=) + SubStates:: wideReact(control, event, active); +} - FFSM2_CONSTEXPR(NO) R_(const R_& ) noexcept = default; - FFSM2_CONSTEXPR(NO) R_( R_&&) noexcept = default; +template +template +FFSM2_CONSTEXPR(14) +void +C_::deepPostReact(FullControl& control, + const TEvent& event) noexcept +{ + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - FFSM2_CONSTEXPR(20) ~R_() noexcept; + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); - /// @brief Access context - /// @return context - FFSM2_CONSTEXPR(14) Context& context() noexcept { return _core.context; } + ScopedRegion region{control}; - /// @brief Access context - /// @return context - FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } + FFSM2_IF_PLANS( subStatus (control) |=) + SubStates::widePostReact(control, event, active); - /// @brief Get state identifier for a state type - /// @tparam TState State type - /// @return Numeric state identifier - template - static constexpr StateID stateId() noexcept { return index(); } + FFSM2_IF_PLANS(const TaskStatus h =) + HeadState::deepPostReact(control, event); + FFSM2_IF_PLANS(headStatus (control) |= h); +} - /// @brief Access state instance - /// @tparam TState State type - /// @return State instance - template - FFSM2_CONSTEXPR(14) TState& access() noexcept { return static_cast< TState&>(_apex); } +template +template +FFSM2_CONSTEXPR(14) +void +C_::deepQuery(ConstControl& control, + TEvent& event) const noexcept +{ + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); - /// @brief Access state instance - /// @tparam TState State type - /// @return State instance - template - FFSM2_CONSTEXPR(11) const TState& access() const noexcept { return static_cast(_apex); } + HeadState::deepQuery(control, event); + SubStates::wideQuery(control, event, active); +} - /// @brief Trigger FSM update cycle (recursively call 'update()' from the root down to the leaf states, - /// on all active states, then process requested transitions) - FFSM2_CONSTEXPR(14) void update() noexcept; +#if FFSM2_PLANS_AVAILABLE() - /// @brief Have FSM react to an event (recursively call matching 'react<>()' from the root down to the leaf states, - /// on all active states, then process requested transitions) - /// @tparam TEvent Event type - /// @param event Event to react to - template - FFSM2_CONSTEXPR(14) void react(const TEvent& event) noexcept; +template +FFSM2_CONSTEXPR(14) +void +C_::deepUpdatePlans(FullControl& control) noexcept { + FFSM2_ASSERT(compoRequested(control) == INVALID_PRONG); - /// @brief Recursively call 'query()' from the root down to the leaf states, on all active states - /// @tparam TEvent Event type - /// @param event Event to react to - template - FFSM2_CONSTEXPR(14) void query(TEvent& event) const noexcept; + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); - /// @brief Get current active state ID - /// @return Current active state ID - FFSM2_CONSTEXPR(11) StateID activeStateId() const noexcept { return _core.registry.active; } + const TaskStatus s = subStatus(control) | + SubStates::wideUpdatePlans (control, active); - /// @brief Check if a state is active - /// @param stateId Destination state identifier - /// @return State active status - FFSM2_CONSTEXPR(11) bool isActive(const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } + const bool planExists = control._core.planData.planExists; - /// @brief Check if a state is active - /// @tparam TState Destination state type - /// @return State active status - template - FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return _core.registry.active == stateId(); } + if (s && planExists) + control.updatePlan(static_cast(*this), s); +} -#if FFSM2_PLANS_AVAILABLE() +#endif - /// @brief Access plan - /// @return Plan - FFSM2_CONSTEXPR(14) Plan plan() noexcept { return Plan{_core.planData}; } +template +FFSM2_CONSTEXPR(14) +bool +C_::deepForwardExitGuard(GuardControl& control) noexcept { + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); - /// @brief Access read-only plan - /// @return Read-only plan - FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } + FFSM2_ASSERT(compoRequested(control) < WIDTH); - /// @brief Succeed a plan task for a state - /// @param stateId state ID - FFSM2_CONSTEXPR(14) void succeed(const StateID stateId_) noexcept; + return SubStates::wideExitGuard(control, active); +} - /// @brief Succeed a plan task for a state - /// @tparam TState state type - template - FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed(stateId()); } +template +FFSM2_CONSTEXPR(14) +bool +C_::deepExitGuard(GuardControl& control) noexcept { + const Prong active = compoActive(control); + FFSM2_ASSERT(active < WIDTH); - /// @brief Fail a plan task for a state - /// @param stateId state ID - FFSM2_CONSTEXPR(14) void fail (const StateID stateId_) noexcept; + FFSM2_ASSERT(compoRequested(control) < WIDTH); - /// @brief Fail a plan task for a state - /// @tparam TState state type - template - FFSM2_CONSTEXPR(14) void fail () noexcept { fail (stateId()); } + return HeadState::deepExitGuard(control) || + SubStates::wideExitGuard(control, active); +} -#endif +template +FFSM2_CONSTEXPR(14) +void +C_::deepExit(PlanControl& control) noexcept { + Prong& active = compoActive (control); + FFSM2_ASSERT(active < WIDTH); - /// @brief Queue a transition into a state (takes effect during immediate*(), update() or react()) - /// @param stateId Destination state identifier - FFSM2_CONSTEXPR(14) void changeTo (const StateID stateId_) noexcept; + SubStates::wideExit(control, active); + HeadState::deepExit(control); - /// @brief Queue a transition into a state (takes effect during immediate*(), update() or react()) - /// @tparam TState Destination state type - template - FFSM2_CONSTEXPR(14) void changeTo () noexcept { changeTo (stateId()); } + active = INVALID_PRONG; -#if FFSM2_UTILITY_THEORY_AVAILABLE() +#if FFSM2_PLANS_AVAILABLE() + Plan plan = control.plan(); + plan.clear(); #endif +} - /// @brief Transition into a state - /// (if transitioning into a region, acts depending on the region type) - /// @param stateId Destination state identifier - FFSM2_CONSTEXPR(14) void immediateChangeTo (const StateID stateId_) noexcept; - - /// @brief Transition into a state (if transitioning into a region, acts depending on the region type) - /// @tparam TState Destination state type - template - FFSM2_CONSTEXPR(14) void immediateChangeTo () noexcept { immediateChangeTo (stateId()); } +template +FFSM2_CONSTEXPR(14) +void +C_::deepChangeToRequested(PlanControl& control) noexcept { + Prong& requested = compoRequested(control); + Prong& active = compoActive (control); -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + FFSM2_ASSERT(active < WIDTH); - /// @brief Get the transition recorded during last 'update()' / 'react()' - /// @return Array of last recorded transitions - /// @see FFSM2_ENABLE_TRANSITION_HISTORY - FFSM2_CONSTEXPR(11) const Transition& previousTransition() const noexcept { return _core.previousTransition; } + FFSM2_ASSERT(requested < WIDTH); - /// @brief Force process a transition (skips 'guard()' calls) - /// Can be used to synchronize multiple FSMs - /// @param destination Transition destination - /// @return Success status - /// @see FFSM2_ENABLE_TRANSITION_HISTORY - FFSM2_CONSTEXPR(14) bool replayTransition(const StateID destination) noexcept; + if (requested != active) { + SubStates::wideExit (control, active); -#endif + active = requested; + requested = INVALID_PRONG; -#if FFSM2_LOG_INTERFACE_AVAILABLE() + SubStates::wideEnter (control, active); + } else { + requested = INVALID_PRONG; - /// @brief Attach logger - /// @param logger A logger implementing 'ffsm2::LoggerInterfaceT<>' interface - /// @see FFSM2_ENABLE_LOG_INTERFACE - FFSM2_CONSTEXPR(14) void attachLogger(Logger* const logger) noexcept { _core.logger = logger; } + // reconstruction done in S_::reenter() + SubStates::wideReenter(control, active); + } +} -#endif +#if FFSM2_SERIALIZATION_AVAILABLE() -protected: - FFSM2_CONSTEXPR(14) void initialEnter() noexcept; - FFSM2_CONSTEXPR(14) void finalExit() noexcept; +template +FFSM2_CONSTEXPR(14) +void +C_::deepSaveActive(const Registry& registry, + WriteStream& stream) const noexcept +{ + stream.template write(registry.active); +} - FFSM2_CONSTEXPR(14) void processRequest() noexcept; - FFSM2_CONSTEXPR(14) void processTransitions(Transition& currentTransition) noexcept; +template +FFSM2_CONSTEXPR(14) +void +C_::deepLoadRequested(Registry& registry, + ReadStream& stream) const noexcept +{ + Prong& requested = compoRequested(registry); - FFSM2_CONSTEXPR(14) bool applyRequest(const Transition& currentTransition, - const StateID destination) noexcept; + requested = stream.template read(); + FFSM2_ASSERT(requested < WIDTH); +} - FFSM2_CONSTEXPR(14) bool cancelledByEntryGuards(const Transition& currentTransition, - const Transition& pendingTransition) noexcept; +#endif - FFSM2_CONSTEXPR(14) bool cancelledByGuards(const Transition& currentTransition, - const Transition& pendingTransition) noexcept; +} +} -#if FFSM2_SERIALIZATION_AVAILABLE() - FFSM2_CONSTEXPR(14) void save(WriteStream& stream) const noexcept; - FFSM2_CONSTEXPR(14) void load( ReadStream& stream) noexcept; -#endif +namespace ffsm2 { +namespace detail { -protected: - Core _core; - Apex _apex; -}; +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload +> +struct G_ final { + static constexpr FeatureTag FEATURE_TAG = NFeatureTag; -// Automatic / manual [de]activation + using Context = TContext; + using Activation = TActivation; -template -class RV_; +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using LoggerInterface = LoggerInterfaceT; +#endif -// Automatic enter() / exit() + static constexpr Short SUBSTITUTION_LIMIT = NSubstitutionLimit; -template -class RV_ , TApex> - : public R_, TApex> -{ - using Base = R_, TApex>; +#if FFSM2_PLANS_AVAILABLE() + static constexpr Long TASK_CAPACITY = NTaskCapacity; +#endif -protected: - using typename Base::Context; - using typename Base::PureContext; + using Payload = TPayload; + using Transition = TransitionT; -#if FFSM2_SERIALIZATION_AVAILABLE() - using typename Base::Args; - using typename Base::WriteStream; - using typename Base::ReadStream; +#if FFSM2_PLANS_AVAILABLE() + using Task = TaskT; #endif -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; + /// @brief Set Context type + /// @tparam T Context type for data shared between states and/or data interface between FSM and external code + template + using ContextT = G_; + + /// @brief Select manual activation strategy + using ManualActivation = G_; + +#if FFSM2_UTILITY_THEORY_AVAILABLE() #endif -public: - FFSM2_CONSTEXPR(14) explicit RV_(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + /// @brief Set Substitution limit + /// @tparam N Maximum number times 'guard()' methods can substitute their states for others + template + using SubstitutionLimitN = G_; - FFSM2_CONSTEXPR(14) explicit RV_(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; +#if FFSM2_PLANS_AVAILABLE() - FFSM2_CONSTEXPR(14) RV_(const RV_& other) noexcept; - FFSM2_CONSTEXPR(14) RV_( RV_&& other) noexcept; + /// @brief Set Task capacity + /// @tparam N Maximum number of tasks across all plans + template + using TaskCapacityN = G_; - FFSM2_CONSTEXPR(20) ~RV_() noexcept; +#endif -#if FFSM2_SERIALIZATION_AVAILABLE() + /// @brief Set Transition Payload type + /// @tparam T Utility type for 'TUtility State::utility() const' method + template + using PayloadT = G_; +}; - /// @brief Buffer for serialization - /// @see `FFSM2_ENABLE_SERIALIZATION` - using SerialBuffer = typename Args::SerialBuffer; +template +struct M_; - /// @brief Serialize FSM into 'buffer' - /// @param buffer `SerialBuffer` to serialize to - /// @see `FFSM2_ENABLE_SERIALIZATION` - FFSM2_CONSTEXPR(14) void save( SerialBuffer& buffer) const noexcept; +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload +> +struct M_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + > final +{ + using Cfg = G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + >; - /// @brief De-serialize FSM from 'buffer' - /// @param buffer `SerialBuffer` to de-serialize from - /// @see `FFSM2_ENABLE_SERIALIZATION` - FFSM2_CONSTEXPR(14) void load(const SerialBuffer& buffer) noexcept; + static constexpr FeatureTag FEATURE_TAG = NFeatureTag; + + using Context = TContext; + using Payload = TPayload; + using Transition = TransitionT; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using LoggerInterface = typename Cfg::LoggerInterface; #endif -private: -#if FFSM2_SERIALIZATION_AVAILABLE() - using Base::save; - using Base::load; +#if FFSM2_UTILITY_THEORY_AVAILABLE() #endif -private: - using Base::initialEnter; - using Base::finalExit; + /// @brief Root + /// @tparam THead Head state + /// @tparam TSubStates Sub-states + template + using Root = RF_>; -protected: -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - using Base::_core; - using Base::_apex; + /// @brief Headless root + /// @tparam TSubStates Sub-states + template < typename... TSubStates> + using PeerRoot = RF_>; + +#if FFSM2_UTILITY_THEORY_AVAILABLE() #endif }; -// Manual enter() / exit() +} -template -class RV_ , TApex> - : public R_, TApex> -{ - using Base = R_, TApex>; +/// @brief Type configuration for MachineT<> +using Config = detail::G_< + FFSM2_FEATURE_TAG + , EmptyContext + , Automatic + , 4 + FFSM2_IF_PLANS(, INVALID_LONG) + , void + >; -protected: -#if FFSM2_SERIALIZATION_AVAILABLE() - using typename Base::PlanControl; +/// @brief 'Template namespace' for FSM classes +/// @tparam TConfig 'ConfigT<>' type configuration for MachineT<> +/// @see ConfigT<> +template +using MachineT = detail::M_; - using typename Base::Args; - using typename Base::WriteStream; - using typename Base::ReadStream; -#endif +/// @brief 'Template namespace' for FSM classes parametrized with default types +using Machine = MachineT<>; -public: - using typename Base::Transition; +} -private: -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - using typename Base::PlanControl; -#endif +namespace ffsm2 { +namespace detail { +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + typename TConfig + , typename TApex +> +class R_ { public: - using Base::Base; - - /// @brief Check if FSM is active - /// @return FSM active status - FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return _core.registry.isActive(); } - - using Base::isActive; - - /// @brief Manually start the FSM - /// Can be used with UE4 to start / stop the FSM in BeginPlay() / EndPlay() - FFSM2_CONSTEXPR(14) void enter() noexcept { initialEnter(); } + static constexpr FeatureTag FEATURE_TAG = TConfig::FEATURE_TAG; - /// @brief Manually stop the FSM - /// Can be used with UE4 to start / stop the FSM in BeginPlay() / EndPlay() - FFSM2_CONSTEXPR(14) void exit() noexcept { finalExit(); } + using Context = typename TConfig::Context; + using Payload = typename TConfig::Payload; -#if FFSM2_SERIALIZATION_AVAILABLE() +protected: + using Forward = RF_; + using StateList = typename Forward::StateList; - /// @brief Buffer for serialization - /// @see `FFSM2_ENABLE_SERIALIZATION` - using SerialBuffer = typename Args::SerialBuffer; + using Args = typename Forward::Args; + using PureContext = typename Args::PureContext; - /// @brief Serialize FSM into 'buffer' - /// @param buffer `SerialBuffer` to serialize to - /// @see `FFSM2_ENABLE_SERIALIZATION` - FFSM2_CONSTEXPR(14) void save( SerialBuffer& buffer) const noexcept; + static_assert(Args::STATE_COUNT < static_cast(-1), "Too many states in the FSM. Change 'Short' type."); + static_assert(Args::STATE_COUNT == static_cast(StateList::SIZE), "STATE_COUNT != StateList::SIZE"); - /// @brief De-serialize FSM from 'buffer' - /// @param buffer `SerialBuffer` to de-serialize from - /// @see `FFSM2_ENABLE_SERIALIZATION` - FFSM2_CONSTEXPR(14) void load(const SerialBuffer& buffer) noexcept; + using Core = CoreT; -#endif + using Apex = MaterialT<0, Args, TApex>; -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + using ConstControl = ConstControlT; + using Control = ControlT ; + using PlanControl = PlanControlT ; + using FullControl = FullControlT ; + using GuardControl = GuardControlT; - /// @brief Start the FSM from a specific state - /// Can be used with UE4 USTRUCT() NetSerialize() to load replicated FSM from FArchive - /// @param destination Transition destination - /// @see FFSM2_ENABLE_TRANSITION_HISTORY - FFSM2_CONSTEXPR(14) void replayEnter(const StateID destination) noexcept; + static constexpr Short SUBSTITUTION_LIMIT = Forward::SUBSTITUTION_LIMIT; +#if FFSM2_PLANS_AVAILABLE() + using PlanData = PlanDataT; #endif -private: +public: #if FFSM2_SERIALIZATION_AVAILABLE() - using Base::save; - using Base::load; - - FFSM2_CONSTEXPR(14) void loadEnter(ReadStream& stream) noexcept; + using WriteStream = typename Args::WriteStream; + using ReadStream = typename Args::ReadStream; #endif -protected: - using Base::initialEnter; - using Base::finalExit; +public: + /// @brief Transition + using Transition = typename Core::Transition; - using Base::_core; +#if FFSM2_PLANS_AVAILABLE() + using CPlan = CPlanT; + using Plan = PayloadPlanT; -#if FFSM2_SERIALIZATION_AVAILABLE() || FFSM2_TRANSITION_HISTORY_AVAILABLE() - using Base::_apex; + static constexpr Long TASK_CAPACITY = Forward::TASK_CAPACITY; #endif -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - using Base::applyRequest; +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using Logger = typename TConfig::LoggerInterface; #endif -}; -template -class RP_; +public: -// Non-'void' payloads + FFSM2_CONSTEXPR(11) explicit R_(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; -template -class RP_ , TApex> - : public RV_, TApex> -{ - using Base = RV_, TApex>; + FFSM2_CONSTEXPR(11) explicit R_(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; - using Transition = TransitionT; + FFSM2_CONSTEXPR(NO) R_(const R_& ) noexcept = default; + FFSM2_CONSTEXPR(NO) R_( R_&&) noexcept = default; -public: - using typename Base::Payload; + FFSM2_CONSTEXPR(20) ~R_() noexcept; -public: - using Base::Base; - using Base::processRequest; + /// @brief Access context + /// @return context + FFSM2_CONSTEXPR(14) Context& context() noexcept { return _core.context; } + + /// @brief Access context + /// @return context + FFSM2_CONSTEXPR(11) const Context& context() const noexcept { return _core.context; } /// @brief Get state identifier for a state type - /// @tparam TState State type + /// @tparam `TState` State type /// @return Numeric state identifier template - static constexpr StateID stateId() noexcept { return Base::template stateId(); } - - /// @brief Transition into a state - /// @param stateId Destination state identifier - /// @param payload Payload - FFSM2_CONSTEXPR(14) void changeWith (const StateID stateId_, - const Payload& payload) noexcept; + static + FFSM2_CONSTEXPR(11) StateID stateId() noexcept { return index() ; } - /// @brief Transition into a state - /// @tparam TState Destination state type - /// @param payload Payload + /// @brief Access state instance + /// @tparam `TState` State type + /// @return State instance template - FFSM2_CONSTEXPR(14) void changeWith (const Payload& payload) noexcept { changeWith(stateId(), payload ); } - - /// @brief Transition into a state (if transitioning into a region, acts depending on the region type) - /// @param stateId Destination state identifier - /// @param payload Payload - FFSM2_CONSTEXPR(14) void immediateChangeWith (const StateID stateId_, - const Payload& payload) noexcept; + FFSM2_CONSTEXPR(14) TState& access() noexcept { return static_cast< TState&>(_apex); } - /// @brief Transition into a state (if transitioning into a region, acts depending on the region type) - /// @tparam TState Destination state type - /// @param payload Payload + /// @brief Access state instance + /// @tparam `TState` State type + /// @return State instance template - FFSM2_CONSTEXPR(14) void immediateChangeWith (const Payload& payload) noexcept { immediateChangeWith (stateId(), payload ); } + FFSM2_CONSTEXPR(11) const TState& access() const noexcept { return static_cast(_apex); } -#if FFSM2_UTILITY_THEORY_AVAILABLE() -#endif - -protected: - using Base::_core; -}; - -template -class RP_ , TApex> - : public RV_, TApex> -{ - using Base = RV_, TApex>; + /// @brief Trigger FSM update cycle (recursively call `update()` from the root down to the leaf states + /// on all active states then process requested transitions) + FFSM2_CONSTEXPR(14) void update() noexcept; -public: - using Base::Base; -}; - -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class InstanceT; + /// @brief Have FSM react to an event (recursively call matching 'react<>()' from the root down to the leaf states + /// on all active states then process requested transitions) + /// @tparam `TEvent` Event type + /// @param `event` Event to react to + template + FFSM2_CONSTEXPR(14) void react(const TEvent& event) noexcept; -// TContext + /// @brief Recursively call 'query()' from the root down to the leaf states on all active states + /// @tparam `TEvent` Event type + /// @param `event` Event to react to + template + FFSM2_CONSTEXPR(14) void query(TEvent& event) const noexcept; -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class InstanceT , TApex> final - : public RP_, TApex> -{ - using Base = RP_, TApex>; + /// @brief Get current active state ID + /// @return Current active state ID + FFSM2_CONSTEXPR(11) StateID activeStateId() const noexcept { return _core.registry.active; } -public: - static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + /// @brief Check if a state is active + /// @param `stateId` Destination state identifier + /// @return State active status + FFSM2_CONSTEXPR(11) bool isActive(const StateID stateId_) const noexcept { return _core.registry.active == stateId_; } - using typename Base::Context; - using typename Base::PureContext; + /// @brief Check if a state is active + /// @tparam `TState` Destination state type + /// @return State active status + template + FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return _core.registry.active == stateId(); } -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; -#endif +#if FFSM2_PLANS_AVAILABLE() -public: - FFSM2_CONSTEXPR(11) explicit InstanceT(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + /// @brief Access plan + /// @return Plan + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) Plan plan() noexcept { return Plan{_core.planData}; } - FFSM2_CONSTEXPR(11) explicit InstanceT(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + /// @brief Access read-only plan + /// @return Read-only plan + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(11) CPlan plan() const noexcept { return CPlan{_core.planData}; } - FFSM2_CONSTEXPR(NO) InstanceT(const InstanceT& ) noexcept = default; - FFSM2_CONSTEXPR(NO) InstanceT( InstanceT&&) noexcept = default; + /// @brief Succeed a plan task for a state + /// @param `stateId` State identifier + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void succeed(const StateID stateId_) noexcept; -private: - using Base::_core; -}; + /// @brief Succeed a plan task for a state + /// @tparam `TState` State type + /// @see `FFSM2_ENABLE_PLANS` + template + FFSM2_CONSTEXPR(14) void succeed() noexcept { succeed(stateId()); } -// TContext& + /// @brief Fail a plan task for a state + /// @param `stateId` State identifier + /// @see `FFSM2_ENABLE_PLANS` + FFSM2_CONSTEXPR(14) void fail (const StateID stateId_) noexcept; -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class InstanceT , TApex> final - : public RP_, TApex> -{ - using Base = RP_, TApex>; + /// @brief Fail a plan task for a state + /// @tparam `TState` State type + /// @see `FFSM2_ENABLE_PLANS` + template + FFSM2_CONSTEXPR(14) void fail () noexcept { fail (stateId()); } -public: - static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; +#endif - using typename Base::Context; + /// @brief Queue a transition into a state (takes effect during `immediate*()`, `update()` or `react()`) + /// @param `stateId` Destination state identifier + /// @see `immediateChangeTo()` + FFSM2_CONSTEXPR(14) void changeTo (const StateID stateId_) noexcept; -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; + /// @brief Queue a transition into a state (takes effect during `immediate*()`, `update()` or `react()`) + /// @tparam `TState` Destination state type + /// @see `immediateChangeTo()` + template + FFSM2_CONSTEXPR(14) void changeTo () noexcept { changeTo (stateId()); } + +#if FFSM2_UTILITY_THEORY_AVAILABLE() #endif -public: - using Base::Base; + /// @brief Transition into a state + /// (if transitioning into a region, acts depending on the region type) + /// @param `stateId` Destination state identifier + /// @see `changeTo()` + FFSM2_CONSTEXPR(14) void immediateChangeTo (const StateID stateId_) noexcept; -private: - using Base::_core; -}; + /// @brief Transition into a state + /// @tparam `TState` Destination state type + /// @see `changeTo()` + template + FFSM2_CONSTEXPR(14) void immediateChangeTo () noexcept { immediateChangeTo (stateId()); } -// TContext* +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class InstanceT , TApex> final - : public RP_, TApex> -{ - using Base = RP_, TApex>; + /// @brief Get the transition recorded during last `update()` / `react()` + /// @return Array of last recorded transitions + /// @see FFSM2_ENABLE_TRANSITION_HISTORY + FFSM2_CONSTEXPR(11) const Transition& previousTransition() const noexcept { return _core.previousTransition; } -public: - static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + /// @brief Force process a transition (skips `guard()` calls) + /// Can be used to synchronize multiple FSMs + /// @param `transition` 'Transition' to replay + /// @return Success status + /// @see FFSM2_ENABLE_TRANSITION_HISTORY + FFSM2_CONSTEXPR(14) bool replayTransition(const StateID destination) noexcept; - using typename Base::Context; +#endif #if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; -#endif -public: - FFSM2_CONSTEXPR(11) explicit InstanceT(Context context = nullptr - FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + /// @brief Attach logger + /// @param `logger` A logger implementing 'ffsm2::LoggerInterfaceT<>' interface + /// @see FFSM2_ENABLE_LOG_INTERFACE + FFSM2_CONSTEXPR(14) void attachLogger(Logger* const logger) noexcept { _core.logger = logger; } - FFSM2_CONSTEXPR(NO) InstanceT(const InstanceT& ) noexcept = default; - FFSM2_CONSTEXPR(NO) InstanceT( InstanceT&&) noexcept = default; +#endif - FFSM2_CONSTEXPR(14) void setContext(Context context) noexcept { _core.context = context; } +protected: + FFSM2_CONSTEXPR(14) void initialEnter() noexcept; + FFSM2_CONSTEXPR(14) void finalExit() noexcept; -private: - using Base::_core; -}; + FFSM2_CONSTEXPR(14) void processRequest() noexcept; + FFSM2_CONSTEXPR(14) void processTransitions(Transition& currentTransition) noexcept; -// TContext == EmptyContext + FFSM2_CONSTEXPR(14) bool applyRequest(const Transition& currentTransition, + const StateID destination) noexcept; -/// @brief FSM Root -/// @tparam Cfg Type configuration -/// @tparam TApex Root region type -template -class FFSM2_EMPTY_BASES InstanceT, TApex> final - : public RP_, TApex> - , EmptyContext -{ - using Base = RP_, TApex>; + FFSM2_CONSTEXPR(14) bool cancelledByEntryGuards(const Transition& currentTransition, + const Transition& pendingTransition) noexcept; -public: - static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + FFSM2_CONSTEXPR(14) bool cancelledByGuards(const Transition& currentTransition, + const Transition& pendingTransition) noexcept; -#if FFSM2_LOG_INTERFACE_AVAILABLE() - using typename Base::Logger; +#if FFSM2_SERIALIZATION_AVAILABLE() + FFSM2_CONSTEXPR(14) void save(WriteStream& stream) const noexcept; + FFSM2_CONSTEXPR(14) void load( ReadStream& stream) noexcept; #endif -public: - FFSM2_CONSTEXPR(11) explicit InstanceT(FFSM2_IF_LOG_INTERFACE(Logger* const logger = nullptr)) noexcept; - - using Base::Base; +protected: + Core _core; + Apex _apex; }; } } - namespace ffsm2 { namespace detail { -template +template FFSM2_CONSTEXPR(11) -R_::R_(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept +R_::R_(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept : _core{context FFSM2_IF_LOG_INTERFACE(, logger)} {} -template +template FFSM2_CONSTEXPR(11) -R_::R_(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept +R_::R_(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept : _core{move(context) FFSM2_IF_LOG_INTERFACE(, logger)} {} -template +template FFSM2_CONSTEXPR(20) -R_::~R_() noexcept { +R_::~R_() noexcept { FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); } -template +template FFSM2_CONSTEXPR(14) void -R_::update() noexcept { +R_::update() noexcept { FFSM2_ASSERT(_core.registry.isActive()); Transition emptyTransition; @@ -6757,11 +6900,11 @@ R_::update() noexcept { processRequest(); } -template +template template FFSM2_CONSTEXPR(14) void -R_::react(const TEvent& event) noexcept { +R_::react(const TEvent& event) noexcept { FFSM2_ASSERT(_core.registry.isActive()); Transition emptyTransition; @@ -6779,11 +6922,11 @@ R_::react(const TEvent& event) noexcept { processRequest(); } -template +template template FFSM2_CONSTEXPR(14) void -R_::query(TEvent& event) const noexcept { +R_::query(TEvent& event) const noexcept { FFSM2_ASSERT(_core.registry.isActive()); ConstControl control{_core}; @@ -6793,19 +6936,19 @@ R_::query(TEvent& event) const noexcept { #if FFSM2_PLANS_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -R_::succeed(const StateID stateId_) noexcept { +R_::succeed(const StateID stateId_) noexcept { _core.planData.tasksSuccesses.set(stateId_); FFSM2_LOG_TASK_STATUS(_core.context, stateId_, StatusEvent::SUCCEEDED); } -template +template FFSM2_CONSTEXPR(14) void -R_::fail(const StateID stateId_) noexcept { +R_::fail(const StateID stateId_) noexcept { _core.planData.tasksFailures.set(stateId_); FFSM2_LOG_TASK_STATUS(_core.context, stateId_, StatusEvent::FAILED); @@ -6813,10 +6956,10 @@ R_::fail(const StateID stateId_) noexcept { #endif -template +template FFSM2_CONSTEXPR(14) void -R_::changeTo(const StateID stateId_) noexcept { +R_::changeTo(const StateID stateId_) noexcept { FFSM2_ASSERT(_core.registry.isActive()); _core.request = Transition{stateId_}; @@ -6824,10 +6967,10 @@ R_::changeTo(const StateID stateId_) noexcept { FFSM2_LOG_TRANSITION(_core.context, INVALID_STATE_ID, stateId_); } -template +template FFSM2_CONSTEXPR(14) void -R_::immediateChangeTo(const StateID stateId_) noexcept { +R_::immediateChangeTo(const StateID stateId_) noexcept { changeTo(stateId_); processRequest(); @@ -6835,10 +6978,10 @@ R_::immediateChangeTo(const StateID stateId_) noexcept { #if FFSM2_TRANSITION_HISTORY_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) bool -R_::replayTransition(const StateID destination) noexcept { +R_::replayTransition(const StateID destination) noexcept { FFSM2_ASSERT(_core.registry.isActive()); _core.previousTransition.clear(); @@ -6866,10 +7009,10 @@ R_::replayTransition(const StateID destination) noexcept { #endif -template +template FFSM2_CONSTEXPR(14) void -R_::initialEnter() noexcept { +R_::initialEnter() noexcept { FFSM2_ASSERT(!_core.registry.isActive()); FFSM2_ASSERT(!_core.request); FFSM2_IF_TRANSITION_HISTORY(FFSM2_ASSERT(!_core.previousTransition)); @@ -6915,10 +7058,10 @@ R_::initialEnter() noexcept { FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); } -template +template FFSM2_CONSTEXPR(14) void -R_::finalExit() noexcept { +R_::finalExit() noexcept { FFSM2_ASSERT(_core.registry.isActive()); FFSM2_ASSERT(!_core.request); @@ -6939,10 +7082,10 @@ R_::finalExit() noexcept { #endif } -template +template FFSM2_CONSTEXPR(14) void -R_::processRequest() noexcept { +R_::processRequest() noexcept { FFSM2_IF_ASSERT(FFSM2_IF_PLANS(_core.planData.verifyPlans())); Transition currentTransition; @@ -6956,10 +7099,10 @@ R_::processRequest() noexcept { FFSM2_IF_TRANSITION_HISTORY(_core.previousTransition = currentTransition); } -template +template FFSM2_CONSTEXPR(14) void -R_::processTransitions(Transition& currentTransition) noexcept { +R_::processTransitions(Transition& currentTransition) noexcept { FFSM2_ASSERT(_core.request); PlanControl control{_core, currentTransition}; @@ -6996,11 +7139,11 @@ R_::processTransitions(Transition& currentTransition) noexcept { _core.registry.clearRequests(); } -template +template FFSM2_CONSTEXPR(14) bool -R_::applyRequest(const Transition& currentTransition, - const StateID destination) noexcept +R_::applyRequest(const Transition& currentTransition, + const StateID destination) noexcept { if (currentTransition != Transition{destination}) { _core.registry.requested = destination; @@ -7010,11 +7153,11 @@ R_::applyRequest(const Transition& currentTransition, return false; } -template +template FFSM2_CONSTEXPR(14) bool -R_::cancelledByEntryGuards(const Transition& currentTransition, - const Transition& pendingTransition) noexcept +R_::cancelledByEntryGuards(const Transition& currentTransition, + const Transition& pendingTransition) noexcept { GuardControl guardControl{_core , currentTransition @@ -7023,11 +7166,11 @@ R_::cancelledByEntryGuards(const Transition& currentTransition, return _apex.deepEntryGuard(guardControl); } -template +template FFSM2_CONSTEXPR(14) bool -R_::cancelledByGuards(const Transition& currentTransition, - const Transition& pendingTransition) noexcept +R_::cancelledByGuards(const Transition& currentTransition, + const Transition& pendingTransition) noexcept { GuardControl guardControl{_core , currentTransition @@ -7039,123 +7182,379 @@ R_::cancelledByGuards(const Transition& currentTransition, #if FFSM2_SERIALIZATION_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -R_::save(WriteStream& stream) const noexcept { +R_::save(WriteStream& stream) const noexcept { FFSM2_ASSERT(_core.registry.isActive()); _apex.deepSaveActive(_core.registry, stream); // TODO: save(stream, _core.requests); -#if FFSM2_PLANS_AVAILABLE() - // TODO: save(stream, _core.planData); -#endif +#if FFSM2_PLANS_AVAILABLE() + // TODO: save(stream, _core.planData); +#endif + +#if FFSM2_UTILITY_THEORY_AVAILABLE() + // TODO: save(stream, _core.rng); +#endif + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + // TODO: save(stream, _core.transitionTarget); + // TODO: save(stream, _core.previousTransition); +#endif +} + +template +FFSM2_CONSTEXPR(14) +void +R_::load(ReadStream& stream) noexcept { + FFSM2_ASSERT(_core.registry.isActive()); + + _core.registry.clearRequests(); + _apex.deepLoadRequested(_core.registry, stream); + + _core.request.clear(); + // TODO: load(stream, _core.requests); + +#if FFSM2_PLANS_AVAILABLE() + _core.planData.clear(); + // TODO: load(stream, _core.planData); +#endif + +#if FFSM2_UTILITY_THEORY_AVAILABLE() + // TODO: load(stream, _core.rng); +#endif + +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + _core.previousTransition.clear(); +#endif + + Transition emptyTransition; + PlanControl control{_core, emptyTransition}; + + _apex.deepChangeToRequested(control); +} + +#endif + +#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#endif + +#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#endif + +} +} + +namespace ffsm2 { +namespace detail { + +// Automatic / manual [de]activation + +template < + typename + , typename +> +class RV_; + +// Automatic enter() / exit() + +template < + FeatureTag NFeatureTag + , typename TContext + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES RV_< + G_< + NFeatureTag + , TContext + , Automatic + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > + : public R_ < + G_< + NFeatureTag + , TContext + , Automatic + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = R_ < + G_< + NFeatureTag + , TContext + , Automatic + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +protected: + using typename Base::Context; + using typename Base::PureContext; + +#if FFSM2_SERIALIZATION_AVAILABLE() + using typename Base::Args; + using typename Base::WriteStream; + using typename Base::ReadStream; +#endif + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + FFSM2_CONSTEXPR(14) explicit RV_(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(14) explicit RV_(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(14) RV_(const RV_& other) noexcept; + FFSM2_CONSTEXPR(14) RV_( RV_&& other) noexcept; + + FFSM2_CONSTEXPR(20) ~RV_() noexcept; + +#if FFSM2_SERIALIZATION_AVAILABLE() + + /// @brief Buffer for serialization + /// @see `FFSM2_ENABLE_SERIALIZATION` + using SerialBuffer = typename Args::SerialBuffer; + + /// @brief Serialize FSM into 'buffer' + /// @param buffer `SerialBuffer` to serialize to + /// @see `FFSM2_ENABLE_SERIALIZATION` + FFSM2_CONSTEXPR(14) void save( SerialBuffer& buffer) const noexcept; + + /// @brief De-serialize FSM from 'buffer' + /// @param buffer `SerialBuffer` to de-serialize from + /// @see `FFSM2_ENABLE_SERIALIZATION` + FFSM2_CONSTEXPR(14) void load(const SerialBuffer& buffer) noexcept; + +#endif + +private: +#if FFSM2_SERIALIZATION_AVAILABLE() + using Base::save; + using Base::load; +#endif + +private: + using Base::initialEnter; + using Base::finalExit; + +protected: +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + using Base::_core; + using Base::_apex; +#endif +}; + +// Manual enter() / exit() + +template < + FeatureTag NFeatureTag + , typename TContext + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES RV_< + G_< + NFeatureTag + , TContext + , Manual + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > + : public R_< + G_< + NFeatureTag + , TContext + , Manual + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = R_< + G_< + NFeatureTag + , TContext + , Manual + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +protected: +#if FFSM2_SERIALIZATION_AVAILABLE() + using typename Base::PlanControl; + + using typename Base::Args; + using typename Base::WriteStream; + using typename Base::ReadStream; +#endif + +public: + using typename Base::Transition; + +private: +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + using typename Base::PlanControl; +#endif + +public: + using Base::Base; + + /// @brief Check if FSM is active + /// @return FSM active status + FFSM2_CONSTEXPR(11) bool isActive() const noexcept { return _core.registry.isActive(); } + + using Base::isActive; + + /// @brief Manually start the FSM + /// Can be used with UE4 to start / stop the FSM in `BeginPlay()` / `EndPlay()` + FFSM2_CONSTEXPR(14) void enter() noexcept { initialEnter(); } + + /// @brief Manually stop the FSM + /// Can be used with UE4 to start / stop the FSM in `BeginPlay()` / `EndPlay()` + FFSM2_CONSTEXPR(14) void exit() noexcept { finalExit(); } + +#if FFSM2_SERIALIZATION_AVAILABLE() + + /// @brief Buffer for serialization + /// @see `FFSM2_ENABLE_SERIALIZATION` + using SerialBuffer = typename Args::SerialBuffer; + + /// @brief Serialize FSM into 'buffer' + /// @param buffer `SerialBuffer` to serialize to + /// @see `FFSM2_ENABLE_SERIALIZATION` + FFSM2_CONSTEXPR(14) void save( SerialBuffer& buffer) const noexcept; + + /// @brief De-serialize FSM from 'buffer' + /// @param buffer `SerialBuffer` to de-serialize from + /// @see `FFSM2_ENABLE_SERIALIZATION` + FFSM2_CONSTEXPR(14) void load(const SerialBuffer& buffer) noexcept; -#if FFSM2_UTILITY_THEORY_AVAILABLE() - // TODO: save(stream, _core.rng); #endif #if FFSM2_TRANSITION_HISTORY_AVAILABLE() - // TODO: save(stream, _core.transitionTarget); - // TODO: save(stream, _core.previousTransition); -#endif -} - -template -FFSM2_CONSTEXPR(14) -void -R_::load(ReadStream& stream) noexcept { - FFSM2_ASSERT(_core.registry.isActive()); - - _core.registry.clearRequests(); - _apex.deepLoadRequested(_core.registry, stream); - _core.request.clear(); - // TODO: load(stream, _core.requests); + /// @brief Start the FSM from a specific state + /// Can be used with UE4 USTRUCT() NetSerialize() to load replicated FSM from FArchive + /// @param `destination` Transition destination + /// @see `FFSM2_ENABLE_TRANSITION_HISTORY` + FFSM2_CONSTEXPR(14) void replayEnter(const StateID destination) noexcept; -#if FFSM2_PLANS_AVAILABLE() - _core.planData.clear(); - // TODO: load(stream, _core.planData); #endif -#if FFSM2_UTILITY_THEORY_AVAILABLE() - // TODO: load(stream, _core.rng); -#endif +private: +#if FFSM2_SERIALIZATION_AVAILABLE() + using Base::save; + using Base::load; -#if FFSM2_TRANSITION_HISTORY_AVAILABLE() - _core.previousTransition.clear(); + FFSM2_CONSTEXPR(14) void loadEnter(ReadStream& stream) noexcept; #endif - Transition emptyTransition; - PlanControl control{_core, emptyTransition}; +protected: + using Base::initialEnter; + using Base::finalExit; - _apex.deepChangeToRequested(control); -} + using Base::_core; +#if FFSM2_SERIALIZATION_AVAILABLE() || FFSM2_TRANSITION_HISTORY_AVAILABLE() + using Base::_apex; #endif -#if FFSM2_STRUCTURE_REPORT_AVAILABLE() +#if FFSM2_TRANSITION_HISTORY_AVAILABLE() + using Base::applyRequest; #endif +}; -#if FFSM2_STRUCTURE_REPORT_AVAILABLE() -#endif +} +} -template +namespace ffsm2 { +namespace detail { + +template FFSM2_CONSTEXPR(14) -RV_, TA>::RV_(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept +RV_, TA_>::RV_(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept : Base{context FFSM2_IF_LOG_INTERFACE(, logger)} { initialEnter(); } -template +template FFSM2_CONSTEXPR(14) -RV_, TA>::RV_(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept +RV_, TA_>::RV_(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept : Base{move(context) FFSM2_IF_LOG_INTERFACE(, logger)} { initialEnter(); } -template +template FFSM2_CONSTEXPR(14) -RV_, TA>::RV_(const RV_& other) noexcept +RV_, TA_>::RV_(const RV_& other) noexcept : Base{other} {} -template +template FFSM2_CONSTEXPR(14) -RV_, TA>::RV_(RV_&& other) noexcept +RV_, TA_>::RV_(RV_&& other) noexcept : Base{move(other)} {} -template +template FFSM2_CONSTEXPR(20) -RV_, TA>::~RV_() noexcept { +RV_, TA_>::~RV_() noexcept { finalExit(); } #if FFSM2_SERIALIZATION_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -RV_, TA>::save(SerialBuffer& buffer) const noexcept { +RV_, TA_>::save(SerialBuffer& buffer) const noexcept { WriteStream stream{buffer}; stream.template write<1>(1); save(stream); } -template +template FFSM2_CONSTEXPR(14) void -RV_, TA>::load(const SerialBuffer& buffer) noexcept { +RV_, TA_>::load(const SerialBuffer& buffer) noexcept { ReadStream stream{buffer}; if (FFSM2_CHECKED(stream.template read<1>())) @@ -7166,10 +7565,10 @@ RV_, TA>::load(const SerialBuffer #if FFSM2_SERIALIZATION_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -RV_, TA>::save(SerialBuffer& buffer) const noexcept { +RV_, TA_>::save(SerialBuffer& buffer) const noexcept { WriteStream stream{buffer}; if (isActive()) { @@ -7181,10 +7580,10 @@ RV_, TA>::save(SerialBuffer& stream.template write<1>(0); } -template +template FFSM2_CONSTEXPR(14) void -RV_, TA>::load(const SerialBuffer& buffer) noexcept { +RV_, TA_>::load(const SerialBuffer& buffer) noexcept { ReadStream stream{buffer}; if (stream.template read<1>()) { @@ -7202,10 +7601,10 @@ RV_, TA>::load(const SerialBu #if FFSM2_TRANSITION_HISTORY_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -RV_, TA>::replayEnter(const StateID destination) noexcept { +RV_, TA_>::replayEnter(const StateID destination) noexcept { FFSM2_ASSERT(_core.registry.active == INVALID_SHORT); FFSM2_ASSERT(!_core.request); FFSM2_IF_TRANSITION_HISTORY(FFSM2_ASSERT(!_core.previousTransition)); @@ -7229,10 +7628,10 @@ RV_, TA>::replayEnter(const S #if FFSM2_SERIALIZATION_AVAILABLE() -template +template FFSM2_CONSTEXPR(14) void -RV_, TA>::loadEnter(ReadStream& stream) noexcept { +RV_, TA_>::loadEnter(ReadStream& stream) noexcept { FFSM2_ASSERT(_core.registry.empty()); _apex.deepLoadRequested(_core.registry, stream); @@ -7255,11 +7654,173 @@ RV_, TA>::loadEnter(ReadStrea #endif -template +} +} + +namespace ffsm2 { +namespace detail { + +template < + typename + , typename +> +class RP_; + +// Non-'void' payloads + +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES RP_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > + : public RV_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = RV_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + + using Transition = TransitionT; + +public: + using typename Base::Payload; + +public: + using Base::Base; + using Base::processRequest; + + /// @brief Get state identifier for a state type + /// @tparam `TState` State type + /// @return Numeric state identifier + template + static constexpr StateID stateId() noexcept { return Base::template stateId(); } + + /// @brief Queue a transition into a state (takes effect during `immediate*()`, `update()` or `react()`) + /// @param `stateId` Destination state identifier + /// @param `payload` Payload + FFSM2_CONSTEXPR(14) void changeWith (const StateID stateId_, + const Payload& payload) noexcept; + + /// @brief Queue a transition into a state (takes effect during `immediate*()`, `update()` or `react()`) + /// @tparam `TState` Destination state type + /// @param `payload` Payload + template + FFSM2_CONSTEXPR(14) void changeWith (const Payload& payload) noexcept { changeWith(stateId(), payload ); } + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + + /// @brief Transition into a state + /// @param `stateId` Destination state identifier + /// @param `payload` Payload + /// @see `changeWith()` + FFSM2_CONSTEXPR(14) void immediateChangeWith (const StateID stateId_, + const Payload& payload) noexcept; + + /// @brief Transition into a state + /// @tparam `TState` Destination state type + /// @param `payload` Payload + /// @see `changeWith()` + template + FFSM2_CONSTEXPR(14) void immediateChangeWith (const Payload& payload) noexcept { immediateChangeWith (stateId(), payload ); } + +#if FFSM2_UTILITY_THEORY_AVAILABLE() +#endif + +protected: + using Base::_core; +}; + +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TApex +> +class FFSM2_EMPTY_BASES RP_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + , TApex + > + : public RV_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + , TApex + > +{ + using Base = RV_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , void + > + , TApex + >; + +public: + using Base::Base; +}; + +} +} + +namespace ffsm2 { +namespace detail { + +template FFSM2_CONSTEXPR(14) void -RP_, TA>::changeWith(const StateID stateId_, - const Payload& payload) noexcept +RP_, TA_>::changeWith(const StateID stateId_, + const Payload& payload) noexcept { FFSM2_ASSERT(_core.registry.isActive()); @@ -7271,44 +7832,336 @@ RP_, TA>::changeWith(const StateI #if FFSM2_UTILITY_THEORY_AVAILABLE() #endif -template +template FFSM2_CONSTEXPR(14) void -RP_, TA>::immediateChangeWith(const StateID stateId_, - const Payload& payload) noexcept +RP_, TA_>::immediateChangeWith(const StateID stateId_, + const Payload& payload) noexcept { changeWith(stateId_, payload); processRequest(); } -template +} +} + +namespace ffsm2 { +namespace detail { + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + typename + , typename +> +class InstanceT; + +// TContext + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES InstanceT< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > final + : public RP_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = RP_< + G_< + NFeatureTag + , TContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +public: + static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + + using typename Base::Context; + using typename Base::PureContext; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + FFSM2_CONSTEXPR(11) explicit InstanceT(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(11) explicit InstanceT(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(NO) InstanceT(const InstanceT& ) noexcept = default; + FFSM2_CONSTEXPR(NO) InstanceT( InstanceT&&) noexcept = default; + +private: + using Base::_core; +}; + +// TContext& + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES InstanceT< + G_< + NFeatureTag + , TContext& + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > final + : public RP_< + G_< + NFeatureTag + , TContext& + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = RP_< + G_< + NFeatureTag + , TContext& + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +public: + static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + + using typename Base::Context; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + using Base::Base; + +private: + using Base::_core; +}; + +// TContext* + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + FeatureTag NFeatureTag + , typename TContext + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES InstanceT< + G_< + NFeatureTag + , TContext* + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > final + : public RP_< + G_< + NFeatureTag + , TContext* + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > +{ + using Base = RP_< + G_< + NFeatureTag + , TContext* + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +public: + static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + + using typename Base::Context; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + FFSM2_CONSTEXPR(11) explicit InstanceT(Context context = nullptr + FFSM2_IF_LOG_INTERFACE(, Logger* const logger = nullptr)) noexcept; + + FFSM2_CONSTEXPR(NO) InstanceT(const InstanceT& ) noexcept = default; + FFSM2_CONSTEXPR(NO) InstanceT( InstanceT&&) noexcept = default; + + FFSM2_CONSTEXPR(14) void setContext(Context context) noexcept { _core.context = context; } + +private: + using Base::_core; +}; + +// TContext == EmptyContext + +/// @brief FSM Root +/// @tparam Cfg Type configuration +/// @tparam TApex Root region type +template < + FeatureTag NFeatureTag + , typename TActivation + , Short NSubstitutionLimit + FFSM2_IF_PLANS(, Long NTaskCapacity) + , typename TPayload + , typename TApex +> +class FFSM2_EMPTY_BASES InstanceT< + G_< + NFeatureTag + , EmptyContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > final + : public RP_< + G_< + NFeatureTag + , EmptyContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + > + , public EmptyContext +{ + using Base = RP_< + G_< + NFeatureTag + , EmptyContext + , TActivation + , NSubstitutionLimit + FFSM2_IF_PLANS(, NTaskCapacity) + , TPayload + > + , TApex + >; + +public: + static constexpr FeatureTag FEATURE_TAG = Base::FEATURE_TAG; + +#if FFSM2_LOG_INTERFACE_AVAILABLE() + using typename Base::Logger; +#endif + +public: + FFSM2_CONSTEXPR(11) explicit InstanceT(FFSM2_IF_LOG_INTERFACE(Logger* const logger = nullptr)) noexcept; + + using Base::Base; +}; + +} +} + +namespace ffsm2 { +namespace detail { + +template FFSM2_CONSTEXPR(11) -InstanceT, TA>::InstanceT(Context& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept +InstanceT, TA_>::InstanceT(Context& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept : Base{context FFSM2_IF_LOG_INTERFACE(, logger)} {} -template +template FFSM2_CONSTEXPR(11) -InstanceT, TA>::InstanceT(PureContext&& context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept +InstanceT, TA_>::InstanceT(PureContext&& context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept : Base{move(context) FFSM2_IF_LOG_INTERFACE(, logger)} {} -template +template FFSM2_CONSTEXPR(11) -InstanceT, TA>::InstanceT(Context context - FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept +InstanceT, TA_>::InstanceT(Context context + FFSM2_IF_LOG_INTERFACE(, Logger* const logger)) noexcept : Base{context FFSM2_IF_LOG_INTERFACE(, logger)} {} -template +template FFSM2_CONSTEXPR(11) -InstanceT, TA>::InstanceT(FFSM2_IF_LOG_INTERFACE(Logger* const logger)) noexcept +InstanceT, TA_>::InstanceT(FFSM2_IF_LOG_INTERFACE(Logger* const logger)) noexcept : Base{static_cast(*this) FFSM2_IF_LOG_INTERFACE(, logger)} {} @@ -7331,16 +8184,25 @@ InstanceT, TA>::Instanc //#undef FFSM2_UNUSED #undef FFSM2_ATTRIBUTE + #undef FFSM2_ATTRIBUTE_FALLTHROUGH + #undef FFSM2_ATTRIBUTE_NO_UNIQUE_ADDRESS #undef FFSM2_CONSTEXPR + #undef FFSM2_CONSTEXPR_NO + #undef FFSM2_CONSTEXPR_11 + #undef FFSM2_CONSTEXPR_14 + #undef FFSM2_CONSTEXPR_17 + #undef FFSM2_CONSTEXPR_20 +//#undef FFSM2_EMPTY_BASES + //#undef FFSM2_BREAK #undef FFSM2_BREAK_AVAILABLE @@ -7373,6 +8235,7 @@ InstanceT, TA>::Instanc #undef FFSM2_IF_TRANSITION_HISTORY #undef FFSM2_VERBOSE_DEBUG_LOG_AVAILABLE + #undef FFSM2_LOG_INTERFACE_AVAILABLE #undef FFSM2_IF_LOG_INTERFACE diff --git a/premake.cmd b/premake.cmd new file mode 100644 index 0000000..7f879f0 --- /dev/null +++ b/premake.cmd @@ -0,0 +1 @@ +premake5.exe --file=premake.lua vs2022 diff --git a/premake.lua b/premake.lua new file mode 100644 index 0000000..1f21402 --- /dev/null +++ b/premake.lua @@ -0,0 +1,293 @@ +workspace "ffsm2" + configurations { + "debug", + "release" + } + conformancemode "On" + debugdir "." + defines { + "UNICODE", + "_UNICODE", + } + filename "ffsm2-all" + flags { + "FatalCompileWarnings", + "NoPCH", + } + includedirs { + "development", + "include", + "external", + } + language "C++" + location "projects/premake" + objdir "$(BUILD_ROOT)/$(SolutionName)-$(PlatformArchitecture)/$(ProjectName)-$(Configuration)/" + platforms { + "32", + "64", + } + + system "windows" + systemversion "latest" + --systemversion "$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))" + + targetdir "binaries-$(PlatformArchitecture)/" + targetname "$(ProjectName)-$(Configuration)-$(PlatformArchitecture)" + warnings "High" + + filter "toolset:msc-v140 or msc-v141" + if os.getversion().majorversion == 10 then + local sWin10SDK = os.getWindowsRegistry( "HKLM:SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0\\ProductVersion" ) + if sWin10SDK ~= nil then systemversion( sWin10SDK .. ".0" ) end + end + + filter "configurations:debug" + defines "_DEBUG" + symbols "On" + + filter "configurations:release" + defines "NDEBUG" + intrinsics "On" + optimize "Speed" + flags { + "LinkTimeOptimization", + } + + filter { "platforms:32" } + architecture "x86" + + filter { "platforms:64" } + architecture "x86_64" + + filter "toolset:msc-ClangCL" + buildoptions { + "-Wpedantic", + } + linkoptions { + "/INCREMENTAL:NO" + } + + filter "toolset:msc-v143" + buildoptions { + "/permissive-", + } + +-- basic_audio_player + +project "basic_audio_player-14" + cppdialect "C++11" + files { + "examples/basic_audio_player/**.*", + } + kind "ConsoleApp" + toolset "msc-v140" + +project "basic_audio_player-15" + cppdialect "C++14" + files { + "examples/basic_audio_player/**.*", + } + kind "ConsoleApp" + toolset "msc-v141" + +project "basic_audio_player-16" + cppdialect "C++17" + files { + "examples/basic_audio_player/**.*", + } + kind "ConsoleApp" + toolset "msc-v142" + +project "basic_audio_player-17" + cppdialect "C++20" + files { + "examples/basic_audio_player/**.*", + } + kind "ConsoleApp" + toolset "msc-v143" + +project "basic_audio_player-clang" + cppdialect "C++20" + files { + "examples/basic_audio_player/**.*", + } + kind "ConsoleApp" + toolset "msc-ClangCL" + +-- basic_traffic_light + +project "basic_traffic_light-14" + cppdialect "C++11" + files { + "examples/basic_traffic_light/**.*", + } + kind "ConsoleApp" + toolset "msc-v140" + +project "basic_traffic_light-15" + cppdialect "C++14" + files { + "examples/basic_traffic_light/**.*", + } + kind "ConsoleApp" + toolset "msc-v141" + +project "basic_traffic_light-16" + cppdialect "C++17" + files { + "examples/basic_traffic_light/**.*", + } + kind "ConsoleApp" + toolset "msc-v142" + +project "basic_traffic_light-17" + cppdialect "C++20" + files { + "examples/basic_traffic_light/**.*", + } + kind "ConsoleApp" + toolset "msc-v143" + +project "basic_traffic_light-clang" + cppdialect "C++20" + files { + "examples/basic_traffic_light/**.*", + } + kind "ConsoleApp" + toolset "msc-ClangCL" + +-- debug_logger_interface + +project "debug_logger_interface-14" + cppdialect "C++11" + files { + "examples/debug_logger_interface/**.*", + } + kind "ConsoleApp" + toolset "msc-v140" + +project "debug_logger_interface-15" + cppdialect "C++14" + files { + "examples/debug_logger_interface/**.*", + } + kind "ConsoleApp" + toolset "msc-v141" + +project "debug_logger_interface-16" + cppdialect "C++17" + files { + "examples/debug_logger_interface/**.*", + } + kind "ConsoleApp" + toolset "msc-v142" + +project "debug_logger_interface-17" + cppdialect "C++20" + files { + "examples/debug_logger_interface/**.*", + } + kind "ConsoleApp" + toolset "msc-v143" + +project "debug_logger_interface-clang" + cppdialect "C++20" + files { + "examples/debug_logger_interface/**.*", + } + kind "ConsoleApp" + toolset "msc-ClangCL" + +-- temp + +project "temp-14" + cppdialect "C++11" + files { + "development/**.*", + "temp/**.*", + } + kind "ConsoleApp" + toolset "msc-v140" + +project "temp-15" + cppdialect "C++14" + files { + "development/**.*", + "temp/**.*", + } + kind "ConsoleApp" + toolset "msc-v141" + +project "temp-16" + cppdialect "C++17" + files { + "development/**.*", + "temp/**.*", + } + kind "ConsoleApp" + toolset "msc-v142" + +project "temp-17" + cppdialect "C++20" + files { + "development/**.*", + "temp/**.*", + } + kind "ConsoleApp" + toolset "msc-v143" + +project "temp-clang" + cppdialect "C++20" + files { + "development/**.*", + "temp/**.*", + } + kind "ConsoleApp" + toolset "msc-ClangCL" + +-- test + +project "test-14" + cppdialect "C++11" + files { + "development/**.*", + "test/**.*", + } + kind "ConsoleApp" + toolset "msc-v140" + +project "test-15" + cppdialect "C++14" + files { + "development/**.*", + "test/**.*", + } + kind "ConsoleApp" + toolset "msc-v141" + +project "test-16" + cppdialect "C++17" + files { + "development/**.*", + "test/**.*", + } + kind "ConsoleApp" + toolset "msc-v142" + +project "test-17" + cppdialect "C++20" + files { + "development/**.*", + "test/**.*", + } + kind "ConsoleApp" + toolset "msc-v143" + +project "test-clang" + cppdialect "C++20" + files { + "development/**.*", + "test/**.*", + } + kind "ConsoleApp" + toolset "msc-ClangCL" diff --git a/projects/premake/basic_audio_player-14.vcxproj b/projects/premake/basic_audio_player-14.vcxproj new file mode 100644 index 0000000..ac6baf2 --- /dev/null +++ b/projects/premake/basic_audio_player-14.vcxproj @@ -0,0 +1,212 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8} + true + Win32Proj + basic_audio_player-14 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + Unicode + v140 + true + + + Application + false + Unicode + v140 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_audio_player-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_audio_player-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_audio_player-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_audio_player-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_audio_player-15.vcxproj b/projects/premake/basic_audio_player-15.vcxproj new file mode 100644 index 0000000..f16e8a7 --- /dev/null +++ b/projects/premake/basic_audio_player-15.vcxproj @@ -0,0 +1,216 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8} + true + Win32Proj + basic_audio_player-15 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v141 + + + Application + true + Unicode + v141 + + + Application + false + Unicode + v141 + true + + + Application + false + Unicode + v141 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_audio_player-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_audio_player-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_audio_player-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_audio_player-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_audio_player-16.vcxproj b/projects/premake/basic_audio_player-16.vcxproj new file mode 100644 index 0000000..5de340e --- /dev/null +++ b/projects/premake/basic_audio_player-16.vcxproj @@ -0,0 +1,204 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8} + true + Win32Proj + basic_audio_player-16 + 10.0 + + + + Application + true + Unicode + v142 + + + Application + true + Unicode + v142 + + + Application + false + Unicode + v142 + true + + + Application + false + Unicode + v142 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_audio_player-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_audio_player-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_audio_player-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_audio_player-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_audio_player-17.vcxproj b/projects/premake/basic_audio_player-17.vcxproj new file mode 100644 index 0000000..ee0593f --- /dev/null +++ b/projects/premake/basic_audio_player-17.vcxproj @@ -0,0 +1,208 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8} + true + Win32Proj + basic_audio_player-17 + 10.0 + + + + Application + true + Unicode + v143 + + + Application + true + Unicode + v143 + + + Application + false + Unicode + v143 + true + + + Application + false + Unicode + v143 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_audio_player-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_audio_player-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_audio_player-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_audio_player-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_audio_player-clang.vcxproj b/projects/premake/basic_audio_player-clang.vcxproj new file mode 100644 index 0000000..87f111b --- /dev/null +++ b/projects/premake/basic_audio_player-clang.vcxproj @@ -0,0 +1,212 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9} + true + Win32Proj + basic_audio_player-clang + 10.0 + + + + Application + true + Unicode + clangcl + + + Application + true + Unicode + clangcl + + + Application + false + Unicode + clangcl + true + + + Application + false + Unicode + clangcl + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_audio_player-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_audio_player-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_audio_player-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_audio_player-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_traffic_light-14.vcxproj b/projects/premake/basic_traffic_light-14.vcxproj new file mode 100644 index 0000000..9a89755 --- /dev/null +++ b/projects/premake/basic_traffic_light-14.vcxproj @@ -0,0 +1,212 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF} + true + Win32Proj + basic_traffic_light-14 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + Unicode + v140 + true + + + Application + false + Unicode + v140 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_traffic_light-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_traffic_light-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_traffic_light-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_traffic_light-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_traffic_light-15.vcxproj b/projects/premake/basic_traffic_light-15.vcxproj new file mode 100644 index 0000000..a9a9c56 --- /dev/null +++ b/projects/premake/basic_traffic_light-15.vcxproj @@ -0,0 +1,216 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {8FF02841-7BEA-5193-6457-E8A350F0B7FF} + true + Win32Proj + basic_traffic_light-15 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v141 + + + Application + true + Unicode + v141 + + + Application + false + Unicode + v141 + true + + + Application + false + Unicode + v141 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_traffic_light-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_traffic_light-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_traffic_light-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_traffic_light-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_traffic_light-16.vcxproj b/projects/premake/basic_traffic_light-16.vcxproj new file mode 100644 index 0000000..4e6b92b --- /dev/null +++ b/projects/premake/basic_traffic_light-16.vcxproj @@ -0,0 +1,204 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {90F02841-7CEA-5193-6557-E8A351F0B7FF} + true + Win32Proj + basic_traffic_light-16 + 10.0 + + + + Application + true + Unicode + v142 + + + Application + true + Unicode + v142 + + + Application + false + Unicode + v142 + true + + + Application + false + Unicode + v142 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_traffic_light-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_traffic_light-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_traffic_light-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_traffic_light-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_traffic_light-17.vcxproj b/projects/premake/basic_traffic_light-17.vcxproj new file mode 100644 index 0000000..8f12f4e --- /dev/null +++ b/projects/premake/basic_traffic_light-17.vcxproj @@ -0,0 +1,208 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {91F02841-7DEA-5193-6657-E8A352F0B7FF} + true + Win32Proj + basic_traffic_light-17 + 10.0 + + + + Application + true + Unicode + v143 + + + Application + true + Unicode + v143 + + + Application + false + Unicode + v143 + true + + + Application + false + Unicode + v143 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_traffic_light-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_traffic_light-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_traffic_light-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_traffic_light-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/basic_traffic_light-clang.vcxproj b/projects/premake/basic_traffic_light-clang.vcxproj new file mode 100644 index 0000000..c9840a3 --- /dev/null +++ b/projects/premake/basic_traffic_light-clang.vcxproj @@ -0,0 +1,212 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F} + true + Win32Proj + basic_traffic_light-clang + 10.0 + + + + Application + true + Unicode + clangcl + + + Application + true + Unicode + clangcl + + + Application + false + Unicode + clangcl + true + + + Application + false + Unicode + clangcl + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\basic_traffic_light-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\basic_traffic_light-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\basic_traffic_light-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\basic_traffic_light-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/debug_logger_interface-14.vcxproj b/projects/premake/debug_logger_interface-14.vcxproj new file mode 100644 index 0000000..7ee9473 --- /dev/null +++ b/projects/premake/debug_logger_interface-14.vcxproj @@ -0,0 +1,212 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {CD91E21A-3954-16A5-8204-A531EE05EF82} + true + Win32Proj + debug_logger_interface-14 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + Unicode + v140 + true + + + Application + false + Unicode + v140 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\debug_logger_interface-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\debug_logger_interface-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\debug_logger_interface-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\debug_logger_interface-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/debug_logger_interface-15.vcxproj b/projects/premake/debug_logger_interface-15.vcxproj new file mode 100644 index 0000000..d1af47f --- /dev/null +++ b/projects/premake/debug_logger_interface-15.vcxproj @@ -0,0 +1,216 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {CE91E21A-3A54-16A5-8304-A531EF05EF82} + true + Win32Proj + debug_logger_interface-15 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v141 + + + Application + true + Unicode + v141 + + + Application + false + Unicode + v141 + true + + + Application + false + Unicode + v141 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\debug_logger_interface-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\debug_logger_interface-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\debug_logger_interface-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\debug_logger_interface-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/debug_logger_interface-16.vcxproj b/projects/premake/debug_logger_interface-16.vcxproj new file mode 100644 index 0000000..0a4004b --- /dev/null +++ b/projects/premake/debug_logger_interface-16.vcxproj @@ -0,0 +1,204 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {CF91E21A-3B54-16A5-8404-A531F005EF82} + true + Win32Proj + debug_logger_interface-16 + 10.0 + + + + Application + true + Unicode + v142 + + + Application + true + Unicode + v142 + + + Application + false + Unicode + v142 + true + + + Application + false + Unicode + v142 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\debug_logger_interface-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\debug_logger_interface-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\debug_logger_interface-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\debug_logger_interface-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/debug_logger_interface-17.vcxproj b/projects/premake/debug_logger_interface-17.vcxproj new file mode 100644 index 0000000..944d697 --- /dev/null +++ b/projects/premake/debug_logger_interface-17.vcxproj @@ -0,0 +1,208 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {D091E21A-3C54-16A5-8504-A531F105EF82} + true + Win32Proj + debug_logger_interface-17 + 10.0 + + + + Application + true + Unicode + v143 + + + Application + true + Unicode + v143 + + + Application + false + Unicode + v143 + true + + + Application + false + Unicode + v143 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\debug_logger_interface-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\debug_logger_interface-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\debug_logger_interface-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\debug_logger_interface-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/debug_logger_interface-clang.vcxproj b/projects/premake/debug_logger_interface-clang.vcxproj new file mode 100644 index 0000000..1d9b5cf --- /dev/null +++ b/projects/premake/debug_logger_interface-clang.vcxproj @@ -0,0 +1,212 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {4D843E1B-393F-2EC7-E2F6-A611CE907857} + true + Win32Proj + debug_logger_interface-clang + 10.0 + + + + Application + true + Unicode + clangcl + + + Application + true + Unicode + clangcl + + + Application + false + Unicode + clangcl + true + + + Application + false + Unicode + clangcl + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\debug_logger_interface-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\debug_logger_interface-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\debug_logger_interface-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\debug_logger_interface-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/ffsm2-all.sln b/projects/premake/ffsm2-all.sln new file mode 100644 index 0000000..a4f644d --- /dev/null +++ b/projects/premake/ffsm2-all.sln @@ -0,0 +1,266 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_audio_player-14", "basic_audio_player-14.vcxproj", "{D6549E75-42C1-5970-0BB5-F1CD77E07BD8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_audio_player-15", "basic_audio_player-15.vcxproj", "{D7549E75-43C1-5970-0CB5-F1CD78E07BD8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_audio_player-16", "basic_audio_player-16.vcxproj", "{D8549E75-44C1-5970-0DB5-F1CD79E07BD8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_audio_player-17", "basic_audio_player-17.vcxproj", "{D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_audio_player-clang", "basic_audio_player-clang.vcxproj", "{B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_traffic_light-14", "basic_traffic_light-14.vcxproj", "{8EF02841-7AEA-5193-6357-E8A34FF0B7FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_traffic_light-15", "basic_traffic_light-15.vcxproj", "{8FF02841-7BEA-5193-6457-E8A350F0B7FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_traffic_light-16", "basic_traffic_light-16.vcxproj", "{90F02841-7CEA-5193-6557-E8A351F0B7FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_traffic_light-17", "basic_traffic_light-17.vcxproj", "{91F02841-7DEA-5193-6657-E8A352F0B7FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_traffic_light-clang", "basic_traffic_light-clang.vcxproj", "{6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_logger_interface-14", "debug_logger_interface-14.vcxproj", "{CD91E21A-3954-16A5-8204-A531EE05EF82}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_logger_interface-15", "debug_logger_interface-15.vcxproj", "{CE91E21A-3A54-16A5-8304-A531EF05EF82}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_logger_interface-16", "debug_logger_interface-16.vcxproj", "{CF91E21A-3B54-16A5-8404-A531F005EF82}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_logger_interface-17", "debug_logger_interface-17.vcxproj", "{D091E21A-3C54-16A5-8504-A531F105EF82}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_logger_interface-clang", "debug_logger_interface-clang.vcxproj", "{4D843E1B-393F-2EC7-E2F6-A611CE907857}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "temp-14", "temp-14.vcxproj", "{ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "temp-15", "temp-15.vcxproj", "{AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "temp-16", "temp-16.vcxproj", "{AFCBAED8-1BAB-2D74-24C3-B84A902194D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "temp-17", "temp-17.vcxproj", "{B0CBAED8-1CAB-2D74-25C3-B84A912194D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "temp-clang", "temp-clang.vcxproj", "{2DF246B5-19AA-8802-82B1-615E6E8823F3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-14", "test-14.vcxproj", "{37901DD9-A36F-9C74-AC87-274B18E602D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-15", "test-15.vcxproj", "{38901DD9-A46F-9C74-AD87-274B19E602D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-16", "test-16.vcxproj", "{39901DD9-A56F-9C74-AE87-274B1AE602D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-17", "test-17.vcxproj", "{3A901DD9-A66F-9C74-AF87-274B1BE602D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-clang", "test-clang.vcxproj", "{77E2BA72-639A-FCBF-CCA1-D51BB87897B0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug|32 = debug|32 + debug|64 = debug|64 + release|32 = release|32 + release|64 = release|64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8}.debug|32.ActiveCfg = debug 32|Win32 + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8}.debug|32.Build.0 = debug 32|Win32 + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8}.debug|64.ActiveCfg = debug 64|x64 + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8}.debug|64.Build.0 = debug 64|x64 + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8}.release|32.ActiveCfg = release 32|Win32 + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8}.release|32.Build.0 = release 32|Win32 + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8}.release|64.ActiveCfg = release 64|x64 + {D6549E75-42C1-5970-0BB5-F1CD77E07BD8}.release|64.Build.0 = release 64|x64 + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8}.debug|32.ActiveCfg = debug 32|Win32 + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8}.debug|32.Build.0 = debug 32|Win32 + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8}.debug|64.ActiveCfg = debug 64|x64 + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8}.debug|64.Build.0 = debug 64|x64 + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8}.release|32.ActiveCfg = release 32|Win32 + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8}.release|32.Build.0 = release 32|Win32 + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8}.release|64.ActiveCfg = release 64|x64 + {D7549E75-43C1-5970-0CB5-F1CD78E07BD8}.release|64.Build.0 = release 64|x64 + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8}.debug|32.ActiveCfg = debug 32|Win32 + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8}.debug|32.Build.0 = debug 32|Win32 + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8}.debug|64.ActiveCfg = debug 64|x64 + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8}.debug|64.Build.0 = debug 64|x64 + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8}.release|32.ActiveCfg = release 32|Win32 + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8}.release|32.Build.0 = release 32|Win32 + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8}.release|64.ActiveCfg = release 64|x64 + {D8549E75-44C1-5970-0DB5-F1CD79E07BD8}.release|64.Build.0 = release 64|x64 + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}.debug|32.ActiveCfg = debug 32|Win32 + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}.debug|32.Build.0 = debug 32|Win32 + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}.debug|64.ActiveCfg = debug 64|x64 + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}.debug|64.Build.0 = debug 64|x64 + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}.release|32.ActiveCfg = release 32|Win32 + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}.release|32.Build.0 = release 32|Win32 + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}.release|64.ActiveCfg = release 64|x64 + {D9549E75-45C1-5970-0EB5-F1CD7AE07BD8}.release|64.Build.0 = release 64|x64 + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}.debug|32.ActiveCfg = debug 32|Win32 + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}.debug|32.Build.0 = debug 32|Win32 + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}.debug|64.ActiveCfg = debug 64|x64 + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}.debug|64.Build.0 = debug 64|x64 + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}.release|32.ActiveCfg = release 32|Win32 + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}.release|32.Build.0 = release 32|Win32 + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}.release|64.ActiveCfg = release 64|x64 + {B6560C2B-A27B-5BAB-CBC6-403BB74A5AC9}.release|64.Build.0 = release 64|x64 + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF}.debug|32.ActiveCfg = debug 32|Win32 + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF}.debug|32.Build.0 = debug 32|Win32 + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF}.debug|64.ActiveCfg = debug 64|x64 + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF}.debug|64.Build.0 = debug 64|x64 + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF}.release|32.ActiveCfg = release 32|Win32 + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF}.release|32.Build.0 = release 32|Win32 + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF}.release|64.ActiveCfg = release 64|x64 + {8EF02841-7AEA-5193-6357-E8A34FF0B7FF}.release|64.Build.0 = release 64|x64 + {8FF02841-7BEA-5193-6457-E8A350F0B7FF}.debug|32.ActiveCfg = debug 32|Win32 + {8FF02841-7BEA-5193-6457-E8A350F0B7FF}.debug|32.Build.0 = debug 32|Win32 + {8FF02841-7BEA-5193-6457-E8A350F0B7FF}.debug|64.ActiveCfg = debug 64|x64 + {8FF02841-7BEA-5193-6457-E8A350F0B7FF}.debug|64.Build.0 = debug 64|x64 + {8FF02841-7BEA-5193-6457-E8A350F0B7FF}.release|32.ActiveCfg = release 32|Win32 + {8FF02841-7BEA-5193-6457-E8A350F0B7FF}.release|32.Build.0 = release 32|Win32 + {8FF02841-7BEA-5193-6457-E8A350F0B7FF}.release|64.ActiveCfg = release 64|x64 + {8FF02841-7BEA-5193-6457-E8A350F0B7FF}.release|64.Build.0 = release 64|x64 + {90F02841-7CEA-5193-6557-E8A351F0B7FF}.debug|32.ActiveCfg = debug 32|Win32 + {90F02841-7CEA-5193-6557-E8A351F0B7FF}.debug|32.Build.0 = debug 32|Win32 + {90F02841-7CEA-5193-6557-E8A351F0B7FF}.debug|64.ActiveCfg = debug 64|x64 + {90F02841-7CEA-5193-6557-E8A351F0B7FF}.debug|64.Build.0 = debug 64|x64 + {90F02841-7CEA-5193-6557-E8A351F0B7FF}.release|32.ActiveCfg = release 32|Win32 + {90F02841-7CEA-5193-6557-E8A351F0B7FF}.release|32.Build.0 = release 32|Win32 + {90F02841-7CEA-5193-6557-E8A351F0B7FF}.release|64.ActiveCfg = release 64|x64 + {90F02841-7CEA-5193-6557-E8A351F0B7FF}.release|64.Build.0 = release 64|x64 + {91F02841-7DEA-5193-6657-E8A352F0B7FF}.debug|32.ActiveCfg = debug 32|Win32 + {91F02841-7DEA-5193-6657-E8A352F0B7FF}.debug|32.Build.0 = debug 32|Win32 + {91F02841-7DEA-5193-6657-E8A352F0B7FF}.debug|64.ActiveCfg = debug 64|x64 + {91F02841-7DEA-5193-6657-E8A352F0B7FF}.debug|64.Build.0 = debug 64|x64 + {91F02841-7DEA-5193-6657-E8A352F0B7FF}.release|32.ActiveCfg = release 32|Win32 + {91F02841-7DEA-5193-6657-E8A352F0B7FF}.release|32.Build.0 = release 32|Win32 + {91F02841-7DEA-5193-6657-E8A352F0B7FF}.release|64.ActiveCfg = release 64|x64 + {91F02841-7DEA-5193-6657-E8A352F0B7FF}.release|64.Build.0 = release 64|x64 + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}.debug|32.ActiveCfg = debug 32|Win32 + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}.debug|32.Build.0 = debug 32|Win32 + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}.debug|64.ActiveCfg = debug 64|x64 + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}.debug|64.Build.0 = debug 64|x64 + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}.release|32.ActiveCfg = release 32|Win32 + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}.release|32.Build.0 = release 32|Win32 + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}.release|64.ActiveCfg = release 64|x64 + {6EF7B917-DAB9-EDA1-236A-7C2E8F6BC67F}.release|64.Build.0 = release 64|x64 + {CD91E21A-3954-16A5-8204-A531EE05EF82}.debug|32.ActiveCfg = debug 32|Win32 + {CD91E21A-3954-16A5-8204-A531EE05EF82}.debug|32.Build.0 = debug 32|Win32 + {CD91E21A-3954-16A5-8204-A531EE05EF82}.debug|64.ActiveCfg = debug 64|x64 + {CD91E21A-3954-16A5-8204-A531EE05EF82}.debug|64.Build.0 = debug 64|x64 + {CD91E21A-3954-16A5-8204-A531EE05EF82}.release|32.ActiveCfg = release 32|Win32 + {CD91E21A-3954-16A5-8204-A531EE05EF82}.release|32.Build.0 = release 32|Win32 + {CD91E21A-3954-16A5-8204-A531EE05EF82}.release|64.ActiveCfg = release 64|x64 + {CD91E21A-3954-16A5-8204-A531EE05EF82}.release|64.Build.0 = release 64|x64 + {CE91E21A-3A54-16A5-8304-A531EF05EF82}.debug|32.ActiveCfg = debug 32|Win32 + {CE91E21A-3A54-16A5-8304-A531EF05EF82}.debug|32.Build.0 = debug 32|Win32 + {CE91E21A-3A54-16A5-8304-A531EF05EF82}.debug|64.ActiveCfg = debug 64|x64 + {CE91E21A-3A54-16A5-8304-A531EF05EF82}.debug|64.Build.0 = debug 64|x64 + {CE91E21A-3A54-16A5-8304-A531EF05EF82}.release|32.ActiveCfg = release 32|Win32 + {CE91E21A-3A54-16A5-8304-A531EF05EF82}.release|32.Build.0 = release 32|Win32 + {CE91E21A-3A54-16A5-8304-A531EF05EF82}.release|64.ActiveCfg = release 64|x64 + {CE91E21A-3A54-16A5-8304-A531EF05EF82}.release|64.Build.0 = release 64|x64 + {CF91E21A-3B54-16A5-8404-A531F005EF82}.debug|32.ActiveCfg = debug 32|Win32 + {CF91E21A-3B54-16A5-8404-A531F005EF82}.debug|32.Build.0 = debug 32|Win32 + {CF91E21A-3B54-16A5-8404-A531F005EF82}.debug|64.ActiveCfg = debug 64|x64 + {CF91E21A-3B54-16A5-8404-A531F005EF82}.debug|64.Build.0 = debug 64|x64 + {CF91E21A-3B54-16A5-8404-A531F005EF82}.release|32.ActiveCfg = release 32|Win32 + {CF91E21A-3B54-16A5-8404-A531F005EF82}.release|32.Build.0 = release 32|Win32 + {CF91E21A-3B54-16A5-8404-A531F005EF82}.release|64.ActiveCfg = release 64|x64 + {CF91E21A-3B54-16A5-8404-A531F005EF82}.release|64.Build.0 = release 64|x64 + {D091E21A-3C54-16A5-8504-A531F105EF82}.debug|32.ActiveCfg = debug 32|Win32 + {D091E21A-3C54-16A5-8504-A531F105EF82}.debug|32.Build.0 = debug 32|Win32 + {D091E21A-3C54-16A5-8504-A531F105EF82}.debug|64.ActiveCfg = debug 64|x64 + {D091E21A-3C54-16A5-8504-A531F105EF82}.debug|64.Build.0 = debug 64|x64 + {D091E21A-3C54-16A5-8504-A531F105EF82}.release|32.ActiveCfg = release 32|Win32 + {D091E21A-3C54-16A5-8504-A531F105EF82}.release|32.Build.0 = release 32|Win32 + {D091E21A-3C54-16A5-8504-A531F105EF82}.release|64.ActiveCfg = release 64|x64 + {D091E21A-3C54-16A5-8504-A531F105EF82}.release|64.Build.0 = release 64|x64 + {4D843E1B-393F-2EC7-E2F6-A611CE907857}.debug|32.ActiveCfg = debug 32|Win32 + {4D843E1B-393F-2EC7-E2F6-A611CE907857}.debug|32.Build.0 = debug 32|Win32 + {4D843E1B-393F-2EC7-E2F6-A611CE907857}.debug|64.ActiveCfg = debug 64|x64 + {4D843E1B-393F-2EC7-E2F6-A611CE907857}.debug|64.Build.0 = debug 64|x64 + {4D843E1B-393F-2EC7-E2F6-A611CE907857}.release|32.ActiveCfg = release 32|Win32 + {4D843E1B-393F-2EC7-E2F6-A611CE907857}.release|32.Build.0 = release 32|Win32 + {4D843E1B-393F-2EC7-E2F6-A611CE907857}.release|64.ActiveCfg = release 64|x64 + {4D843E1B-393F-2EC7-E2F6-A611CE907857}.release|64.Build.0 = release 64|x64 + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}.debug|32.ActiveCfg = debug 32|Win32 + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}.debug|32.Build.0 = debug 32|Win32 + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}.debug|64.ActiveCfg = debug 64|x64 + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}.debug|64.Build.0 = debug 64|x64 + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}.release|32.ActiveCfg = release 32|Win32 + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}.release|32.Build.0 = release 32|Win32 + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}.release|64.ActiveCfg = release 64|x64 + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5}.release|64.Build.0 = release 64|x64 + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}.debug|32.ActiveCfg = debug 32|Win32 + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}.debug|32.Build.0 = debug 32|Win32 + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}.debug|64.ActiveCfg = debug 64|x64 + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}.debug|64.Build.0 = debug 64|x64 + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}.release|32.ActiveCfg = release 32|Win32 + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}.release|32.Build.0 = release 32|Win32 + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}.release|64.ActiveCfg = release 64|x64 + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5}.release|64.Build.0 = release 64|x64 + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5}.debug|32.ActiveCfg = debug 32|Win32 + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5}.debug|32.Build.0 = debug 32|Win32 + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5}.debug|64.ActiveCfg = debug 64|x64 + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5}.debug|64.Build.0 = debug 64|x64 + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5}.release|32.ActiveCfg = release 32|Win32 + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5}.release|32.Build.0 = release 32|Win32 + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5}.release|64.ActiveCfg = release 64|x64 + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5}.release|64.Build.0 = release 64|x64 + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5}.debug|32.ActiveCfg = debug 32|Win32 + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5}.debug|32.Build.0 = debug 32|Win32 + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5}.debug|64.ActiveCfg = debug 64|x64 + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5}.debug|64.Build.0 = debug 64|x64 + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5}.release|32.ActiveCfg = release 32|Win32 + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5}.release|32.Build.0 = release 32|Win32 + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5}.release|64.ActiveCfg = release 64|x64 + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5}.release|64.Build.0 = release 64|x64 + {2DF246B5-19AA-8802-82B1-615E6E8823F3}.debug|32.ActiveCfg = debug 32|Win32 + {2DF246B5-19AA-8802-82B1-615E6E8823F3}.debug|32.Build.0 = debug 32|Win32 + {2DF246B5-19AA-8802-82B1-615E6E8823F3}.debug|64.ActiveCfg = debug 64|x64 + {2DF246B5-19AA-8802-82B1-615E6E8823F3}.debug|64.Build.0 = debug 64|x64 + {2DF246B5-19AA-8802-82B1-615E6E8823F3}.release|32.ActiveCfg = release 32|Win32 + {2DF246B5-19AA-8802-82B1-615E6E8823F3}.release|32.Build.0 = release 32|Win32 + {2DF246B5-19AA-8802-82B1-615E6E8823F3}.release|64.ActiveCfg = release 64|x64 + {2DF246B5-19AA-8802-82B1-615E6E8823F3}.release|64.Build.0 = release 64|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|32.ActiveCfg = debug 32|Win32 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|32.Build.0 = debug 32|Win32 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|64.ActiveCfg = debug 64|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|64.Build.0 = debug 64|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|32.ActiveCfg = release 32|Win32 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|32.Build.0 = release 32|Win32 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|64.ActiveCfg = release 64|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|64.Build.0 = release 64|x64 + {38901DD9-A46F-9C74-AD87-274B19E602D6}.debug|32.ActiveCfg = debug 32|Win32 + {38901DD9-A46F-9C74-AD87-274B19E602D6}.debug|32.Build.0 = debug 32|Win32 + {38901DD9-A46F-9C74-AD87-274B19E602D6}.debug|64.ActiveCfg = debug 64|x64 + {38901DD9-A46F-9C74-AD87-274B19E602D6}.debug|64.Build.0 = debug 64|x64 + {38901DD9-A46F-9C74-AD87-274B19E602D6}.release|32.ActiveCfg = release 32|Win32 + {38901DD9-A46F-9C74-AD87-274B19E602D6}.release|32.Build.0 = release 32|Win32 + {38901DD9-A46F-9C74-AD87-274B19E602D6}.release|64.ActiveCfg = release 64|x64 + {38901DD9-A46F-9C74-AD87-274B19E602D6}.release|64.Build.0 = release 64|x64 + {39901DD9-A56F-9C74-AE87-274B1AE602D6}.debug|32.ActiveCfg = debug 32|Win32 + {39901DD9-A56F-9C74-AE87-274B1AE602D6}.debug|32.Build.0 = debug 32|Win32 + {39901DD9-A56F-9C74-AE87-274B1AE602D6}.debug|64.ActiveCfg = debug 64|x64 + {39901DD9-A56F-9C74-AE87-274B1AE602D6}.debug|64.Build.0 = debug 64|x64 + {39901DD9-A56F-9C74-AE87-274B1AE602D6}.release|32.ActiveCfg = release 32|Win32 + {39901DD9-A56F-9C74-AE87-274B1AE602D6}.release|32.Build.0 = release 32|Win32 + {39901DD9-A56F-9C74-AE87-274B1AE602D6}.release|64.ActiveCfg = release 64|x64 + {39901DD9-A56F-9C74-AE87-274B1AE602D6}.release|64.Build.0 = release 64|x64 + {3A901DD9-A66F-9C74-AF87-274B1BE602D6}.debug|32.ActiveCfg = debug 32|Win32 + {3A901DD9-A66F-9C74-AF87-274B1BE602D6}.debug|32.Build.0 = debug 32|Win32 + {3A901DD9-A66F-9C74-AF87-274B1BE602D6}.debug|64.ActiveCfg = debug 64|x64 + {3A901DD9-A66F-9C74-AF87-274B1BE602D6}.debug|64.Build.0 = debug 64|x64 + {3A901DD9-A66F-9C74-AF87-274B1BE602D6}.release|32.ActiveCfg = release 32|Win32 + {3A901DD9-A66F-9C74-AF87-274B1BE602D6}.release|32.Build.0 = release 32|Win32 + {3A901DD9-A66F-9C74-AF87-274B1BE602D6}.release|64.ActiveCfg = release 64|x64 + {3A901DD9-A66F-9C74-AF87-274B1BE602D6}.release|64.Build.0 = release 64|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|32.ActiveCfg = debug 32|Win32 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|32.Build.0 = debug 32|Win32 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|64.ActiveCfg = debug 64|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|64.Build.0 = debug 64|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|32.ActiveCfg = release 32|Win32 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|32.Build.0 = release 32|Win32 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|64.ActiveCfg = release 64|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|64.Build.0 = release 64|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/premake/ffsm2-lite.sln b/projects/premake/ffsm2-lite.sln new file mode 100644 index 0000000..a6786b7 --- /dev/null +++ b/projects/premake/ffsm2-lite.sln @@ -0,0 +1,59 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-14", "test-14.vcxproj", "{37901DD9-A36F-9C74-AC87-274B18E602D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-clang", "test-clang.vcxproj", "{77E2BA72-639A-FCBF-CCA1-D51BB87897B0}" +EndProject +Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "tools", "tools.pyproj", "{2347027E-E5DE-43C4-8EF9-5F1411ADE33B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug|32 = debug|32 + debug|64 = debug|64 + debug|Any CPU = debug|Any CPU + release|32 = release|32 + release|64 = release|64 + release|Any CPU = release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|32.ActiveCfg = debug 32|Win32 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|32.Build.0 = debug 32|Win32 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|64.ActiveCfg = debug 64|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|64.Build.0 = debug 64|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|Any CPU.ActiveCfg = debug 32|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.debug|Any CPU.Build.0 = debug 32|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|32.ActiveCfg = release 32|Win32 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|32.Build.0 = release 32|Win32 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|64.ActiveCfg = release 64|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|64.Build.0 = release 64|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|Any CPU.ActiveCfg = release 32|x64 + {37901DD9-A36F-9C74-AC87-274B18E602D6}.release|Any CPU.Build.0 = release 32|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|32.ActiveCfg = debug 32|Win32 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|32.Build.0 = debug 32|Win32 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|64.ActiveCfg = debug 64|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|64.Build.0 = debug 64|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|Any CPU.ActiveCfg = debug 32|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.debug|Any CPU.Build.0 = debug 32|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|32.ActiveCfg = release 32|Win32 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|32.Build.0 = release 32|Win32 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|64.ActiveCfg = release 64|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|64.Build.0 = release 64|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|Any CPU.ActiveCfg = release 32|x64 + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0}.release|Any CPU.Build.0 = release 32|x64 + {2347027E-E5DE-43C4-8EF9-5F1411ADE33B}.debug|32.ActiveCfg = Debug|Any CPU + {2347027E-E5DE-43C4-8EF9-5F1411ADE33B}.debug|64.ActiveCfg = Debug|Any CPU + {2347027E-E5DE-43C4-8EF9-5F1411ADE33B}.debug|Any CPU.ActiveCfg = Debug|Any CPU + {2347027E-E5DE-43C4-8EF9-5F1411ADE33B}.release|32.ActiveCfg = Release|Any CPU + {2347027E-E5DE-43C4-8EF9-5F1411ADE33B}.release|64.ActiveCfg = Release|Any CPU + {2347027E-E5DE-43C4-8EF9-5F1411ADE33B}.release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {718B8CBD-04FD-4F7D-AD45-199FF85332B1} + EndGlobalSection +EndGlobal diff --git a/projects/premake/temp-14.vcxproj b/projects/premake/temp-14.vcxproj new file mode 100644 index 0000000..83049be --- /dev/null +++ b/projects/premake/temp-14.vcxproj @@ -0,0 +1,271 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {ADCBAED8-19AB-2D74-22C3-B84A8E2194D5} + true + Win32Proj + temp-14 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + Unicode + v140 + true + + + Application + false + Unicode + v140 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\temp-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\temp-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\temp-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\temp-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/temp-14.vcxproj.filters b/projects/premake/temp-14.vcxproj.filters new file mode 100644 index 0000000..b7c4b15 --- /dev/null +++ b/projects/premake/temp-14.vcxproj.filters @@ -0,0 +1,212 @@ + + + + + {18D587F8-0477-B2CE-ED31-C622D972391F} + + + {BD5C5527-2973-53BD-72EA-DEDEDE3F2445} + + + {4633AC7A-B2BE-193F-BBCF-9C3327DA753F} + + + {EBAD437B-5763-BC70-E057-B6474C0CB374} + + + {5EA9B55C-CA69-3193-93A4-7A10FF23766F} + + + {B8A70EB0-A4A0-2D02-CDD2-1287B92A0D0E} + + + + + detail + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + + \ No newline at end of file diff --git a/projects/premake/temp-15.vcxproj b/projects/premake/temp-15.vcxproj new file mode 100644 index 0000000..ef4c29f --- /dev/null +++ b/projects/premake/temp-15.vcxproj @@ -0,0 +1,275 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {AECBAED8-1AAB-2D74-23C3-B84A8F2194D5} + true + Win32Proj + temp-15 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v141 + + + Application + true + Unicode + v141 + + + Application + false + Unicode + v141 + true + + + Application + false + Unicode + v141 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\temp-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\temp-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\temp-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\temp-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/temp-15.vcxproj.filters b/projects/premake/temp-15.vcxproj.filters new file mode 100644 index 0000000..b7c4b15 --- /dev/null +++ b/projects/premake/temp-15.vcxproj.filters @@ -0,0 +1,212 @@ + + + + + {18D587F8-0477-B2CE-ED31-C622D972391F} + + + {BD5C5527-2973-53BD-72EA-DEDEDE3F2445} + + + {4633AC7A-B2BE-193F-BBCF-9C3327DA753F} + + + {EBAD437B-5763-BC70-E057-B6474C0CB374} + + + {5EA9B55C-CA69-3193-93A4-7A10FF23766F} + + + {B8A70EB0-A4A0-2D02-CDD2-1287B92A0D0E} + + + + + detail + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + + \ No newline at end of file diff --git a/projects/premake/temp-16.vcxproj b/projects/premake/temp-16.vcxproj new file mode 100644 index 0000000..d978221 --- /dev/null +++ b/projects/premake/temp-16.vcxproj @@ -0,0 +1,263 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {AFCBAED8-1BAB-2D74-24C3-B84A902194D5} + true + Win32Proj + temp-16 + 10.0 + + + + Application + true + Unicode + v142 + + + Application + true + Unicode + v142 + + + Application + false + Unicode + v142 + true + + + Application + false + Unicode + v142 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\temp-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\temp-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\temp-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\temp-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/temp-16.vcxproj.filters b/projects/premake/temp-16.vcxproj.filters new file mode 100644 index 0000000..b7c4b15 --- /dev/null +++ b/projects/premake/temp-16.vcxproj.filters @@ -0,0 +1,212 @@ + + + + + {18D587F8-0477-B2CE-ED31-C622D972391F} + + + {BD5C5527-2973-53BD-72EA-DEDEDE3F2445} + + + {4633AC7A-B2BE-193F-BBCF-9C3327DA753F} + + + {EBAD437B-5763-BC70-E057-B6474C0CB374} + + + {5EA9B55C-CA69-3193-93A4-7A10FF23766F} + + + {B8A70EB0-A4A0-2D02-CDD2-1287B92A0D0E} + + + + + detail + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + + \ No newline at end of file diff --git a/projects/premake/temp-17.vcxproj b/projects/premake/temp-17.vcxproj new file mode 100644 index 0000000..892ba0d --- /dev/null +++ b/projects/premake/temp-17.vcxproj @@ -0,0 +1,267 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {B0CBAED8-1CAB-2D74-25C3-B84A912194D5} + true + Win32Proj + temp-17 + 10.0 + + + + Application + true + Unicode + v143 + + + Application + true + Unicode + v143 + + + Application + false + Unicode + v143 + true + + + Application + false + Unicode + v143 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\temp-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\temp-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\temp-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\temp-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/temp-17.vcxproj.filters b/projects/premake/temp-17.vcxproj.filters new file mode 100644 index 0000000..b7c4b15 --- /dev/null +++ b/projects/premake/temp-17.vcxproj.filters @@ -0,0 +1,212 @@ + + + + + {18D587F8-0477-B2CE-ED31-C622D972391F} + + + {BD5C5527-2973-53BD-72EA-DEDEDE3F2445} + + + {4633AC7A-B2BE-193F-BBCF-9C3327DA753F} + + + {EBAD437B-5763-BC70-E057-B6474C0CB374} + + + {5EA9B55C-CA69-3193-93A4-7A10FF23766F} + + + {B8A70EB0-A4A0-2D02-CDD2-1287B92A0D0E} + + + + + detail + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + + \ No newline at end of file diff --git a/projects/premake/temp-clang.vcxproj b/projects/premake/temp-clang.vcxproj new file mode 100644 index 0000000..a24e787 --- /dev/null +++ b/projects/premake/temp-clang.vcxproj @@ -0,0 +1,271 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {2DF246B5-19AA-8802-82B1-615E6E8823F3} + true + Win32Proj + temp-clang + 10.0 + + + + Application + true + Unicode + clangcl + + + Application + true + Unicode + clangcl + + + Application + false + Unicode + clangcl + true + + + Application + false + Unicode + clangcl + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\temp-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\temp-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\temp-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\temp-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/temp-clang.vcxproj.filters b/projects/premake/temp-clang.vcxproj.filters new file mode 100644 index 0000000..b7c4b15 --- /dev/null +++ b/projects/premake/temp-clang.vcxproj.filters @@ -0,0 +1,212 @@ + + + + + {18D587F8-0477-B2CE-ED31-C622D972391F} + + + {BD5C5527-2973-53BD-72EA-DEDEDE3F2445} + + + {4633AC7A-B2BE-193F-BBCF-9C3327DA753F} + + + {EBAD437B-5763-BC70-E057-B6474C0CB374} + + + {5EA9B55C-CA69-3193-93A4-7A10FF23766F} + + + {B8A70EB0-A4A0-2D02-CDD2-1287B92A0D0E} + + + + + detail + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\containers + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\features + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail\root + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\shared + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + detail\structure + + + + \ No newline at end of file diff --git a/projects/premake/test-14.vcxproj b/projects/premake/test-14.vcxproj new file mode 100644 index 0000000..735def2 --- /dev/null +++ b/projects/premake/test-14.vcxproj @@ -0,0 +1,298 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {37901DD9-A36F-9C74-AC87-274B18E602D6} + true + Win32Proj + test-14 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + Unicode + v140 + true + + + Application + false + Unicode + v140 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\test-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\test-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\test-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\test-14\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + true + Level3 + + + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/test-14.vcxproj.filters b/projects/premake/test-14.vcxproj.filters new file mode 100644 index 0000000..7925c89 --- /dev/null +++ b/projects/premake/test-14.vcxproj.filters @@ -0,0 +1,303 @@ + + + + + {C863C707-3419-40FD-BD0D-3AD429C23601} + + + {D53817DF-414F-1575-8AC6-A096F61BE6FC} + + + {F74E282B-E373-77AB-0CBF-5C3BF84276C9} + + + {3C8D1621-A846-81CB-31A6-9BA59D5E373B} + + + {05381925-71A6-6EA4-BA8F-29A4263D6440} + + + {2A2B469A-9643-2DC4-5FF0-BC5DCBC7C15D} + + + {5D724C46-C955-5B86-D258-89C23EBB21D7} + + + {57441CA8-4380-1F12-AC92-370998EDC72C} + + + {65689E7C-519F-9F0D-FA8B-8510E6A11B0F} + + + {0BE41589-7799-8E7E-008E-88556C428582} + + + + + development\ffsm2\detail + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2 + + + test + + + test + + + test + + + + + test + + + test\shared + + + test\shared + + + test\shared + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + \ No newline at end of file diff --git a/projects/premake/test-15.vcxproj b/projects/premake/test-15.vcxproj new file mode 100644 index 0000000..ea51789 --- /dev/null +++ b/projects/premake/test-15.vcxproj @@ -0,0 +1,302 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {38901DD9-A46F-9C74-AD87-274B19E602D6} + true + Win32Proj + test-15 + 10.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + 10.0.22621.0 + + + + Application + true + Unicode + v141 + + + Application + true + Unicode + v141 + + + Application + false + Unicode + v141 + true + + + Application + false + Unicode + v141 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\test-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\test-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\test-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\test-15\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp14 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp14 + true + Level3 + + + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/test-15.vcxproj.filters b/projects/premake/test-15.vcxproj.filters new file mode 100644 index 0000000..7925c89 --- /dev/null +++ b/projects/premake/test-15.vcxproj.filters @@ -0,0 +1,303 @@ + + + + + {C863C707-3419-40FD-BD0D-3AD429C23601} + + + {D53817DF-414F-1575-8AC6-A096F61BE6FC} + + + {F74E282B-E373-77AB-0CBF-5C3BF84276C9} + + + {3C8D1621-A846-81CB-31A6-9BA59D5E373B} + + + {05381925-71A6-6EA4-BA8F-29A4263D6440} + + + {2A2B469A-9643-2DC4-5FF0-BC5DCBC7C15D} + + + {5D724C46-C955-5B86-D258-89C23EBB21D7} + + + {57441CA8-4380-1F12-AC92-370998EDC72C} + + + {65689E7C-519F-9F0D-FA8B-8510E6A11B0F} + + + {0BE41589-7799-8E7E-008E-88556C428582} + + + + + development\ffsm2\detail + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2 + + + test + + + test + + + test + + + + + test + + + test\shared + + + test\shared + + + test\shared + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + \ No newline at end of file diff --git a/projects/premake/test-16.vcxproj b/projects/premake/test-16.vcxproj new file mode 100644 index 0000000..7e42ebd --- /dev/null +++ b/projects/premake/test-16.vcxproj @@ -0,0 +1,290 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {39901DD9-A56F-9C74-AE87-274B1AE602D6} + true + Win32Proj + test-16 + 10.0 + + + + Application + true + Unicode + v142 + + + Application + true + Unicode + v142 + + + Application + false + Unicode + v142 + true + + + Application + false + Unicode + v142 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\test-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\test-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\test-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\test-16\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + stdcpp17 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + stdcpp17 + true + Level3 + + + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/test-16.vcxproj.filters b/projects/premake/test-16.vcxproj.filters new file mode 100644 index 0000000..7925c89 --- /dev/null +++ b/projects/premake/test-16.vcxproj.filters @@ -0,0 +1,303 @@ + + + + + {C863C707-3419-40FD-BD0D-3AD429C23601} + + + {D53817DF-414F-1575-8AC6-A096F61BE6FC} + + + {F74E282B-E373-77AB-0CBF-5C3BF84276C9} + + + {3C8D1621-A846-81CB-31A6-9BA59D5E373B} + + + {05381925-71A6-6EA4-BA8F-29A4263D6440} + + + {2A2B469A-9643-2DC4-5FF0-BC5DCBC7C15D} + + + {5D724C46-C955-5B86-D258-89C23EBB21D7} + + + {57441CA8-4380-1F12-AC92-370998EDC72C} + + + {65689E7C-519F-9F0D-FA8B-8510E6A11B0F} + + + {0BE41589-7799-8E7E-008E-88556C428582} + + + + + development\ffsm2\detail + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2 + + + test + + + test + + + test + + + + + test + + + test\shared + + + test\shared + + + test\shared + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + \ No newline at end of file diff --git a/projects/premake/test-17.vcxproj b/projects/premake/test-17.vcxproj new file mode 100644 index 0000000..2d372ae --- /dev/null +++ b/projects/premake/test-17.vcxproj @@ -0,0 +1,294 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {3A901DD9-A66F-9C74-AF87-274B1BE602D6} + true + Win32Proj + test-17 + 10.0 + + + + Application + true + Unicode + v143 + + + Application + true + Unicode + v143 + + + Application + false + Unicode + v143 + true + + + Application + false + Unicode + v143 + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\test-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\test-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\test-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\test-17\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + /permissive- %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/test-17.vcxproj.filters b/projects/premake/test-17.vcxproj.filters new file mode 100644 index 0000000..7925c89 --- /dev/null +++ b/projects/premake/test-17.vcxproj.filters @@ -0,0 +1,303 @@ + + + + + {C863C707-3419-40FD-BD0D-3AD429C23601} + + + {D53817DF-414F-1575-8AC6-A096F61BE6FC} + + + {F74E282B-E373-77AB-0CBF-5C3BF84276C9} + + + {3C8D1621-A846-81CB-31A6-9BA59D5E373B} + + + {05381925-71A6-6EA4-BA8F-29A4263D6440} + + + {2A2B469A-9643-2DC4-5FF0-BC5DCBC7C15D} + + + {5D724C46-C955-5B86-D258-89C23EBB21D7} + + + {57441CA8-4380-1F12-AC92-370998EDC72C} + + + {65689E7C-519F-9F0D-FA8B-8510E6A11B0F} + + + {0BE41589-7799-8E7E-008E-88556C428582} + + + + + development\ffsm2\detail + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2 + + + test + + + test + + + test + + + + + test + + + test\shared + + + test\shared + + + test\shared + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + \ No newline at end of file diff --git a/projects/premake/test-clang.vcxproj b/projects/premake/test-clang.vcxproj new file mode 100644 index 0000000..5802019 --- /dev/null +++ b/projects/premake/test-clang.vcxproj @@ -0,0 +1,298 @@ + + + + + debug 32 + Win32 + + + debug 32 + x64 + + + debug 64 + Win32 + + + debug 64 + x64 + + + release 32 + Win32 + + + release 32 + x64 + + + release 64 + Win32 + + + release 64 + x64 + + + + {77E2BA72-639A-FCBF-CCA1-D51BB87897B0} + true + Win32Proj + test-clang + 10.0 + + + + Application + true + Unicode + clangcl + + + Application + true + Unicode + clangcl + + + Application + false + Unicode + clangcl + true + + + Application + false + Unicode + clangcl + true + + + + + + + + + + + + + + + + + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\debug\test-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + true + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\debug\test-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\32\release\test-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + false + ..\..\binaries-$(PlatformArchitecture)\ + $(BUILD_ROOT)\$(SolutionName)-$(PlatformArchitecture)\$(ProjectName)-$(Configuration)\64\release\test-clang\ + $(ProjectName)-$(Configuration)-$(PlatformArchitecture) + .exe + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;_DEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + NotUsing + Level4 + true + UNICODE;_UNICODE;NDEBUG;%(PreprocessorDefinitions) + ..\..\development;..\..\include;..\..\external;%(AdditionalIncludeDirectories) + MaxSpeed + true + true + false + true + -Wpedantic %(AdditionalOptions) + stdcpp20 + true + Level3 + + + Console + true + true + /INCREMENTAL:NO %(AdditionalOptions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/premake/test-clang.vcxproj.filters b/projects/premake/test-clang.vcxproj.filters new file mode 100644 index 0000000..7925c89 --- /dev/null +++ b/projects/premake/test-clang.vcxproj.filters @@ -0,0 +1,303 @@ + + + + + {C863C707-3419-40FD-BD0D-3AD429C23601} + + + {D53817DF-414F-1575-8AC6-A096F61BE6FC} + + + {F74E282B-E373-77AB-0CBF-5C3BF84276C9} + + + {3C8D1621-A846-81CB-31A6-9BA59D5E373B} + + + {05381925-71A6-6EA4-BA8F-29A4263D6440} + + + {2A2B469A-9643-2DC4-5FF0-BC5DCBC7C15D} + + + {5D724C46-C955-5B86-D258-89C23EBB21D7} + + + {57441CA8-4380-1F12-AC92-370998EDC72C} + + + {65689E7C-519F-9F0D-FA8B-8510E6A11B0F} + + + {0BE41589-7799-8E7E-008E-88556C428582} + + + + + development\ffsm2\detail + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\containers + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\features + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail\root + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\shared + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2\detail\structure + + + development\ffsm2 + + + test + + + test + + + test + + + + + test + + + test\shared + + + test\shared + + + test\shared + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + test + + + \ No newline at end of file diff --git a/projects/premake/tools.pyproj b/projects/premake/tools.pyproj new file mode 100644 index 0000000..8aa7869 --- /dev/null +++ b/projects/premake/tools.pyproj @@ -0,0 +1,42 @@ + + + Debug + 2.0 + 2347027e-e5de-43c4-8ef9-5f1411ade33b + . + ..\..\tools\join.py + + + ../../tools + Global|PythonCore|3.9 + Standard Python launcher + . + HFSM-tools + HFSM-tools + False + False + + + true + false + + + true + false + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/visual-studio/test-14.vcxproj b/projects/visual-studio/test-14.vcxproj index 3659ab2..daa1505 100644 --- a/projects/visual-studio/test-14.vcxproj +++ b/projects/visual-studio/test-14.vcxproj @@ -43,28 +43,43 @@ + - - - - + + + + + + + + - + + + + + + + - + + + - + + - + + @@ -72,19 +87,29 @@ - - - + + + + + + - + + + + + + + - + + diff --git a/projects/visual-studio/test-14.vcxproj.filters b/projects/visual-studio/test-14.vcxproj.filters index 364c4c1..d40b10e 100644 --- a/projects/visual-studio/test-14.vcxproj.filters +++ b/projects/visual-studio/test-14.vcxproj.filters @@ -36,30 +36,15 @@ ffsm2 - - ffsm2\detail - ffsm2\detail\containers ffsm2\detail\containers - - ffsm2\detail\containers - - - ffsm2\detail\features - ffsm2\detail\features - - ffsm2\detail\root - - - ffsm2\detail\root - ffsm2\detail\root @@ -87,23 +72,83 @@ ffsm2\detail\structure - + ffsm2\detail\structure - + + ffsm2\detail\root + + + test + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + ffsm2\detail\structure - + ffsm2\detail\structure - + + ffsm2\detail\structure + + + ffsm2\detail\structure + + ffsm2\detail\root - + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\features + + ffsm2\detail\structure - - test + + ffsm2\detail\structure + + + ffsm2\detail\structure @@ -178,24 +223,12 @@ test - - ffsm2\detail - ffsm2\detail\containers ffsm2\detail\containers - - ffsm2\detail\containers - - - ffsm2\detail\root - - - ffsm2\detail\root - ffsm2\detail\root @@ -211,9 +244,6 @@ ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\structure @@ -223,5 +253,50 @@ ffsm2\detail\root + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + \ No newline at end of file diff --git a/projects/visual-studio/test-15.vcxproj b/projects/visual-studio/test-15.vcxproj index 76b11e6..141c6b5 100644 --- a/projects/visual-studio/test-15.vcxproj +++ b/projects/visual-studio/test-15.vcxproj @@ -43,28 +43,43 @@ + - - - - + + + + + + + + - + + + + + + + - + + + - + + - + + @@ -72,19 +87,29 @@ - - - + + + + + + - + + + + + + + - + + diff --git a/projects/visual-studio/test-15.vcxproj.filters b/projects/visual-studio/test-15.vcxproj.filters index 9e77c7b..5302076 100644 --- a/projects/visual-studio/test-15.vcxproj.filters +++ b/projects/visual-studio/test-15.vcxproj.filters @@ -36,15 +36,6 @@ ffsm2 - - ffsm2\detail - - - ffsm2\detail\root - - - ffsm2\detail\root - ffsm2\detail\root @@ -72,18 +63,9 @@ ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\structure - - ffsm2\detail\structure - - - ffsm2\detail\features - ffsm2\detail\features @@ -93,18 +75,81 @@ ffsm2\detail\containers - - ffsm2\detail\containers - ffsm2\detail\root - - ffsm2\detail\structure - test + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + @@ -178,15 +223,6 @@ test - - ffsm2\detail - - - ffsm2\detail\root - - - ffsm2\detail\root - ffsm2\detail\root @@ -202,18 +238,12 @@ ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\containers ffsm2\detail\containers - - ffsm2\detail\containers - ffsm2\detail\structure @@ -223,5 +253,50 @@ ffsm2\detail\root + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + \ No newline at end of file diff --git a/projects/visual-studio/test-16.vcxproj b/projects/visual-studio/test-16.vcxproj index f2e9026..41f1c82 100644 --- a/projects/visual-studio/test-16.vcxproj +++ b/projects/visual-studio/test-16.vcxproj @@ -51,28 +51,43 @@ + - - - - + + + + + + + + - + + + + + + + - + + + - + + - + + @@ -80,19 +95,29 @@ - - - + + + + + + - + + + + + + + - + + diff --git a/projects/visual-studio/test-16.vcxproj.filters b/projects/visual-studio/test-16.vcxproj.filters index d34e102..322012d 100644 --- a/projects/visual-studio/test-16.vcxproj.filters +++ b/projects/visual-studio/test-16.vcxproj.filters @@ -36,15 +36,6 @@ ffsm2 - - ffsm2\detail - - - ffsm2\detail\root - - - ffsm2\detail\root - ffsm2\detail\root @@ -72,18 +63,9 @@ ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\structure - - ffsm2\detail\structure - - - ffsm2\detail\features - ffsm2\detail\features @@ -93,18 +75,81 @@ ffsm2\detail\containers - - ffsm2\detail\containers - ffsm2\detail\root - - ffsm2\detail\structure - test + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + @@ -178,15 +223,6 @@ test - - ffsm2\detail - - - ffsm2\detail\root - - - ffsm2\detail\root - ffsm2\detail\root @@ -202,18 +238,12 @@ ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\containers ffsm2\detail\containers - - ffsm2\detail\containers - ffsm2\detail\structure @@ -223,5 +253,50 @@ ffsm2\detail\root + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + \ No newline at end of file diff --git a/projects/visual-studio/test-17.vcxproj b/projects/visual-studio/test-17.vcxproj index 8ec7195..1e6e15a 100644 --- a/projects/visual-studio/test-17.vcxproj +++ b/projects/visual-studio/test-17.vcxproj @@ -27,28 +27,43 @@ + - - - - + + + + + + + + - + + + + + + + - + + + - + + - + + @@ -56,19 +71,29 @@ - - - + + + + + + - + + + + + + + - + + diff --git a/projects/visual-studio/test-17.vcxproj.filters b/projects/visual-studio/test-17.vcxproj.filters index 38eac61..b463f64 100644 --- a/projects/visual-studio/test-17.vcxproj.filters +++ b/projects/visual-studio/test-17.vcxproj.filters @@ -33,18 +33,9 @@ ffsm2 - - ffsm2\detail - - - ffsm2\detail\root - ffsm2\detail\root - - ffsm2\detail\root - ffsm2\detail\root @@ -69,24 +60,12 @@ ffsm2\detail\shared - - ffsm2\detail\structure - ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\structure - - ffsm2\detail\structure - - - ffsm2\detail\features - ffsm2\detail\features @@ -96,27 +75,84 @@ ffsm2\detail\containers - - ffsm2\detail\containers - test test - - - + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + ffsm2\detail - - + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + ffsm2\detail\root - - + + ffsm2\detail\root - - + + + ffsm2\detail\root + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + + ffsm2\detail\root @@ -140,21 +176,60 @@ ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\containers ffsm2\detail\containers - - ffsm2\detail\containers - test + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + diff --git a/projects/visual-studio/test-clang.vcxproj b/projects/visual-studio/test-clang.vcxproj index d426dc2..4897d36 100644 --- a/projects/visual-studio/test-clang.vcxproj +++ b/projects/visual-studio/test-clang.vcxproj @@ -51,28 +51,43 @@ + - - - - + + + + + + + + - + + + + + + + - + + + - + + - + + @@ -80,19 +95,29 @@ - - - + + + + + + - + + + + + + + - + + diff --git a/projects/visual-studio/test-clang.vcxproj.filters b/projects/visual-studio/test-clang.vcxproj.filters index 014c45b..d49912f 100644 --- a/projects/visual-studio/test-clang.vcxproj.filters +++ b/projects/visual-studio/test-clang.vcxproj.filters @@ -36,15 +36,6 @@ ffsm2 - - ffsm2\detail - - - ffsm2\detail\root - - - ffsm2\detail\root - ffsm2\detail\root @@ -72,18 +63,9 @@ ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\structure - - ffsm2\detail\structure - - - ffsm2\detail\features - ffsm2\detail\features @@ -93,18 +75,81 @@ ffsm2\detail\containers - - ffsm2\detail\containers - ffsm2\detail\root - - ffsm2\detail\structure - test + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\features + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\structure + @@ -178,15 +223,6 @@ test - - ffsm2\detail - - - ffsm2\detail\root - - - ffsm2\detail\root - ffsm2\detail\root @@ -202,18 +238,12 @@ ffsm2\detail\structure - - ffsm2\detail\structure - ffsm2\detail\containers ffsm2\detail\containers - - ffsm2\detail\containers - ffsm2\detail\structure @@ -223,5 +253,50 @@ ffsm2\detail\root + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail + + + ffsm2\detail\structure + + + ffsm2\detail\structure + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\root + + + ffsm2\detail\features + \ No newline at end of file diff --git a/test/test_plan_external.cpp b/test/test_plan_external.cpp index c570953..3375885 100644 --- a/test/test_plan_external.cpp +++ b/test/test_plan_external.cpp @@ -83,7 +83,7 @@ struct A void update(FullControl& control) { const auto plan = control.plan(); - auto it = plan.first(); + auto it = plan.begin(); REQUIRE(it); REQUIRE(*it == FSM::Task{ FSM::stateId(), FSM::stateId() }); diff --git a/test/test_plan_external_payloads.cpp b/test/test_plan_external_payloads.cpp index e5e0f60..84404c3 100644 --- a/test/test_plan_external_payloads.cpp +++ b/test/test_plan_external_payloads.cpp @@ -88,7 +88,7 @@ struct A void update(FullControl& control) { const auto plan = control.plan(); - auto it = plan.first(); + auto it = plan.begin(); REQUIRE(it); REQUIRE(*it == FSM::Task{ FSM::stateId(), FSM::stateId() }); diff --git a/test/test_plans.cpp b/test/test_plans.cpp index ded87e1..22f5044 100644 --- a/test/test_plans.cpp +++ b/test/test_plans.cpp @@ -90,7 +90,7 @@ struct A void enter(PlanControl& control) { const auto plan = control.plan(); - auto it = plan.first(); + auto it = plan.begin(); REQUIRE(it); REQUIRE(*it == FSM::Task{ FSM::stateId(), FSM::stateId() }); diff --git a/test/test_plans_payloads.cpp b/test/test_plans_payloads.cpp index fb35894..1468155 100644 --- a/test/test_plans_payloads.cpp +++ b/test/test_plans_payloads.cpp @@ -98,7 +98,7 @@ struct A void enter(PlanControl& control) { const auto plan = control.plan(); - auto it = plan.first(); + auto it = plan.begin(); REQUIRE(it); REQUIRE(*it == FSM::Task{ FSM::stateId(), FSM::stateId() }); diff --git a/test/test_plans_verbose.cpp b/test/test_plans_verbose.cpp index ac2cf07..ff0596b 100644 --- a/test/test_plans_verbose.cpp +++ b/test/test_plans_verbose.cpp @@ -97,7 +97,7 @@ struct A void enter(PlanControl& control) { const auto plan = control.plan(); - auto it = plan.first(); + auto it = plan.begin(); REQUIRE(it); REQUIRE(*it == FSM::Task{ FSM::stateId(), FSM::stateId() }); diff --git a/tools/join.py b/tools/join.py index 25187d5..0f89714 100644 --- a/tools/join.py +++ b/tools/join.py @@ -2,20 +2,20 @@ #=============================================================================== -def merge(folder, path, included, commentRE, output): +def merge(path, folder, lastLineEmpty, included, output, commentRE): pathTokens = path.split("/") current = folder + "/" + pathTokens[-1] with open(current, 'r', encoding='utf-8') as input: - lastLineEmpty = False - - if included: + if not lastLineEmpty: output.write("\n") lastLineEmpty = True for line in input: - if line.startswith('#include "'): - next = line[10 : -2] + hashIndex = line.find('#include "') + + if hashIndex != -1: + next = line[hashIndex + 10 : -2] if next not in included: nextTokens = next.split("/") @@ -24,10 +24,11 @@ def merge(folder, path, included, commentRE, output): #output.write("// inlined '" + pathTokens[-1] + "' -> '" + nextTokens[-1] + "'\n") if len(nextTokens) == 1: - merge(folder, next, included, commentRE, output) + lastLineEmpty = merge(next, folder, lastLineEmpty, included, output, commentRE) else: name = nextTokens.pop() - merge(folder + "/" + "/".join(nextTokens), name, included, commentRE, output) + subFolder = folder + "/" + "/".join(nextTokens) + lastLineEmpty = merge(name, subFolder, lastLineEmpty, included, output, commentRE) else: if line.startswith('\ufeff'): @@ -46,14 +47,14 @@ def merge(folder, path, included, commentRE, output): output.write(line) + return lastLineEmpty + #------------------------------------------------------------------------------- -output = open("../include/ffsm2/machine.hpp", 'w', encoding='utf-8-sig') -included = [] commentRE = re.compile("(?:\s*\/\/ COMMON)|(?:\s*\/\/ SPECIFIC)|(?:\s*\/\/\/\/)|(?:\s*\/\/--)|(?:\s*\/\/ -)") -merge("../development/ffsm2", "machine_dev.hpp", included, commentRE, output) - +output = open("../include/ffsm2/machine.hpp" , 'w', encoding='utf-8-sig') +merge("machine_dev.hpp" , "../development/ffsm2", True, [], output, commentRE) output.close() #===============================================================================