Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/modules/ROOT/attachments/backmp11/BackAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ class back_adapter : public boost::msm::backmp11::state_machine<
{
try
{
return Base::process_event(event);
return static_cast<boost::msm::back::HandledEnum>(
Base::process_event(event));
}
catch (std::exception& e)
{
Expand Down
11 changes: 5 additions & 6 deletions doc/modules/ROOT/attachments/backmp11/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,15 @@ class Logger : public back::default_observer

static std::string to_string(process_result result)
{
using Enum = boost::msm::back::HandledEnum;
switch (result)
{
case Enum::HANDLED_FALSE:
case process_result::discarded:
return "discarded";
case Enum::HANDLED_TRUE:
return "handled";
case Enum::HANDLED_GUARD_REJECT:
case process_result::consumed:
return "consumed";
case process_result::rejected:
return "rejected";
case Enum::HANDLED_DEFERRED:
case process_result::deferred:
return "deferred";
default:
return {};
Expand Down
2 changes: 1 addition & 1 deletion doc/modules/ROOT/pages/backmp11-back-end.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ Calling `start(...)` on an active or `stop(...)` on an inactive state machine ha

== Handling events

Use xref:reference:boost/msm/backmp11/state_machine/process_event.adoc[`process_result state_machine::process_event(const Event&)`] to start processing an event while the state machine is idle.
Use xref:reference:boost/msm/backmp11/state_machine/process_event.adoc[`process_result state_machine::process_event(const Event&)`] to trigger processing an event while the state machine is idle. The xref:reference:boost/msm/backmp11/process_result.adoc[`process_result`] enum returns the result of the processing attempt.

You can enqueue an event to the event pool for subsequent processing in an action with xref:reference:boost/msm/backmp11/state_machine/enqueue_event.adoc[`void state_machine::enqueue_event(const Event&)`]. The enqueued event will be processed immediately after the current event has finished processing.
If an event is enqueued while the state machine is idle, you can explicitly request the state machine to process events from its event pool with xref:reference:boost/msm/backmp11/state_machine/process_event_pool.adoc[`size_t process_event_pool(size_t max_events = SIZE_MAX)`].
Expand Down
6 changes: 3 additions & 3 deletions doc/modules/ROOT/pages/version-history.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
** Ensure basic exception guarantee and propagate exceptions to the caller (https://github.com/boostorg/msm/issues/221[#221])
** Provide a reflection API and serialization support for Boost.Serialization, Boost.JSON and nlohmann/json (https://github.com/boostorg/msm/issues/197[#197])
** Configurable event pool and inline storage (https://github.com/boostorg/msm/issues/239[#239])
** API reference and examples are now available
* Bug fixes (`backmp11`):
** State machine processes events although it is not running (https://github.com/boostorg/msm/issues/198[#198])
* **Breaking changes (`backmp11`)**:
** Events in `process_event(...)` are not enqueued automatically anymore to reduce memory footprint, use `enqueue_event(...)` in actions (https://github.com/boostorg/msm/issues/178[#178])
** The back-end does not forward constructor arguments to the front-end anymore, it must be default-constructible. To use custom constructors, define them in the back-end (https://github.com/boostorg/msm/issues/232[#232])
** The deprecated APIs `process_queued_events()` and `process_single_queued_event()` are removed, use `process_event_pool(...)` instead
** The default active state switch policy is set to "after source exit" in compliance to the UML specification. The other options are not UML-compliant and will be removed in version 1.93 (https://github.com/boostorg/msm/issues/222[#222])
* Documentation:
** API reference is now generated from source with MrDocs
** The default active state switch policy is set to "after source exit" in compliance to the UML specification. The other options are not UML-compliant and will be removed (https://github.com/boostorg/msm/issues/222[#222])
** The back-end uses its own `process_result` type with new enum values instead of aliasing the enum of the `back` namespace. The old enum values are deprecated (https://github.com/boostorg/msm/issues/242[#242]) and will be removed

== Boost 1.91

Expand Down
49 changes: 46 additions & 3 deletions include/boost/msm/backmp11/common_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
#include <cstdint>
#include <type_traits>

#include <boost/msm/back/common_types.hpp>

namespace boost::msm::backmp11
{

Expand All @@ -32,7 +30,52 @@ enum class machine_state : uint8_t
};

/// Return type of @ref state_machine::process_event calls.
using process_result = back::HandledEnum;
enum class process_result : uint8_t
{
/// No matching transition found, or the state machine was not ready.
///
/// The state machine is not ready when stopped or
/// already processing another event.
discarded = 0,
/// The event triggered at least one transition.
consumed = 1,
/// All matching guards evaluated to false, no transition fired.
rejected = 2,
/// The event will be re-evaluated after the next transition.
deferred = 4,

/// Deprecated enum values.
HANDLED_FALSE [[deprecated("Use discarded")]] = 0,
HANDLED_TRUE [[deprecated("Use accepted")]] = 1,
HANDLED_GUARD_REJECT [[deprecated("Use rejected")]] = 2,
HANDLED_DEFERRED [[deprecated("Use deferred")]] = 4
};

constexpr process_result operator|(process_result lhs, process_result rhs)
{
return static_cast<process_result>(
static_cast<std::underlying_type_t<process_result>>(lhs) |
static_cast<std::underlying_type_t<process_result>>(rhs));
}

constexpr process_result& operator|=(process_result& lhs, process_result rhs)
{
lhs = lhs | rhs;
return lhs;
}

constexpr process_result operator&(process_result lhs, process_result rhs)
{
return static_cast<process_result>(
static_cast<std::underlying_type_t<process_result>>(lhs) &
static_cast<std::underlying_type_t<process_result>>(rhs));
}

constexpr process_result& operator&=(process_result& lhs, process_result rhs)
{
lhs = lhs & rhs;
return lhs;
}

/// Default event when starting a state machine (see @ref state_machine::start).
struct starting {};
Expand Down
49 changes: 7 additions & 42 deletions include/boost/msm/backmp11/detail/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,8 @@
#ifndef BOOST_MSM_BACKMP11_DETAIL_COMMON_HPP
#define BOOST_MSM_BACKMP11_DETAIL_COMMON_HPP

#include <cstdint>

#include <boost/msm/backmp11/common_types.hpp>

namespace boost::msm::back
{

// Bitwise operations for process_result.
// Defined in this header instead of back because type_traits are C++11.
// Defined in the back namespace because the operations have to be in the
// same namespace as HandledEnum.

constexpr HandledEnum operator|(HandledEnum lhs, HandledEnum rhs)
{
return static_cast<HandledEnum>(
static_cast<std::underlying_type_t<HandledEnum>>(lhs) |
static_cast<std::underlying_type_t<HandledEnum>>(rhs));
}

constexpr HandledEnum& operator|=(HandledEnum& lhs, HandledEnum rhs)
{
lhs = lhs | rhs;
return lhs;
}

constexpr HandledEnum operator&(HandledEnum lhs, HandledEnum rhs)
{
return static_cast<HandledEnum>(
static_cast<std::underlying_type_t<HandledEnum>>(lhs) &
static_cast<std::underlying_type_t<HandledEnum>>(rhs));
}

constexpr HandledEnum& operator&=(HandledEnum& lhs, HandledEnum rhs)
{
lhs = lhs & rhs;
return lhs;
}

} // namespace boost::msm::back

namespace boost::msm::backmp11::detail
{

Expand Down Expand Up @@ -81,11 +43,14 @@ enum class process_info
event_pool
};

using process_result = back::HandledEnum;

// Bitmask for process result checks.
static constexpr process_result handled_true_or_deferred =
process_result::HANDLED_TRUE | process_result::HANDLED_DEFERRED;
constexpr process_result consumed_or_deferred =
process_result::consumed | process_result::deferred;

constexpr bool any(process_result result)
{
return result != process_result::discarded;
}

template <typename Policy, typename = void>
struct compile_policy_impl;
Expand Down
4 changes: 2 additions & 2 deletions include/boost/msm/backmp11/detail/event_pool_processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class event_pool_processor
}

// Consider anything except "only deferred" to be a processed event.
if (*result != process_result::HANDLED_DEFERRED)
if (*result != process_result::deferred)
{
processed_events++;
if (processed_events == max_events)
Expand All @@ -175,7 +175,7 @@ class event_pool_processor
// (required to prevent infinitely processing the same event,
// if it was handled and at the same time action-deferred
// in orthogonal regions).
if (!(*result & process_result::HANDLED_DEFERRED))
if (!(any(*result & process_result::deferred)))
{
m_event_pool.cur_seq_cnt += 1;
}
Expand Down
14 changes: 7 additions & 7 deletions include/boost/msm/backmp11/detail/favor_runtime_speed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ struct compile_policy_impl<
using table = dispatch_impl<typename Policy::dispatch_strategy>;
return table::dispatch(sm, region_id, event);
}
return process_result::HANDLED_FALSE;
return process_result::discarded;
}

// Dispatch an event to the SM's internal table.
Expand All @@ -147,7 +147,7 @@ struct compile_policy_impl<
{
return internal_dispatch_impl::transition::process(sm, event);
}
return process_result::HANDLED_FALSE;
return process_result::discarded;
}

private:
Expand Down Expand Up @@ -330,7 +330,7 @@ struct compile_policy_impl<
const Event& event)
{
const auto state_id = sm.m_active_state_ids[region_id];
process_result result = process_result::HANDLED_FALSE;
process_result result = process_result::discarded;
mp11::mp_for_each<typename base::merged_transitions>(
[&sm, region_id, &event, state_id, &result](auto transition)
{
Expand Down Expand Up @@ -367,7 +367,7 @@ struct compile_policy_impl<
{
return cell(sm, region_id, event);
}
return process_result::HANDLED_FALSE;
return process_result::discarded;
}

private:
Expand Down Expand Up @@ -410,17 +410,17 @@ struct compile_policy_impl<

static process_result process(StateMachine& sm, Event const& evt)
{
process_result result = process_result::HANDLED_FALSE;
process_result result = process_result::discarded;
mp_for_each_until<Transitions>(
[&result, &sm, &evt](auto transition)
{
using Transition = decltype(transition);
result |= Transition::process(sm, evt);
if (result & handled_true_or_deferred)
if (any(result & consumed_or_deferred))
{
// If a guard rejected previously,
// ensure this bit is not present.
result &= handled_true_or_deferred;
result &= consumed_or_deferred;
return true;
}
return false;
Expand Down
4 changes: 4 additions & 0 deletions include/boost/msm/backmp11/detail/metafunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,10 @@ struct is_state_blocking_impl
template<typename T>
using is_state_blocking = typename is_state_blocking_impl<T>::type;

// Helper to print types within metafunctions for debugging.
template <typename... Ts>
struct [[deprecated]] print_types {};

} // boost::msm::backmp11::detail

#endif // BOOST_MSM_BACKMP11_DETAIL_METAFUNCTIONS_HPP
Loading
Loading