mirror of
https://github.com/boostorg/msm.git
synced 2026-07-21 13:23:45 +00:00
Refactor tests (#2)
* Extracted traits into a separate header to include multiple backends at once * Refactored tests to test multiple variations of backends with the same test code * Added test cases with back::favor_compile_time for existing tests * Removed redundant Back11 tests
This commit is contained in:
committed by
GitHub
parent
33e77cbfc7
commit
7753fa0170
@@ -25,11 +25,10 @@
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/msm/event_traits.hpp>
|
||||
#include <boost/msm/back/traits.hpp>
|
||||
#include <boost/msm/back/metafunctions.hpp>
|
||||
#include <boost/msm/back/common_types.hpp>
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(is_frow)
|
||||
|
||||
namespace boost { namespace msm { namespace back
|
||||
{
|
||||
|
||||
|
||||
@@ -57,20 +57,7 @@
|
||||
#include <boost/msm/mpl_graph/incidence_list_graph.hpp>
|
||||
#include <boost/msm/mpl_graph/depth_first_search.hpp>
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_creation)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_exit)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(concrete_exit_state)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(composite_tag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(not_real_row_tag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(event_blocking_flag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_entry_state)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(completion_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_exception_thrown)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_message_queue)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(activate_deferred_events)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(wrapped_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(active_state_switch_policy)
|
||||
#include <boost/msm/back/traits.hpp>
|
||||
|
||||
namespace boost { namespace msm { namespace back
|
||||
{
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <boost/msm/active_state_switching_policies.hpp>
|
||||
#include <boost/msm/row_tags.hpp>
|
||||
#include <boost/msm/msm_grammar.hpp>
|
||||
#include <boost/msm/back/traits.hpp>
|
||||
#include <boost/msm/back/fold_to_list.hpp>
|
||||
#include <boost/msm/back/metafunctions.hpp>
|
||||
#include <boost/msm/back/history_policies.hpp>
|
||||
@@ -66,20 +67,6 @@
|
||||
#include <boost/msm/back/no_fsm_check.hpp>
|
||||
#include <boost/msm/back/queue_container_deque.hpp>
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(non_forwarding_flag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(initial_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(final_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(do_serialize)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(history_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(fsm_check)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(compile_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(queue_container_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(using_declared_table)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(event_queue_before_deferred_queue)
|
||||
|
||||
#ifndef BOOST_MSM_CONSTRUCTOR_ARG_SIZE
|
||||
#define BOOST_MSM_CONSTRUCTOR_ARG_SIZE 5 // default max number of arguments for constructors
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2008 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACK_TRAITS_H
|
||||
#define BOOST_MSM_BACK_TRAITS_H
|
||||
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
// Metafunctions
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_creation)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_exit)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(concrete_exit_state)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(composite_tag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(not_real_row_tag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(event_blocking_flag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_entry_state)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(completion_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_exception_thrown)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_message_queue)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(activate_deferred_events)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(wrapped_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(active_state_switch_policy)
|
||||
|
||||
// State machine
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(non_forwarding_flag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(initial_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(final_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(do_serialize)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(history_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(fsm_check)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(compile_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(queue_container_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(using_declared_table)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(event_queue_before_deferred_queue)
|
||||
|
||||
// Dispatch table
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(is_frow)
|
||||
|
||||
#endif // BOOST_MSM_BACK_TRAITS_H
|
||||
@@ -31,11 +31,10 @@
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/msm/event_traits.hpp>
|
||||
#include <boost/msm/back/traits.hpp>
|
||||
#include <boost/msm/back11/metafunctions.hpp>
|
||||
#include <boost/msm/back/common_types.hpp>
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(is_frow)
|
||||
|
||||
namespace boost { namespace msm { namespace back11
|
||||
{
|
||||
|
||||
|
||||
@@ -69,20 +69,7 @@
|
||||
#include <boost/msm/mpl_graph/incidence_list_graph.hpp>
|
||||
#include <boost/msm/mpl_graph/depth_first_search.hpp>
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_creation)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_exit)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(concrete_exit_state)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(composite_tag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(not_real_row_tag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(event_blocking_flag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_entry_state)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(completion_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_exception_thrown)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_message_queue)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(activate_deferred_events)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(wrapped_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(active_state_switch_policy)
|
||||
#include <boost/msm/back/traits.hpp>
|
||||
|
||||
namespace boost { namespace msm { namespace back11
|
||||
{
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include <boost/msm/active_state_switching_policies.hpp>
|
||||
#include <boost/msm/row_tags.hpp>
|
||||
#include <boost/msm/msm_grammar.hpp>
|
||||
#include <boost/msm/back/traits.hpp>
|
||||
#include <boost/msm/back/fold_to_list.hpp>
|
||||
#include <boost/msm/back11/metafunctions.hpp>
|
||||
#include <boost/msm/back/history_policies.hpp>
|
||||
@@ -69,20 +70,6 @@
|
||||
#include <boost/msm/back/queue_container_deque.hpp>
|
||||
#include <boost/msm/back11/dispatch_table.hpp>
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(non_forwarding_flag)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(initial_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(final_event)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(do_serialize)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(history_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(fsm_check)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(compile_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(queue_container_policy)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(using_declared_table)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(event_queue_before_deferred_queue)
|
||||
|
||||
#ifndef BOOST_MSM_CONSTRUCTOR_ARG_SIZE
|
||||
#define BOOST_MSM_CONSTRUCTOR_ARG_SIZE 5 // default max number of arguments for constructors
|
||||
#endif
|
||||
@@ -449,7 +436,7 @@ private:
|
||||
BOOST_ASSERT(state == (current_state));
|
||||
// if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
|
||||
if (has_pseudo_exit<T1>::type::value &&
|
||||
!is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
|
||||
!back11::is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
|
||||
{
|
||||
return ::boost::msm::back::HANDLED_FALSE;
|
||||
}
|
||||
@@ -530,7 +517,7 @@ private:
|
||||
|
||||
// if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
|
||||
if (has_pseudo_exit<T1>::type::value &&
|
||||
!is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
|
||||
!back11::is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
|
||||
{
|
||||
return ::boost::msm::back::HANDLED_FALSE;
|
||||
}
|
||||
@@ -595,7 +582,7 @@ private:
|
||||
|
||||
// if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
|
||||
if (has_pseudo_exit<T1>::type::value &&
|
||||
!is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
|
||||
!back11::is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
|
||||
{
|
||||
return ::boost::msm::back::HANDLED_FALSE;
|
||||
}
|
||||
@@ -662,7 +649,7 @@ private:
|
||||
|
||||
// if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
|
||||
if (has_pseudo_exit<T1>::type::value &&
|
||||
!is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
|
||||
!back11::is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
|
||||
{
|
||||
return ::boost::msm::back::HANDLED_FALSE;
|
||||
}
|
||||
|
||||
+19
-19
@@ -9,12 +9,12 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE anonymous_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -136,12 +136,12 @@ namespace
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<my_machine_> my_machine;
|
||||
typedef get_test_machines<my_machine_> my_machines;
|
||||
|
||||
//static char const* const state_names[] = { "State1", "State2", "State3", "State4" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( anonymous_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE ( anonymous_test, my_machine, my_machines )
|
||||
{
|
||||
my_machine p;
|
||||
|
||||
@@ -149,13 +149,13 @@ namespace
|
||||
// in this case it will also immediately trigger all anonymous transitions
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"State4 should be active"); //State4
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().exit_counter == 1,"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().entry_counter == 1,"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State4&>().entry_counter == 1,"State4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State3&>().exit_counter == 1,"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State3&>().entry_counter == 1,"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State4&>().entry_counter == 1,"State4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.always_true_counter == 1,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.always_false_counter == 1,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.state2_to_state3_counter == 1,"action not called correctly");
|
||||
@@ -165,14 +165,14 @@ namespace
|
||||
// this event will bring us back to the initial state and thus, a new "loop" will be started
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"State4 should be active"); //State4
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 2,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 2,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 2,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().exit_counter == 2,"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().entry_counter == 2,"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State4&>().entry_counter == 2,"State4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State4&>().exit_counter == 1,"State4 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().exit_counter == 2,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().exit_counter == 2,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().entry_counter == 2,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State3&>().exit_counter == 2,"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State3&>().entry_counter == 2,"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State4&>().entry_counter == 2,"State4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State4&>().exit_counter == 1,"State4 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.always_true_counter == 2,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.always_false_counter == 2,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.state2_to_state3_counter == 2,"action not called correctly");
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
#include <boost/msm/front/euml/common.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
@@ -23,7 +23,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_anonymous_and_guard_test
|
||||
#define BOOST_TEST_MODULE anonymous_and_guard_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -86,9 +86,9 @@ struct Bug : public bmf::state_machine_def<Bug> {
|
||||
};
|
||||
|
||||
// backend
|
||||
typedef boost::msm::back::state_machine<Bug> MyStateMachine;
|
||||
typedef get_test_machines<Bug> MyStateMachines;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_anonymous_and_guard_test1)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(anonymous_and_guard_test1, MyStateMachine, MyStateMachines)
|
||||
{
|
||||
MyStateMachine sm;
|
||||
sm.start();
|
||||
@@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE(back11_anonymous_and_guard_test1)
|
||||
BOOST_CHECK_MESSAGE(sm.current_state()[1] == 3, "Completed should be active");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_anonymous_and_guard_test2)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(anonymous_and_guard_test2, MyStateMachine, MyStateMachines)
|
||||
{
|
||||
MyStateMachine sm;
|
||||
sm.start();
|
||||
+18
-18
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE anonymous_euml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -107,11 +107,11 @@ namespace
|
||||
my_machine_) //fsm name
|
||||
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<my_machine_> my_machine;
|
||||
typedef get_test_machines<my_machine_> my_machines;
|
||||
|
||||
//static char const* const state_names[] = { "State1", "State2", "State3", "State4" };
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( anonymous_euml_test, my_machine, my_machines )
|
||||
{
|
||||
my_machine p;
|
||||
|
||||
@@ -119,19 +119,19 @@ namespace
|
||||
// in this case it will also immediately trigger all anonymous transitions
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"State4 should be active"); //State4
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State1)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State1)&>().get_attribute(exit_counter) == 1,
|
||||
"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State1)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State1)&>().get_attribute(entry_counter) == 1,
|
||||
"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State2)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State2)&>().get_attribute(exit_counter) == 1,
|
||||
"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State2)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State2)&>().get_attribute(entry_counter) == 1,
|
||||
"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State3)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State3)&>().get_attribute(exit_counter) == 1,
|
||||
"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State3)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State3)&>().get_attribute(entry_counter) == 1,
|
||||
"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State4)&>().get_attribute(entry_counter)== 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State4)&>().get_attribute(entry_counter)== 1,
|
||||
"State4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(always_true_counter) == 1,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(always_false_counter) == 1,"guard not called correctly");
|
||||
@@ -142,19 +142,19 @@ namespace
|
||||
// this event will bring us back to the initial state and thus, a new "loop" will be started
|
||||
p.process_event(event1);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"State4 should be active"); //State4
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State1)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State1)&>().get_attribute(exit_counter) == 2,
|
||||
"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State1)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State1)&>().get_attribute(entry_counter) == 2,
|
||||
"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State2)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State2)&>().get_attribute(exit_counter) == 2,
|
||||
"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State2)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State2)&>().get_attribute(entry_counter) == 2,
|
||||
"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State3)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State3)&>().get_attribute(exit_counter) == 2,
|
||||
"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State3)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State3)&>().get_attribute(entry_counter) == 2,
|
||||
"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(State4)&>().get_attribute(entry_counter)== 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(State4)&>().get_attribute(entry_counter)== 2,
|
||||
"State4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(always_true_counter) == 2,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(always_false_counter) == 2,"guard not called correctly");
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_anonymous_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace boost::msm::front;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct event1 {};
|
||||
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct my_machine_ : public msm::front::state_machine_def<my_machine_>
|
||||
{
|
||||
unsigned int state2_to_state3_counter;
|
||||
unsigned int state3_to_state4_counter;
|
||||
unsigned int always_true_counter;
|
||||
unsigned int always_false_counter;
|
||||
|
||||
my_machine_():
|
||||
state2_to_state3_counter(0),
|
||||
state3_to_state4_counter(0),
|
||||
always_true_counter(0),
|
||||
always_false_counter(0)
|
||||
{}
|
||||
|
||||
// The list of FSM states
|
||||
struct State1 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct State2 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
struct State3 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
struct State4 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef State1 initial_state;
|
||||
|
||||
// transition actions
|
||||
void State2ToState3(none const&) { ++state2_to_state3_counter; }
|
||||
void State3ToState4(none const&) { ++state3_to_state4_counter; }
|
||||
// guard conditions
|
||||
bool always_true(none const& )
|
||||
{
|
||||
++always_true_counter;
|
||||
return true;
|
||||
}
|
||||
bool always_false(none const& )
|
||||
{
|
||||
++always_false_counter;
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef my_machine_ p; // makes transition table cleaner
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
_row < State1 , none , State2 >,
|
||||
a_row < State2 , none , State3 , &p::State2ToState3 >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
row < State3 , none , State4 , &p::State3ToState4 , &p::always_true >,
|
||||
g_row < State3 , none , State4 , &p::always_false >,
|
||||
_row < State4 , event1 , State1 >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const&, FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<my_machine_::State1&>().entry_counter=0;
|
||||
fsm.template get_state<my_machine_::State1&>().exit_counter=0;
|
||||
fsm.template get_state<my_machine_::State2&>().entry_counter=0;
|
||||
fsm.template get_state<my_machine_::State2&>().exit_counter=0;
|
||||
fsm.template get_state<my_machine_::State3&>().entry_counter=0;
|
||||
fsm.template get_state<my_machine_::State3&>().exit_counter=0;
|
||||
fsm.template get_state<my_machine_::State4&>().entry_counter=0;
|
||||
fsm.template get_state<my_machine_::State4&>().exit_counter=0;
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<my_machine_> my_machine;
|
||||
|
||||
//static char const* const state_names[] = { "State1", "State2", "State3", "State4" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_anonymous_test )
|
||||
{
|
||||
my_machine p;
|
||||
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
// in this case it will also immediately trigger all anonymous transitions
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"State4 should be active"); //State4
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().exit_counter == 1,"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().entry_counter == 1,"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State4&>().entry_counter == 1,"State4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.always_true_counter == 1,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.always_false_counter == 1,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.state2_to_state3_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.state3_to_state4_counter == 1,"action not called correctly");
|
||||
|
||||
|
||||
// this event will bring us back to the initial state and thus, a new "loop" will be started
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"State4 should be active"); //State4
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 2,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 2,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 2,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().exit_counter == 2,"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().entry_counter == 2,"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State4&>().entry_counter == 2,"State4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State4&>().exit_counter == 1,"State4 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.always_true_counter == 2,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.always_false_counter == 2,"guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.state2_to_state3_counter == 2,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.state3_to_state4_counter == 2,"action not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_big_with_functors_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace boost::msm::front;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct event1 {};
|
||||
struct event2 {};
|
||||
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct my_machine_ : public msm::front::state_machine_def<my_machine_>
|
||||
{
|
||||
|
||||
my_machine_()
|
||||
{}
|
||||
|
||||
// The list of FSM states
|
||||
struct State1 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State2 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State3 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State4 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State5 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State6 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State7 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State8 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State9 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State10 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State11 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
struct State12 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef State1 initial_state;
|
||||
|
||||
// transition actions
|
||||
|
||||
// guard conditions
|
||||
|
||||
typedef my_machine_ p; // makes transition table cleaner
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
_row < State1 , event1 , State2 >,
|
||||
_row < State2 , event1 , State3 >,
|
||||
_row < State3 , event1 , State4 >,
|
||||
_row < State4 , event1 , State5 >,
|
||||
_row < State5 , event1 , State6 >,
|
||||
_row < State6 , event1 , State7 >,
|
||||
_row < State7 , event1 , State8 >,
|
||||
_row < State8 , event1 , State9 >,
|
||||
_row < State9 , event1 , State10 >,
|
||||
_row < State10 , event1 , State11 >,
|
||||
_row < State11 , event1 , State12 >,
|
||||
|
||||
_row < State12 , event2 , State11 >,
|
||||
_row < State11 , event2 , State10 >,
|
||||
_row < State10 , event2 , State9 >,
|
||||
_row < State9 , event2 , State8 >,
|
||||
_row < State8 , event2 , State7 >,
|
||||
_row < State7 , event2 , State6 >,
|
||||
_row < State6 , event2 , State5 >,
|
||||
_row < State5 , event2 , State4 >,
|
||||
_row < State4 , event2 , State3 >,
|
||||
_row < State3 , event2 , State2 >,
|
||||
_row < State2 , event2 , State1 >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const&, FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM&)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<my_machine_> my_machine;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_big_with_functors_test )
|
||||
{
|
||||
my_machine p;
|
||||
|
||||
// needed to start the highest-level SM.
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active"); //State1
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 0,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State5&>().exit_counter == 0,"State5 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State5&>().entry_counter == 0,"State5 entry not called correctly");
|
||||
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 11,"State12 should be active"); //State12
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State12&>().exit_counter == 0,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State7&>().exit_counter == 1,"State7 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State7&>().entry_counter == 1,"State7 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State10&>().exit_counter == 1,"State10 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State10&>().entry_counter == 1,"State10 entry not called correctly");
|
||||
|
||||
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
p.process_event(event2());
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active"); //State1
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 2,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 2,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State7&>().exit_counter == 2,"State7 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State7&>().entry_counter == 2,"State7 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State10&>().exit_counter == 2,"State10 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State10&>().entry_counter == 2,"State10 entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_entries_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
namespace fusion = boost::fusion;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct event1 {};
|
||||
struct event2 {};
|
||||
struct event3 {};
|
||||
struct event4 {};
|
||||
struct event5 {};
|
||||
struct event6
|
||||
{
|
||||
event6(){}
|
||||
template <class Event>
|
||||
event6(Event const&){}
|
||||
};
|
||||
// front-end: define the FSM structure
|
||||
struct Fsm_ : public msm::front::state_machine_def<Fsm_>
|
||||
{
|
||||
// The list of FSM states
|
||||
struct State1 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct State2 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct SubFsm2_ : public msm::front::state_machine_def<SubFsm2_>
|
||||
{
|
||||
typedef msm::back11::state_machine<SubFsm2_> SubFsm2;
|
||||
|
||||
unsigned int entry_action_counter;
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
|
||||
struct SubState1 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct SubState1b : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct SubState2 : public msm::front::state<> , public msm::front::explicit_entry<0>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct SubState2b : public msm::front::state<> , public msm::front::explicit_entry<1>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
// test with a pseudo entry
|
||||
struct PseudoEntry1 : public msm::front::entry_pseudo_state<0>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct SubState3 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct PseudoExit1 : public msm::front::exit_pseudo_state<event6>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
// action methods
|
||||
void entry_action(event4 const&)
|
||||
{
|
||||
++entry_action_counter;
|
||||
}
|
||||
// the initial state. Must be defined
|
||||
typedef fusion::vector<SubState1,SubState1b> initial_state;
|
||||
|
||||
typedef fusion::vector<SubState2b> explicit_creation;
|
||||
|
||||
// Transition table for SubFsm2
|
||||
struct transition_table : fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +--------------+-------------+------------+------------------------+----------------------+
|
||||
a_row < PseudoEntry1 , event4 , SubState3 ,&SubFsm2_::entry_action >,
|
||||
_row < SubState2 , event6 , SubState1 >,
|
||||
_row < SubState3 , event5 , PseudoExit1 >
|
||||
// +--------------+-------------+------------+------------------------+----------------------+
|
||||
> {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const& , FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
};
|
||||
typedef msm::back11::state_machine<SubFsm2_> SubFsm2;
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef State1 initial_state;
|
||||
|
||||
// transition actions
|
||||
// guard conditions
|
||||
|
||||
// Transition table for Fsm
|
||||
struct transition_table : fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------------------+--------+------------------------------------+-------+--------+
|
||||
_row < State1 , event1 , SubFsm2 >,
|
||||
_row < State1 , event2 , SubFsm2::direct<SubFsm2_::SubState2> >,
|
||||
_row < State1 , event3 , fusion::vector<SubFsm2::direct<SubFsm2_::SubState2>,
|
||||
SubFsm2::direct<SubFsm2_::SubState2b> > >,
|
||||
_row < State1 , event4 , SubFsm2::entry_pt
|
||||
<SubFsm2_::PseudoEntry1> >,
|
||||
// +---------------------+--------+------------------------------------+-------+--------+
|
||||
_row < SubFsm2 , event1 , State1 >,
|
||||
_row < SubFsm2::exit_pt
|
||||
<SubFsm2_::PseudoExit1>, event6 , State2 >
|
||||
// +---------------------+--------+------------------------------------+-------+--------+
|
||||
> {};
|
||||
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const& , FSM&,int )
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<Fsm_::State1&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::State1&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::State2&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::State2&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().entry_action_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState1&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState1&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState1b&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState1b&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState2&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState2&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState2b&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState2b&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState3&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState3&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::PseudoEntry1&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::PseudoEntry1&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::exit_pt<SubFsm2_::PseudoExit1>&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::exit_pt<SubFsm2_::PseudoExit1>&>().exit_counter=0;
|
||||
|
||||
}
|
||||
};
|
||||
typedef msm::back11::state_machine<Fsm_> Fsm;
|
||||
// static char const* const state_names[] = { "State1", "SubFsm2","State2" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_entries_test )
|
||||
{
|
||||
Fsm p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().exit_counter == 1,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_counter == 1,"SubFsm2 entry not called correctly");
|
||||
|
||||
p.process_event(event2());
|
||||
p.process_event(event6());
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().exit_counter == 2,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().entry_counter == 3,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().exit_counter == 2,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_counter == 2,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2&>().entry_counter == 1,
|
||||
"SubFsm2::SubState2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2&>().exit_counter == 1,
|
||||
"SubFsm2::SubState2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState1&>().entry_counter == 2,
|
||||
"SubFsm2::SubState1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState1&>().exit_counter == 2,
|
||||
"SubFsm2::SubState1 exit not called correctly");
|
||||
|
||||
p.process_event(event3());
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().exit_counter == 3,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().entry_counter == 4,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().exit_counter == 3,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_counter == 3,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2&>().entry_counter == 2,
|
||||
"SubFsm2::SubState2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2&>().exit_counter == 2,
|
||||
"SubFsm2::SubState2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2b&>().entry_counter == 1,
|
||||
"SubFsm2::SubState2b entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2b&>().exit_counter == 1,
|
||||
"SubFsm2::SubState2b exit not called correctly");
|
||||
|
||||
p.process_event(event4());
|
||||
p.process_event(event5());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"State2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().exit_counter == 4,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().exit_counter == 4,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_counter == 4,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::PseudoEntry1&>().entry_counter == 1,
|
||||
"SubFsm2::PseudoEntry1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::PseudoEntry1&>().exit_counter == 1,
|
||||
"SubFsm2::PseudoEntry1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState3&>().entry_counter == 1,
|
||||
"SubFsm2::SubState3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState3&>().exit_counter == 1,
|
||||
"SubFsm2::SubState3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2::exit_pt<Fsm_::SubFsm2_::PseudoExit1>&>().entry_counter == 1,
|
||||
"SubFsm2::PseudoExit1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2::exit_pt<Fsm_::SubFsm2_::PseudoExit1>&>().exit_counter == 1,
|
||||
"SubFsm2::PseudoExit1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_action_counter == 1,"Action not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,358 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE Back11HistoryTest
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct play {};
|
||||
struct end_pause {};
|
||||
struct stop {};
|
||||
struct pause {};
|
||||
struct open_close {};
|
||||
struct NextSong {};
|
||||
struct PreviousSong {};
|
||||
struct cd_detected
|
||||
{
|
||||
cd_detected(std::string name)
|
||||
: name(name)
|
||||
{}
|
||||
std::string name;
|
||||
};
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
|
||||
player_():
|
||||
start_playback_counter(0),
|
||||
can_close_drawer_counter(0)
|
||||
{}
|
||||
// The list of FSM states
|
||||
struct Empty : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct Open : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// sm_ptr still supported but deprecated as functors are a much better way to do the same thing
|
||||
struct Stopped : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
unsigned int start_next_song_counter;
|
||||
unsigned int start_prev_song_guard_counter;
|
||||
|
||||
Playing_():
|
||||
start_next_song_counter(0),
|
||||
start_prev_song_guard_counter(0)
|
||||
{}
|
||||
|
||||
// The list of FSM states
|
||||
struct Song1 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct Song2 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct Song3 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
// the initial state. Must be defined
|
||||
typedef Song1 initial_state;
|
||||
// transition actions
|
||||
void start_next_song(NextSong const&) {++start_next_song_counter; }
|
||||
void start_prev_song(PreviousSong const&) { }
|
||||
// guard conditions
|
||||
bool start_prev_song_guard(PreviousSong const&) {++start_prev_song_guard_counter;return true; }
|
||||
|
||||
typedef Playing_ pl; // makes transition table cleaner
|
||||
// Transition table for Playing
|
||||
struct transition_table : mpl::vector4<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
_row < Song1 , NextSong , Song2 >,
|
||||
row < Song2 , PreviousSong, Song1 , &pl::start_prev_song,&pl::start_prev_song_guard>,
|
||||
a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
|
||||
g_row < Song3 , PreviousSong, Song2 ,&pl::start_prev_song_guard>
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const&, FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back11::state_machine<
|
||||
Playing_,
|
||||
msm::back11::state_machine<player_>,
|
||||
msm::back::ShallowHistory<mpl::vector<end_pause> > > Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef Empty initial_state;
|
||||
|
||||
// transition actions
|
||||
void start_playback(play const&) {++start_playback_counter; }
|
||||
void open_drawer(open_close const&) { }
|
||||
void store_cd_info(cd_detected const&) { }
|
||||
void stop_playback(stop const&) { }
|
||||
void pause_playback(pause const&) { }
|
||||
void resume_playback(end_pause const&) { }
|
||||
void stop_and_open(open_close const&) { }
|
||||
void stopped_again(stop const&){}
|
||||
//guards
|
||||
bool can_close_drawer(open_close const&)
|
||||
{
|
||||
++can_close_drawer_counter;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
typedef player_ p; // makes transition table cleaner
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : mpl::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Stopped , play , Playing , &p::start_playback >,
|
||||
a_row < Stopped , open_close , Open , &p::open_drawer >,
|
||||
_row < Stopped , stop , Stopped >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
g_row < Open , open_close , Empty , &p::can_close_drawer >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Empty , open_close , Open , &p::open_drawer >,
|
||||
a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Playing , stop , Stopped , &p::stop_playback >,
|
||||
a_row < Playing , pause , Paused , &p::pause_playback >,
|
||||
a_row < Playing , open_close , Open , &p::stop_and_open >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Paused , end_pause , Playing , &p::resume_playback >,
|
||||
a_row < Paused , stop , Stopped , &p::stop_playback >,
|
||||
a_row < Paused , open_close , Open , &p::stop_and_open >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const& , FSM&,int )
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
}
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Back11HistoryTest)
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().exit_counter == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().entry_counter == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().exit_counter == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(PreviousSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().exit_counter == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
"submachine guard not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 3,
|
||||
"Song2 entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 2,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
#include <boost/fusion/include/std_tuple.hpp>
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
// functors
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
// for And_ operator
|
||||
#include <boost/msm/front/operator.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_kleene_deferred_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace msm::front;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct event1 {};
|
||||
struct event2 {};
|
||||
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct fsm_ : public msm::front::state_machine_def<fsm_>
|
||||
{
|
||||
// we want deferred events and no state requires deferred events (only the fsm in the
|
||||
// transition table), so the fsm does.
|
||||
typedef int activate_deferred_events;
|
||||
|
||||
// The list of FSM states
|
||||
struct StateA : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter=0;
|
||||
int exit_counter = 0;
|
||||
};
|
||||
struct StateB : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter = 0;
|
||||
int exit_counter = 0;
|
||||
};
|
||||
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef StateA initial_state;
|
||||
|
||||
struct is_event1
|
||||
{
|
||||
template <class EVT, class FSM, class SourceState, class TargetState>
|
||||
bool operator()(EVT const& evt, FSM&, SourceState&, TargetState&)
|
||||
{
|
||||
bool is_deferred = boost::any_cast<event1>(&evt) != 0;
|
||||
return is_deferred;
|
||||
}
|
||||
};
|
||||
|
||||
typedef fsm_ p; // makes transition table cleaner
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
Row < StateA , event1 , StateB , none , none >,
|
||||
Row < StateB , boost::any , none , Defer , is_event1 >,
|
||||
Row < StateB , event2 , StateA , none , none >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
>/*>::type*/ {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const&, FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<fsm_> Fsm;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_kleene_deferred_test)
|
||||
{
|
||||
Fsm fsm;
|
||||
|
||||
fsm.start();
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateA&>().entry_counter == 1,"StateA entry not called correctly");
|
||||
|
||||
fsm.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(fsm.current_state()[0] == 1,"StateB should be active");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateA&>().exit_counter == 1,"StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateB&>().entry_counter == 1,"StateB entry not called correctly");
|
||||
|
||||
fsm.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(fsm.current_state()[0] == 1, "StateB should be active");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateA&>().exit_counter == 1, "StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateB&>().entry_counter == 1, "StateB entry not called correctly");
|
||||
|
||||
fsm.process_event(event2());
|
||||
BOOST_CHECK_MESSAGE(fsm.current_state()[0] == 1, "StateB should be active");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateA&>().exit_counter == 2, "StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateB&>().entry_counter == 2, "StateB entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
// Copyright 2024 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_many_deferred_transitions
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace msmf = boost::msm::front;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
namespace
|
||||
{
|
||||
// ----- Events
|
||||
struct Event1 {};
|
||||
struct Event2 {};
|
||||
struct Event3 {};
|
||||
struct Event4 {};
|
||||
|
||||
// ----- State machine
|
||||
struct Sm1_ :msmf::state_machine_def<Sm1_> {
|
||||
|
||||
// States
|
||||
struct State1 :msmf::state<> {
|
||||
template <class Event, class Fsm>
|
||||
void on_entry(Event const&, Fsm&) const {
|
||||
}
|
||||
};
|
||||
struct State2 :msmf::state<> {
|
||||
template <class Event, class Fsm>
|
||||
void on_entry(Event const&, Fsm&) const {
|
||||
}
|
||||
};
|
||||
struct State3 :msmf::state<> {
|
||||
template <class Event, class Fsm>
|
||||
void on_entry(Event const&, Fsm&) const {
|
||||
}
|
||||
};
|
||||
struct State4 :msmf::state<> {
|
||||
template <class Event, class Fsm>
|
||||
void on_entry(Event const&, Fsm&) const {
|
||||
}
|
||||
};
|
||||
struct State5 :msmf::state<> {
|
||||
template <class Event, class Fsm>
|
||||
void on_entry(Event const&, Fsm&) const {
|
||||
}
|
||||
};
|
||||
// Set initial state
|
||||
typedef State1 initial_state;
|
||||
// Enable deferred capability
|
||||
typedef int activate_deferred_events;
|
||||
// Transition table
|
||||
struct transition_table :mpl::vector<
|
||||
// Start Event Next Action Guard
|
||||
msmf::Row < State1, Event1, msmf::none, msmf::Defer>,
|
||||
msmf::Row < State1, Event2, msmf::none, msmf::Defer>,
|
||||
msmf::Row < State1, Event3, msmf::none, msmf::Defer>,
|
||||
msmf::Row < State1, Event4, State2 , msmf::none>,
|
||||
|
||||
msmf::Row < State2, Event3, msmf::none, msmf::Defer>,
|
||||
msmf::Row < State2, Event1, msmf::none, msmf::Defer>,
|
||||
msmf::Row < State2, Event2, State3 , msmf::none>,
|
||||
|
||||
msmf::Row < State3, Event1, State4 , msmf::none>,
|
||||
msmf::Row < State3, Event3, State5 , msmf::none>,
|
||||
msmf::Row < State4, Event3, State5 , msmf::none>,
|
||||
msmf::Row < State5, Event1, State4 , msmf::none>
|
||||
> {};
|
||||
|
||||
template <class Fsm, class Event>
|
||||
void no_transition(Event const&, Fsm&, int /*state*/) {
|
||||
}
|
||||
};
|
||||
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<Sm1_> Sm1;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_many_deferred_transitions)
|
||||
{
|
||||
Sm1 sm1;
|
||||
sm1.start();
|
||||
sm1.process_event(Event1());
|
||||
sm1.process_event(Event2());
|
||||
sm1.process_event(Event3());
|
||||
sm1.process_event(Event4());
|
||||
|
||||
BOOST_CHECK_MESSAGE(sm1.current_state()[0] == 4, "State5 should be active");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,509 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_orthogonal_deferred3_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace boost::msm::front;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct play {};
|
||||
struct end_pause {};
|
||||
struct stop {};
|
||||
struct pause {};
|
||||
struct open_close {};
|
||||
struct NextSong {};
|
||||
struct PreviousSong {};
|
||||
struct error_found {};
|
||||
struct end_error {};
|
||||
struct do_terminate {};
|
||||
|
||||
// Flags. Allow information about a property of the current state
|
||||
struct PlayingPaused{};
|
||||
struct CDLoaded {};
|
||||
struct FirstSongPlaying {};
|
||||
|
||||
// A "complicated" event type that carries some data.
|
||||
struct cd_detected
|
||||
{
|
||||
cd_detected(std::string name)
|
||||
: name(name)
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
// we want deferred events and no state requires deferred events (only the fsm in the
|
||||
// transition table), so the fsm does.
|
||||
typedef int activate_deferred_events;
|
||||
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
unsigned int report_error_counter;
|
||||
unsigned int report_end_error_counter;
|
||||
|
||||
player_():
|
||||
start_playback_counter(0),
|
||||
can_close_drawer_counter(0),
|
||||
report_error_counter(0),
|
||||
report_end_error_counter(0)
|
||||
{}
|
||||
// The list of FSM states
|
||||
struct Empty : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct Open : public msm::front::state<>
|
||||
{
|
||||
typedef boost::fusion::vector<CDLoaded> flag_list;
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
struct Stopped : public msm::front::state<>
|
||||
{
|
||||
typedef boost::fusion::vector<CDLoaded> flag_list;
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// the player state machine contains a state which is himself a state machine
|
||||
// as you see, no need to declare it anywhere so Playing can be developed separately
|
||||
// by another team in another module. For simplicity I just declare it inside player
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
// when playing, the CD is loaded and we are in either pause or playing (duh)
|
||||
typedef boost::fusion::vector<PlayingPaused,CDLoaded> flag_list;
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
unsigned int start_next_song_counter;
|
||||
unsigned int start_prev_song_guard_counter;
|
||||
|
||||
Playing_():
|
||||
start_next_song_counter(0),
|
||||
start_prev_song_guard_counter(0)
|
||||
{}
|
||||
|
||||
// The list of FSM states
|
||||
struct Song1 : public msm::front::state<>
|
||||
{
|
||||
typedef boost::fusion::vector<FirstSongPlaying> flag_list;
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct Song2 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct Song3 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
// the initial state. Must be defined
|
||||
typedef Song1 initial_state;
|
||||
// transition actions
|
||||
void start_next_song(NextSong const&) {++start_next_song_counter; }
|
||||
void start_prev_song(PreviousSong const&) { }
|
||||
// guard conditions
|
||||
bool start_prev_song_guard(PreviousSong const&) {++start_prev_song_guard_counter;return true; }
|
||||
|
||||
typedef Playing_ pl; // makes transition table cleaner
|
||||
// Transition table for Playing
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
_row < Song1 , NextSong , Song2 >,
|
||||
row < Song2 , PreviousSong, Song1 , &pl::start_prev_song,&pl::start_prev_song_guard>,
|
||||
a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
|
||||
g_row < Song3 , PreviousSong, Song2 ,&pl::start_prev_song_guard>
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const&, FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back11::state_machine<Playing_> Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
{
|
||||
typedef boost::fusion::vector<PlayingPaused,CDLoaded> flag_list;
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct AllOk : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
// this state is also made terminal so that all the events are blocked
|
||||
struct ErrorMode : //public msm::front::terminate_state<> // ErrorMode terminates the state machine
|
||||
public msm::front::interrupt_state<end_error/*boost::fusion::vector<end_error>*/> // ErroMode just interrupts. Will resume if
|
||||
// the event end_error is generated
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct ErrorTerminate : public msm::front::terminate_state<> // terminates the state machine
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef boost::fusion::vector<Empty,AllOk> initial_state;
|
||||
|
||||
// transition actions
|
||||
void start_playback(play const&) {++start_playback_counter; }
|
||||
void open_drawer(open_close const&) { }
|
||||
void store_cd_info(cd_detected const&) { }
|
||||
void stop_playback(stop const&) { }
|
||||
void pause_playback(pause const&) { }
|
||||
void resume_playback(end_pause const&) { }
|
||||
void stop_and_open(open_close const&) { }
|
||||
void stopped_again(stop const&){}
|
||||
void report_error(error_found const&) {++report_error_counter;}
|
||||
void report_end_error(end_error const&) {++report_end_error_counter;}
|
||||
|
||||
//guards
|
||||
bool can_close_drawer(open_close const&)
|
||||
{
|
||||
++can_close_drawer_counter;
|
||||
return true;
|
||||
}
|
||||
struct is_play_event
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
bool operator()(EVT const& evt,FSM&,SourceState& ,TargetState& )
|
||||
{
|
||||
bool is_play = boost::any_cast<play>(&evt) != 0;
|
||||
return is_play;
|
||||
}
|
||||
};
|
||||
struct MyDefer
|
||||
{
|
||||
// mark as deferring to avoid stack overflows in certain conditions
|
||||
typedef int deferring_action;
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& ) const
|
||||
{
|
||||
fsm.defer_event(play());
|
||||
}
|
||||
};
|
||||
typedef player_ p; // makes transition table cleaner
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Stopped , play , Playing , &p::start_playback >,
|
||||
a_row < Stopped , open_close , Open , &p::open_drawer >,
|
||||
_row < Stopped , stop , Stopped >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
g_row < Open , open_close , Empty , &p::can_close_drawer >,
|
||||
Row < Open , play , none , Defer , none >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Empty , open_close , Open , &p::open_drawer >,
|
||||
a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
|
||||
Row < Empty , boost::any , none , MyDefer , is_play_event >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Playing , stop , Stopped , &p::stop_playback >,
|
||||
a_row < Playing , pause , Paused , &p::pause_playback >,
|
||||
a_row < Playing , open_close , Open , &p::stop_and_open >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Paused , end_pause , Playing , &p::resume_playback >,
|
||||
a_row < Paused , stop , Stopped , &p::stop_playback >,
|
||||
a_row < Paused , open_close , Open , &p::stop_and_open >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
|
||||
a_row <ErrorMode, end_error ,AllOk , &p::report_end_error >,
|
||||
_row < AllOk , do_terminate,ErrorTerminate >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const& , FSM&,int)
|
||||
{
|
||||
BOOST_ERROR("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<player_::AllOk&>().entry_counter=0;
|
||||
fsm.template get_state<player_::AllOk&>().exit_counter=0;
|
||||
fsm.template get_state<player_::ErrorMode&>().entry_counter=0;
|
||||
fsm.template get_state<player_::ErrorMode&>().exit_counter=0;
|
||||
fsm.template get_state<player_::ErrorTerminate&>().entry_counter=0;
|
||||
fsm.template get_state<player_::ErrorTerminate&>().exit_counter=0;
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
|
||||
//static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode" };
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_orthogonal_deferred3_test )
|
||||
{
|
||||
player p;
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
p.start();
|
||||
// test deferred event
|
||||
// deferred in Empty and Open, will be handled only after event cd_detected
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 0,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded>() == false,"CDLoaded should not be active");
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
//deferred event should have been processed
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<FirstSongPlaying>() == true,"FirstSongPlaying should be active");
|
||||
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().exit_counter == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().entry_counter == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().exit_counter == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(PreviousSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().exit_counter == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
"submachine guard not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<FirstSongPlaying>() == false,"FirstSongPlaying should not be active");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded,player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
//test interrupt
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(error_found());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().exit_counter == 1,"ErrorMode exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().entry_counter == 2,"AllOk entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 3,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 3,"Playing entry not called correctly");
|
||||
|
||||
//test terminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(do_terminate());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 2,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorTerminate&>().entry_counter == 1,"ErrorTerminate entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorTerminate&>().exit_counter == 0,"ErrorTerminate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/puml/puml.hpp>
|
||||
|
||||
#include <PumlCommon.hpp>
|
||||
#include "PumlCommon.hpp"
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_orthogonal_deferred3_with_puml_test
|
||||
|
||||
@@ -1,253 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_simple_internal_euml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::msm::front::euml;
|
||||
namespace msm = boost::msm;
|
||||
|
||||
namespace
|
||||
{
|
||||
// A "complicated" event type that carries some data.
|
||||
enum DiskTypeEnum
|
||||
{
|
||||
DISK_CD=0,
|
||||
DISK_DVD=1
|
||||
};
|
||||
// events
|
||||
BOOST_MSM_EUML_EVENT(play)
|
||||
BOOST_MSM_EUML_EVENT(end_pause)
|
||||
BOOST_MSM_EUML_EVENT(stop)
|
||||
BOOST_MSM_EUML_EVENT(pause)
|
||||
BOOST_MSM_EUML_EVENT(open_close)
|
||||
BOOST_MSM_EUML_EVENT(internal_evt)
|
||||
BOOST_MSM_EUML_EVENT(to_ignore)
|
||||
// A "complicated" event type that carries some data.
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,cd_name)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(DiskTypeEnum,cd_type)
|
||||
BOOST_MSM_EUML_ATTRIBUTES((attributes_ << cd_name << cd_type ), cd_detected_attributes)
|
||||
BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(cd_detected,cd_detected_attributes)
|
||||
|
||||
//states
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,entry_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,exit_counter)
|
||||
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Open)
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Stopped)
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Playing)
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Paused)
|
||||
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,empty_internal_guard_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,empty_internal_action_counter)
|
||||
|
||||
BOOST_MSM_EUML_ACTION(internal_guard_fct)
|
||||
{
|
||||
template <class FSM,class EVT,class SourceState,class TargetState>
|
||||
bool operator()(EVT const&, FSM& ,SourceState& src,TargetState& )
|
||||
{
|
||||
++src.get_attribute(empty_internal_guard_counter);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
BOOST_MSM_EUML_DECLARE_STATE((++state_(entry_counter),++state_(exit_counter),
|
||||
attributes_ << entry_counter << exit_counter
|
||||
<< empty_internal_guard_counter << empty_internal_action_counter),Empty_def)
|
||||
// derive to be able to add an internal transition table
|
||||
struct Empty_impl : public Empty_def
|
||||
{
|
||||
Empty_impl(){}
|
||||
BOOST_MSM_EUML_DECLARE_INTERNAL_TRANSITION_TABLE((
|
||||
internal_evt [internal_guard_fct] / ++source_(empty_internal_action_counter)
|
||||
))
|
||||
};
|
||||
// declare an instance for the stt as we are manually declaring a state
|
||||
Empty_impl const Empty;
|
||||
|
||||
//fsm
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_playback_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,can_close_drawer_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,internal_action_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,internal_guard_counter)
|
||||
BOOST_MSM_EUML_ACTION(No_Transition)
|
||||
{
|
||||
template <class FSM,class Event>
|
||||
void operator()(Event const&,FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
};
|
||||
BOOST_MSM_EUML_ACTION(good_disk_format)
|
||||
{
|
||||
template <class FSM,class EVT,class SourceState,class TargetState>
|
||||
bool operator()(EVT const& evt,FSM&,SourceState& ,TargetState& )
|
||||
{
|
||||
if (evt.get_attribute(cd_type)!=DISK_CD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
BOOST_MSM_EUML_ACTION(internal_guard)
|
||||
{
|
||||
template <class FSM,class EVT,class SourceState,class TargetState>
|
||||
bool operator()(EVT const&,FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++fsm.get_attribute(internal_guard_counter);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
BOOST_MSM_EUML_ACTION(internal_guard2)
|
||||
{
|
||||
template <class FSM,class EVT,class SourceState,class TargetState>
|
||||
bool operator()(EVT const&,FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++fsm.get_attribute(internal_guard_counter);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
BOOST_MSM_EUML_TRANSITION_TABLE((
|
||||
Playing == Stopped + play / ++fsm_(start_playback_counter) ,
|
||||
Playing == Paused + end_pause ,
|
||||
// +------------------------------------------------------------------------------+
|
||||
Empty == Open + open_close / ++fsm_(can_close_drawer_counter),
|
||||
Empty + to_ignore ,
|
||||
Empty + internal_evt [internal_guard2] / ++fsm_(internal_action_counter) ,
|
||||
Empty + cd_detected [internal_guard] ,
|
||||
// +------------------------------------------------------------------------------+
|
||||
Open == Empty + open_close ,
|
||||
Open == Paused + open_close ,
|
||||
Open == Stopped + open_close ,
|
||||
Open == Playing + open_close ,
|
||||
// +------------------------------------------------------------------------------+
|
||||
Paused == Playing + pause ,
|
||||
// +------------------------------------------------------------------------------+
|
||||
Stopped == Playing + stop ,
|
||||
Stopped == Paused + stop ,
|
||||
Stopped == Empty + cd_detected [good_disk_format] ,
|
||||
Stopped == Stopped + stop
|
||||
// +------------------------------------------------------------------------------+
|
||||
),transition_table)
|
||||
|
||||
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
|
||||
init_ << Empty, // Init State
|
||||
no_action, // Entry
|
||||
no_action, // Exit
|
||||
attributes_ << start_playback_counter << can_close_drawer_counter
|
||||
<< internal_action_counter << internal_guard_counter, // Attributes
|
||||
configure_ << no_configure_, // configuration
|
||||
No_Transition // no_transition handler
|
||||
),
|
||||
player_) //fsm name
|
||||
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Paused", "Open", "Empty", "Playing" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_simple_internal_euml_test )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(entry_counter) == 1,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
// internal events
|
||||
p.process_event(to_ignore);
|
||||
p.process_event(internal_evt);
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(internal_action_counter) == 1,"Internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(internal_guard_counter) == 1,"Internal guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(empty_internal_action_counter) == 0,
|
||||
"Empty internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(empty_internal_guard_counter) == 1,
|
||||
"Empty internal guard not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(exit_counter) == 1,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(entry_counter) == 1,
|
||||
"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(can_close_drawer_counter) == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
p.process_event(play);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(exit_counter) == 2,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,331 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#include <boost/msm/front/euml/common.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_simple_internal_functors_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
namespace msm = boost::msm;
|
||||
using namespace msm::front;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct play {};
|
||||
struct end_pause {};
|
||||
struct stop {};
|
||||
struct pause {};
|
||||
struct open_close {};
|
||||
struct internal_evt {};
|
||||
struct to_ignore {};
|
||||
|
||||
// A "complicated" event type that carries some data.
|
||||
enum DiskTypeEnum
|
||||
{
|
||||
DISK_CD=0,
|
||||
DISK_DVD=1
|
||||
};
|
||||
struct cd_detected
|
||||
{
|
||||
cd_detected(std::string name, DiskTypeEnum diskType)
|
||||
: name(name),
|
||||
disc_type(diskType)
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
DiskTypeEnum disc_type;
|
||||
};
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
unsigned int internal_action_counter;
|
||||
unsigned int internal_guard_counter;
|
||||
|
||||
player_():
|
||||
start_playback_counter(0),
|
||||
can_close_drawer_counter(0),
|
||||
internal_action_counter(0),
|
||||
internal_guard_counter(0)
|
||||
{}
|
||||
|
||||
// The list of FSM states
|
||||
struct Empty : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
unsigned int empty_internal_guard_counter;
|
||||
unsigned int empty_internal_action_counter;
|
||||
struct internal_guard_fct
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
bool operator()(EVT const& ,FSM&,SourceState& src,TargetState& )
|
||||
{
|
||||
++src.empty_internal_guard_counter;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
struct internal_action_fct
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& ,SourceState& src,TargetState& )
|
||||
{
|
||||
++src.empty_internal_action_counter;
|
||||
}
|
||||
};
|
||||
// Transition table for Empty
|
||||
struct internal_transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
Internal < internal_evt , internal_action_fct ,internal_guard_fct >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
};
|
||||
struct Open : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// sm_ptr still supported but deprecated as functors are a much better way to do the same thing
|
||||
struct Stopped : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
struct Playing : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef Empty initial_state;
|
||||
|
||||
// transition actions
|
||||
void start_playback(play const&) {++start_playback_counter; }
|
||||
void open_drawer(open_close const&) { }
|
||||
void store_cd_info(cd_detected const&) { }
|
||||
void stop_playback(stop const&) { }
|
||||
void pause_playback(pause const&) { }
|
||||
void resume_playback(end_pause const&) { }
|
||||
void stop_and_open(open_close const&) { }
|
||||
void stopped_again(stop const&){}
|
||||
struct internal_action
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++fsm.internal_action_counter;
|
||||
}
|
||||
};
|
||||
struct internal_guard
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
bool operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++fsm.internal_guard_counter;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
struct internal_guard2
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
bool operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++fsm.internal_guard_counter;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// guard conditions
|
||||
bool good_disk_format(cd_detected const& evt)
|
||||
{
|
||||
// to test a guard condition, let's say we understand only CDs, not DVD
|
||||
if (evt.disc_type != DISK_CD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool can_close_drawer(open_close const&)
|
||||
{
|
||||
++can_close_drawer_counter;
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef player_ p; // makes transition table cleaner
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Stopped , play , Playing , &p::start_playback >,
|
||||
a_row < Stopped , open_close , Open , &p::open_drawer >,
|
||||
_row < Stopped , stop , Stopped >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
g_row < Open , open_close , Empty , &p::can_close_drawer >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Empty , open_close , Open , &p::open_drawer >,
|
||||
row < Empty , cd_detected , Stopped , &p::store_cd_info ,&p::good_disk_format >,
|
||||
Row < Empty , internal_evt, none , internal_action ,internal_guard2 >,
|
||||
Row < Empty , to_ignore , none , none , none >,
|
||||
Row < Empty , cd_detected , none , none ,internal_guard >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Playing , stop , Stopped , &p::stop_playback >,
|
||||
a_row < Playing , pause , Paused , &p::pause_playback >,
|
||||
a_row < Playing , open_close , Open , &p::stop_and_open >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Paused , end_pause , Playing , &p::resume_playback >,
|
||||
a_row < Paused , stop , Stopped , &p::stop_playback >,
|
||||
a_row < Paused , open_close , Open , &p::stop_and_open >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const&, FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().empty_internal_guard_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().empty_internal_action_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
}
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_simple_internal_functors_test )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
// internal events
|
||||
p.process_event(to_ignore());
|
||||
p.process_event(internal_evt());
|
||||
BOOST_CHECK_MESSAGE(p.internal_action_counter == 1,"Internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 1,"Internal guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().empty_internal_action_counter == 0,"Empty internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().empty_internal_guard_counter == 1,"Empty internal guard not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 2,"Internal guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 3,"Internal guard not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_simple_machine_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct play {};
|
||||
struct end_pause {};
|
||||
struct stop {};
|
||||
struct pause {};
|
||||
struct open_close {};
|
||||
|
||||
// A "complicated" event type that carries some data.
|
||||
enum DiskTypeEnum
|
||||
{
|
||||
DISK_CD=0,
|
||||
DISK_DVD=1
|
||||
};
|
||||
struct cd_detected
|
||||
{
|
||||
cd_detected(std::string name, DiskTypeEnum diskType)
|
||||
: name(name),
|
||||
disc_type(diskType)
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
DiskTypeEnum disc_type;
|
||||
};
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
|
||||
player_():
|
||||
start_playback_counter(0),
|
||||
can_close_drawer_counter(0)
|
||||
{}
|
||||
|
||||
// The list of FSM states
|
||||
struct Empty : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct Open : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// sm_ptr still supported but deprecated as functors are a much better way to do the same thing
|
||||
struct Stopped : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
struct Playing : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef Empty initial_state;
|
||||
|
||||
// transition actions
|
||||
void start_playback(play const&) {++start_playback_counter; }
|
||||
void open_drawer(open_close const&) { }
|
||||
void store_cd_info(cd_detected const&) { }
|
||||
void stop_playback(stop const&) { }
|
||||
void pause_playback(pause const&) { }
|
||||
void resume_playback(end_pause const&) { }
|
||||
void stop_and_open(open_close const&) { }
|
||||
void stopped_again(stop const&){}
|
||||
// guard conditions
|
||||
bool good_disk_format(cd_detected const& evt)
|
||||
{
|
||||
// to test a guard condition, let's say we understand only CDs, not DVD
|
||||
if (evt.disc_type != DISK_CD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool can_close_drawer(open_close const&)
|
||||
{
|
||||
++can_close_drawer_counter;
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef player_ p; // makes transition table cleaner
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Stopped , play , Playing , &p::start_playback >,
|
||||
a_row < Stopped , open_close , Open , &p::open_drawer >,
|
||||
_row < Stopped , stop , Stopped >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
g_row < Open , open_close , Empty , &p::can_close_drawer >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Empty , open_close , Open , &p::open_drawer >,
|
||||
row < Empty , cd_detected , Stopped , &p::store_cd_info ,&p::good_disk_format >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Playing , stop , Stopped , &p::stop_playback >,
|
||||
a_row < Playing , pause , Paused , &p::pause_playback >,
|
||||
a_row < Playing , open_close , Open , &p::stop_and_open >,
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
a_row < Paused , end_pause , Playing , &p::resume_playback >,
|
||||
a_row < Paused , stop , Stopped , &p::stop_playback >,
|
||||
a_row < Paused , open_close , Open , &p::stop_and_open >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const& , FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
}
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_simple_machine_test )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,367 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
#include <boost/fusion/include/std_tuple.hpp>
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
// functors
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
// for And_ operator
|
||||
#include <boost/msm/front/operator.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_simple_with_functors_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace msm::front;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct play {int cpt_ = 0;};
|
||||
struct end_pause {int cpt_ = 0;};
|
||||
struct stop {};
|
||||
struct pause {};
|
||||
struct open_close {};
|
||||
|
||||
// A "complicated" event type that carries some data.
|
||||
enum DiskTypeEnum
|
||||
{
|
||||
DISK_CD=0,
|
||||
DISK_DVD=1
|
||||
};
|
||||
struct cd_detected
|
||||
{
|
||||
cd_detected(std::string name, DiskTypeEnum diskType)
|
||||
: name(name),
|
||||
disc_type(diskType)
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
DiskTypeEnum disc_type;
|
||||
};
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
unsigned int test_fct_counter;
|
||||
|
||||
player_():
|
||||
start_playback_counter(0),
|
||||
can_close_drawer_counter(0),
|
||||
test_fct_counter(0)
|
||||
{}
|
||||
|
||||
// The list of FSM states
|
||||
struct Empty : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct Open : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// sm_ptr still supported but deprecated as functors are a much better way to do the same thing
|
||||
struct Stopped : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
struct Playing : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const& e,FSM& )
|
||||
{
|
||||
++entry_counter;
|
||||
event_counter = e.cpt_;
|
||||
}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
int event_counter=0;
|
||||
};
|
||||
|
||||
struct Paused : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef Empty initial_state;
|
||||
|
||||
// transition actions
|
||||
struct TestFct
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT& e, FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++e.cpt_;
|
||||
++fsm.test_fct_counter;
|
||||
}
|
||||
};
|
||||
struct start_playback
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++fsm.start_playback_counter;
|
||||
}
|
||||
};
|
||||
struct open_drawer
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
|
||||
{
|
||||
}
|
||||
};
|
||||
struct close_drawer
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
|
||||
{
|
||||
}
|
||||
};
|
||||
struct store_cd_info
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const&,FSM& fsm ,SourceState& ,TargetState& )
|
||||
{
|
||||
fsm.process_event(play());
|
||||
}
|
||||
};
|
||||
struct stop_playback
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
|
||||
{
|
||||
}
|
||||
};
|
||||
struct pause_playback
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
|
||||
{
|
||||
}
|
||||
};
|
||||
struct resume_playback
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT& e,FSM& ,SourceState& ,TargetState& )
|
||||
{
|
||||
++e.cpt_;
|
||||
}
|
||||
};
|
||||
struct stop_and_open
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
|
||||
{
|
||||
}
|
||||
};
|
||||
struct stopped_again
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
|
||||
{
|
||||
}
|
||||
};
|
||||
// guard conditions
|
||||
struct DummyGuard
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
bool operator()(EVT const&,FSM&,SourceState&,TargetState&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct good_disk_format
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
bool operator()(EVT& evt ,FSM&,SourceState& ,TargetState& )
|
||||
{
|
||||
// to test a guard condition, let's say we understand only CDs, not DVD
|
||||
if (evt.disc_type != DISK_CD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct always_true
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
bool operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct can_close_drawer
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
bool operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++fsm.can_close_drawer_counter;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef player_ p; // makes transition table cleaner
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
Row < Stopped , play , Playing , ActionSequence_
|
||||
<boost::fusion::vector<
|
||||
TestFct,start_playback> >
|
||||
, DummyGuard >,
|
||||
Row < Stopped , open_close , Open , open_drawer , none >,
|
||||
Row < Stopped , stop , Stopped , none , none >,
|
||||
// +---------+-------------+---------+---------------------------+----------------------+
|
||||
Row < Open , open_close , Empty , close_drawer , can_close_drawer >,
|
||||
// +---------+-------------+---------+---------------------------+----------------------+
|
||||
Row < Empty , open_close , Open , open_drawer , none >,
|
||||
Row < Empty , cd_detected , Stopped , store_cd_info , And_<good_disk_format,
|
||||
always_true> >,
|
||||
// +---------+-------------+---------+---------------------------+----------------------+
|
||||
Row < Playing , stop , Stopped , stop_playback , none >,
|
||||
Row < Playing , pause , Paused , pause_playback , none >,
|
||||
Row < Playing , open_close , Open , stop_and_open , none >,
|
||||
// +---------+-------------+---------+---------------------------+----------------------+
|
||||
Row < Paused , end_pause , Playing , resume_playback , none >,
|
||||
Row < Paused , stop , Stopped , stop_playback , none >,
|
||||
Row < Paused , open_close , Open , stop_and_open , none >
|
||||
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
>/*>::type*/ {};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const&, FSM&,int)
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
}
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_simple_with_functors_test )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.test_fct_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().event_counter == 1,"Playing event counter incorrect");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
// Copyright 2010 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE Back11TestDeferIn2Regions
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace boost::msm::front;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct event1 {};
|
||||
struct event2 {};
|
||||
struct event3 {};
|
||||
struct eventd {};
|
||||
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
// The list of FSM states
|
||||
struct State11 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct State12 : public msm::front::state<>
|
||||
{
|
||||
typedef boost::fusion::vector<eventd> deferred_events;
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct State13 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct State21 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
struct State22 : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
};
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef boost::fusion::vector<State11,State21> initial_state;
|
||||
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
Row < State11 , event1 , State12 >,
|
||||
Row < State12 , event2 , State13 >,
|
||||
|
||||
Row < State21 , event3 , State22 >,
|
||||
Row < State22 , eventd , State21 >
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
> {};
|
||||
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const& , FSM&,int )
|
||||
{
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
// init counters
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::State11&>().entry_counter=0;
|
||||
fsm.template get_state<player_::State11&>().exit_counter=0;
|
||||
fsm.template get_state<player_::State12&>().entry_counter=0;
|
||||
fsm.template get_state<player_::State12&>().exit_counter=0;
|
||||
fsm.template get_state<player_::State13&>().entry_counter=0;
|
||||
fsm.template get_state<player_::State13&>().exit_counter=0;
|
||||
fsm.template get_state<player_::State21&>().entry_counter=0;
|
||||
fsm.template get_state<player_::State22&>().exit_counter=0;
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( Back11TestDeferIn2Regions )
|
||||
{
|
||||
player p;
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
p.start();
|
||||
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
|
||||
// deferred
|
||||
p.process_event(eventd());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().exit_counter == 0,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 0,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 1,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 0,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 0,"State22 entry not called correctly");
|
||||
|
||||
p.process_event(event3());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 1,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 2,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 1,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 1,"State22 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_deferred_queue().size() == 1,"Deferred queue should have one element");
|
||||
p.clear_deferred_queue();
|
||||
|
||||
p.process_event(event2());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"State13 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 1,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 2,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 1,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 1,"State22 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_deferred_queue().size() == 0,"Deferred queue should have no element");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2024 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include <boost/msm/back/favor_compile_time.hpp>
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
|
||||
template<typename Front>
|
||||
using get_test_machines = boost::mpl::vector<
|
||||
boost::msm::back::state_machine<Front>,
|
||||
boost::msm::back::state_machine<Front, boost::msm::back::favor_compile_time>,
|
||||
boost::msm::back11::state_machine<Front>
|
||||
>;
|
||||
|
||||
#define BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(frontname) \
|
||||
using base = msm::front::state_machine_def<frontname>; \
|
||||
template<typename T1, class Event, typename T2> \
|
||||
using _row = typename base::template _row<T1, Event, T2>; \
|
||||
template< \
|
||||
typename T1, \
|
||||
class Event, \
|
||||
typename T2, \
|
||||
void (frontname::*action)(Event const&), \
|
||||
bool (frontname::*guard)(Event const&) \
|
||||
> using row = typename base::template row<T1, Event, T2, action, guard>; \
|
||||
template< \
|
||||
typename T1, \
|
||||
class Event, \
|
||||
typename T2, \
|
||||
void (frontname::*action)(Event const&) \
|
||||
> using a_row = typename base::template a_row<T1, Event, T2, action>; \
|
||||
template< \
|
||||
typename T1, \
|
||||
class Event, \
|
||||
typename T2, \
|
||||
bool (frontname::*guard)(Event const&) \
|
||||
> using g_row = typename base::template g_row<T1, Event, T2, guard>;
|
||||
|
||||
|
||||
|
||||
// template<typename State, typename Fsm>
|
||||
// State& get_state(Fsm&& fsm)
|
||||
// {
|
||||
// return fsm.template get_state<State&>();
|
||||
// }
|
||||
+29
-24
@@ -8,11 +8,16 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
|
||||
#define BOOST_MPL_LIMIT_VECTOR_SIZE 30
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE big_with_functors_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
@@ -195,20 +200,20 @@ namespace
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<my_machine_> my_machine;
|
||||
typedef get_test_machines<my_machine_> my_machines;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( big_with_functors_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( big_with_functors_test, my_machine, my_machines )
|
||||
{
|
||||
my_machine p;
|
||||
|
||||
// needed to start the highest-level SM.
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active"); //State1
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 0,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State5&>().exit_counter == 0,"State5 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State5&>().entry_counter == 0,"State5 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().exit_counter == 0,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State5&>().exit_counter == 0,"State5 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State5&>().entry_counter == 0,"State5 entry not called correctly");
|
||||
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
@@ -223,14 +228,14 @@ namespace
|
||||
p.process_event(event1());
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 11,"State12 should be active"); //State12
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State12&>().exit_counter == 0,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State7&>().exit_counter == 1,"State7 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State7&>().entry_counter == 1,"State7 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State10&>().exit_counter == 1,"State10 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State10&>().entry_counter == 1,"State10 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State12&>().exit_counter == 0,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State7&>().exit_counter == 1,"State7 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State7&>().entry_counter == 1,"State7 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State10&>().exit_counter == 1,"State10 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State10&>().entry_counter == 1,"State10 entry not called correctly");
|
||||
|
||||
|
||||
p.process_event(event2());
|
||||
@@ -246,14 +251,14 @@ namespace
|
||||
p.process_event(event2());
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active"); //State1
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 2,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 2,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State7&>().exit_counter == 2,"State7 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State7&>().entry_counter == 2,"State7 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State10&>().exit_counter == 2,"State10 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State10&>().entry_counter == 2,"State10 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().exit_counter == 2,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().entry_counter == 2,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State7&>().exit_counter == 2,"State7 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State7&>().entry_counter == 2,"State7 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State10&>().exit_counter == 2,"State10 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State10&>().entry_counter == 2,"State10 entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
file(GLOB SOURCES "*.cpp")
|
||||
# TODO:
|
||||
# Fully install boost to test Serialize
|
||||
list(FILTER SOURCES EXCLUDE REGEX "Serialize|BigWithFunctors")
|
||||
# list(FILTER SOURCES INCLUDE REGEX "Anonymous")
|
||||
|
||||
add_executable(msm_test
|
||||
${SOURCES}
|
||||
# Anonymous.cpp
|
||||
# AnonymousEuml.cpp
|
||||
# AnonymousAndGuard.cpp
|
||||
# BigWithFunctors.cpp
|
||||
# CompositeMachine.cpp
|
||||
# Entries.cpp
|
||||
main.cpp
|
||||
)
|
||||
target_include_directories(msm_test PRIVATE ../include)
|
||||
target_compile_definitions(msm_test PRIVATE "BOOST_MSM_NONSTANDALONE_TEST")
|
||||
+64
-46
@@ -8,11 +8,11 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE composite_euml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -52,9 +52,14 @@ namespace
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Stopped)
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Paused)
|
||||
|
||||
// Playing is now a state machine itself.
|
||||
// State machine attributes.
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_next_song_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_prev_song_guard_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_playback_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,can_close_drawer_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,test_fct_counter)
|
||||
|
||||
// Playing is now a state machine itself.
|
||||
// It has 5 substates
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Song1)
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Song2)
|
||||
@@ -62,6 +67,9 @@ namespace
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Region2State1)
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Region2State2)
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// Playing has a transition table
|
||||
BOOST_MSM_EUML_TRANSITION_TABLE((
|
||||
// +------------------------------------------------------------------------------+
|
||||
@@ -82,14 +90,11 @@ namespace
|
||||
<< start_prev_song_guard_counter // Attributes
|
||||
),Playing_)
|
||||
// choice of back-end
|
||||
typedef msm::back::state_machine<Playing_> Playing_type;
|
||||
typedef Back<Playing_, Policy> Playing_type;
|
||||
Playing_type const Playing;
|
||||
|
||||
|
||||
//fsm
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_playback_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,can_close_drawer_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,test_fct_counter)
|
||||
BOOST_MSM_EUML_ACTION(No_Transition)
|
||||
{
|
||||
template <class FSM,class Event>
|
||||
@@ -142,138 +147,151 @@ namespace
|
||||
),
|
||||
player_) //fsm name
|
||||
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Paused", "Open", "Empty", "Playing" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( composite_euml_test, test_machine, test_machines )
|
||||
{
|
||||
player p;
|
||||
typename test_machine::player p;
|
||||
typedef typename test_machine::player_ player_;
|
||||
typedef typename test_machine::Playing_type Playing_type;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(can_close_drawer_counter) == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(entry_counter) == 1,
|
||||
"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(test_fct_counter) == 1,"action not called correctly");
|
||||
|
||||
p.process_event(next_song);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[1] == 3,"Region2State1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().current_state()[1] == 3,"Region2State1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Region2State1)&>().get_attribute(entry_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Region2State1)&>().get_attribute(entry_counter) == 1,
|
||||
"Region2State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song1)&>().get_attribute(exit_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song1)&>().get_attribute(exit_counter) == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_attribute(start_next_song_counter) == 0,
|
||||
p.template get_state<Playing_type&>().get_attribute(start_next_song_counter) == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(next_song);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(entry_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(entry_counter) == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(exit_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(exit_counter) == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_attribute(start_next_song_counter) == 1,
|
||||
p.template get_state<Playing_type&>().get_attribute(start_next_song_counter) == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(previous_song);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 2,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(exit_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(exit_counter) == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_attribute(start_prev_song_guard_counter) == 1,
|
||||
p.template get_state<Playing_type&>().get_attribute(start_prev_song_guard_counter) == 1,
|
||||
"submachine guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Region2State2)&>().get_attribute(entry_counter) == 0,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Region2State2)&>().get_attribute(entry_counter) == 0,
|
||||
"Region2State2 entry not called correctly");
|
||||
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(exit_counter) == 1,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(entry_counter) == 2,
|
||||
"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(exit_counter) == 2,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Playing_type;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
|
||||
+72
-55
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE composite_machine_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -38,9 +38,14 @@ namespace
|
||||
std::string name;
|
||||
};
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(player_);
|
||||
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
|
||||
@@ -81,6 +86,8 @@ namespace
|
||||
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Playing_);
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
@@ -150,7 +157,7 @@ namespace
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back::state_machine<Playing_> Playing;
|
||||
typedef Back<Playing_, Policy> Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
@@ -217,128 +224,138 @@ namespace
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().exit_counter=0;
|
||||
}
|
||||
|
||||
};
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( composite_machine_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( composite_machine_test, test_machine, test_machines )
|
||||
{
|
||||
player p;
|
||||
typename test_machine::player p;
|
||||
typedef typename test_machine::player_ player_;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 0,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(PreviousSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 2,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
"submachine guard not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE constructor_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -189,12 +189,12 @@ namespace
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( constructor_test, player, players )
|
||||
{
|
||||
SomeExternalContext ctx(3);
|
||||
player p(boost::ref(ctx),5);
|
||||
|
||||
+83
-66
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE entries_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -34,9 +34,14 @@ namespace
|
||||
template <class Event>
|
||||
event6(Event const&){}
|
||||
};
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// front-end: define the FSM structure
|
||||
struct Fsm_ : public msm::front::state_machine_def<Fsm_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Fsm_);
|
||||
|
||||
// The list of FSM states
|
||||
struct State1 : public msm::front::state<>
|
||||
{
|
||||
@@ -58,7 +63,8 @@ namespace
|
||||
};
|
||||
struct SubFsm2_ : public msm::front::state_machine_def<SubFsm2_>
|
||||
{
|
||||
typedef msm::back::state_machine<SubFsm2_> SubFsm2;
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(SubFsm2_);
|
||||
typedef Back<SubFsm2_, Policy> SubFsm2;
|
||||
|
||||
unsigned int entry_action_counter;
|
||||
|
||||
@@ -159,7 +165,7 @@ namespace
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
};
|
||||
typedef msm::back::state_machine<SubFsm2_> SubFsm2;
|
||||
typedef Back<SubFsm2_, Policy> SubFsm2;
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef State1 initial_state;
|
||||
@@ -169,19 +175,19 @@ namespace
|
||||
|
||||
// Transition table for Fsm
|
||||
struct transition_table : mpl::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------------------+--------+------------------------------------+-------+--------+
|
||||
_row < State1 , event1 , SubFsm2 >,
|
||||
_row < State1 , event2 , SubFsm2::direct<SubFsm2_::SubState2> >,
|
||||
_row < State1 , event3 , mpl::vector<SubFsm2::direct<SubFsm2_::SubState2>,
|
||||
SubFsm2::direct<SubFsm2_::SubState2b> > >,
|
||||
_row < State1 , event4 , SubFsm2::entry_pt
|
||||
<SubFsm2_::PseudoEntry1> >,
|
||||
// +---------------------+--------+------------------------------------+-------+--------+
|
||||
_row < SubFsm2 , event1 , State1 >,
|
||||
_row < SubFsm2::exit_pt
|
||||
<SubFsm2_::PseudoExit1>, event6 , State2 >
|
||||
// +---------------------+--------+------------------------------------+-------+--------+
|
||||
// Start Event Next Action Guard
|
||||
// +---------------------+--------+-----------------------------------------------------+-------+--------+
|
||||
_row < State1 , event1 , SubFsm2 >,
|
||||
_row < State1 , event2 , typename SubFsm2::template direct<typename SubFsm2_::SubState2> >,
|
||||
_row < State1 , event3 , mpl::vector<typename SubFsm2::template direct<typename SubFsm2_::SubState2>,
|
||||
typename SubFsm2::template direct<typename SubFsm2_::SubState2b> > >,
|
||||
_row < State1 , event4 , typename SubFsm2::template entry_pt
|
||||
<typename SubFsm2_::PseudoEntry1> >,
|
||||
// +---------------------+--------+-----------------------------------------------------+-------+--------+
|
||||
_row < SubFsm2 , event1 , State1 >,
|
||||
_row < typename SubFsm2::template exit_pt
|
||||
<typename SubFsm2_::PseudoExit1>, event6 , State2 >
|
||||
// +---------------------+--------+-----------------------------------------------------+-------+--------+
|
||||
> {};
|
||||
|
||||
// Replaces the default no-transition response.
|
||||
@@ -201,96 +207,107 @@ namespace
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().entry_action_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState1&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState1&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState1b&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState1b&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState2&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState2&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState2b&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState2b&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState3&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::SubState3&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::PseudoEntry1&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::PseudoEntry1&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::exit_pt<SubFsm2_::PseudoExit1>&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<Fsm_::SubFsm2::exit_pt<SubFsm2_::PseudoExit1>&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState1&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState1&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState1b&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState1b&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState2&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState2&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState2b&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState2b&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState3&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::SubState3&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::PseudoEntry1&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::PseudoEntry1&>().exit_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::template exit_pt<typename SubFsm2_::PseudoExit1>&>().entry_counter=0;
|
||||
fsm.template get_state<Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::template exit_pt<typename SubFsm2_::PseudoExit1>&>().exit_counter=0;
|
||||
|
||||
}
|
||||
};
|
||||
typedef msm::back::state_machine<Fsm_> Fsm;
|
||||
typedef Back<Fsm_, Policy> Fsm;
|
||||
};
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
// static char const* const state_names[] = { "State1", "SubFsm2","State2" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( entries_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( entries_test, test_machine, test_machines )
|
||||
{
|
||||
Fsm p;
|
||||
typename test_machine::Fsm p;
|
||||
typedef typename test_machine::Fsm_ Fsm_;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
|
||||
p.process_event(event1());
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().exit_counter == 1,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_counter == 1,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State1&>().entry_counter == 2,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().exit_counter == 1,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().entry_counter == 1,"SubFsm2 entry not called correctly");
|
||||
|
||||
p.process_event(event2());
|
||||
p.process_event(event6());
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().exit_counter == 2,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().entry_counter == 3,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().exit_counter == 2,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_counter == 2,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2&>().entry_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State1&>().exit_counter == 2,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State1&>().entry_counter == 3,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().exit_counter == 2,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().entry_counter == 2,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState2&>().entry_counter == 1,
|
||||
"SubFsm2::SubState2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2&>().exit_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState2&>().exit_counter == 1,
|
||||
"SubFsm2::SubState2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState1&>().entry_counter == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState1&>().entry_counter == 2,
|
||||
"SubFsm2::SubState1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState1&>().exit_counter == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState1&>().exit_counter == 2,
|
||||
"SubFsm2::SubState1 exit not called correctly");
|
||||
|
||||
p.process_event(event3());
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().exit_counter == 3,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().entry_counter == 4,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().exit_counter == 3,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_counter == 3,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2&>().entry_counter == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State1&>().exit_counter == 3,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State1&>().entry_counter == 4,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().exit_counter == 3,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().entry_counter == 3,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState2&>().entry_counter == 2,
|
||||
"SubFsm2::SubState2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2&>().exit_counter == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState2&>().exit_counter == 2,
|
||||
"SubFsm2::SubState2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2b&>().entry_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState2b&>().entry_counter == 1,
|
||||
"SubFsm2::SubState2b entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState2b&>().exit_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState2b&>().exit_counter == 1,
|
||||
"SubFsm2::SubState2b exit not called correctly");
|
||||
|
||||
p.process_event(event4());
|
||||
p.process_event(event5());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"State2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State1&>().exit_counter == 4,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().exit_counter == 4,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_counter == 4,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::PseudoEntry1&>().entry_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State1&>().exit_counter == 4,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().exit_counter == 4,"SubFsm2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().entry_counter == 4,"SubFsm2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::PseudoEntry1&>().entry_counter == 1,
|
||||
"SubFsm2::PseudoEntry1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::PseudoEntry1&>().exit_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::PseudoEntry1&>().exit_counter == 1,
|
||||
"SubFsm2::PseudoEntry1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState3&>().entry_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState3&>().entry_counter == 1,
|
||||
"SubFsm2::SubState3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2_::SubState3&>().exit_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2_::SubState3&>().exit_counter == 1,
|
||||
"SubFsm2::SubState3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2::exit_pt<Fsm_::SubFsm2_::PseudoExit1>&>().entry_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::template exit_pt<typename Fsm_::SubFsm2_::PseudoExit1>&>().entry_counter == 1,
|
||||
"SubFsm2::PseudoExit1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().get_state<Fsm_::SubFsm2::exit_pt<Fsm_::SubFsm2_::PseudoExit1>&>().exit_counter == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().template get_state<typename Fsm_::SubFsm2::template exit_pt<typename Fsm_::SubFsm2_::PseudoExit1>&>().exit_counter == 1,
|
||||
"SubFsm2::PseudoExit1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Fsm_::SubFsm2&>().entry_action_counter == 1,"Action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename Fsm_::SubFsm2&>().entry_action_counter == 1,"Action not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Fsm;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Fsm_::SubFsm2;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
|
||||
+22
-22
@@ -9,7 +9,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
// functors
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <boost/msm/front/euml/operator.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE event_queue_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -291,23 +291,23 @@ namespace
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_event_queue )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( event_queue_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.enqueue_event(open_close());
|
||||
p.execute_single_queued_event();
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.enqueue_event(open_close());
|
||||
p.enqueue_event(
|
||||
@@ -318,42 +318,42 @@ namespace
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.test_fct_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.enqueue_event(end_pause());
|
||||
p.execute_queued_events();
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.enqueue_event(pause());
|
||||
p.enqueue_event(stop());
|
||||
p.enqueue_event(stop());
|
||||
p.execute_queued_events();
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+77
-59
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE history_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -38,9 +38,14 @@ namespace
|
||||
std::string name;
|
||||
};
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(player_);
|
||||
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
|
||||
@@ -81,6 +86,8 @@ namespace
|
||||
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Playing_);
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
@@ -150,7 +157,7 @@ namespace
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back::state_machine<Playing_,msm::back::ShallowHistory<mpl::vector<end_pause> > > Playing;
|
||||
typedef Back<Playing_,Policy,msm::back::ShallowHistory<mpl::vector<end_pause> > > Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
@@ -217,139 +224,150 @@ namespace
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().exit_counter=0;
|
||||
}
|
||||
|
||||
};
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( history_test, test_machine, test_machines )
|
||||
{
|
||||
player p;
|
||||
typename test_machine::player p;
|
||||
typedef typename test_machine::player_ player_;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 0,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(PreviousSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 2,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
"submachine guard not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 3,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 3,
|
||||
"Song2 entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 2,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter == 2,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
+13
-10
@@ -12,7 +12,7 @@
|
||||
#include <boost/fusion/include/std_tuple.hpp>
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
// functors
|
||||
@@ -97,29 +97,32 @@ namespace
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<fsm_> Fsm;
|
||||
typedef mpl::vector<
|
||||
boost::msm::back::state_machine<fsm_>,
|
||||
boost::msm::back11::state_machine<fsm_>
|
||||
> Fsms;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(kleene_deferred_test)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(kleene_deferred_test, Fsm, Fsms)
|
||||
{
|
||||
Fsm fsm;
|
||||
|
||||
fsm.start();
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateA&>().entry_counter == 1,"StateA entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.template get_state<fsm_::StateA&>().entry_counter == 1,"StateA entry not called correctly");
|
||||
|
||||
fsm.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(fsm.current_state()[0] == 1,"StateB should be active");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateA&>().exit_counter == 1,"StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateB&>().entry_counter == 1,"StateB entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.template get_state<fsm_::StateA&>().exit_counter == 1,"StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.template get_state<fsm_::StateB&>().entry_counter == 1,"StateB entry not called correctly");
|
||||
|
||||
fsm.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(fsm.current_state()[0] == 1, "StateB should be active");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateA&>().exit_counter == 1, "StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateB&>().entry_counter == 1, "StateB entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.template get_state<fsm_::StateA&>().exit_counter == 1, "StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.template get_state<fsm_::StateB&>().entry_counter == 1, "StateB entry not called correctly");
|
||||
|
||||
fsm.process_event(event2());
|
||||
BOOST_CHECK_MESSAGE(fsm.current_state()[0] == 1, "StateB should be active");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateA&>().exit_counter == 2, "StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.get_state<fsm_::StateB&>().entry_counter == 2, "StateB entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.template get_state<fsm_::StateA&>().exit_counter == 2, "StateA exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(fsm.template get_state<fsm_::StateB&>().entry_counter == 2, "StateB entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
@@ -87,10 +87,10 @@ namespace
|
||||
};
|
||||
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<Sm1_> Sm1;
|
||||
typedef get_test_machines<Sm1_> Sm1s;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back_many_deferred_transitions)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(back_many_deferred_transitions, Sm1, Sm1s)
|
||||
{
|
||||
Sm1 sm1;
|
||||
sm1.start();
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/puml/puml.hpp>
|
||||
#include <PumlCommon.hpp>
|
||||
#include "PumlCommon.hpp"
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_only_string_puml_test
|
||||
#define BOOST_TEST_MODULE only_string_puml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -76,10 +76,10 @@ namespace
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_only_string_puml_test)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(only_string_puml_test, player, players)
|
||||
{
|
||||
player p;
|
||||
static_assert(msm::back11::get_number_of_regions<typename player::initial_state>::type::value == 1);
|
||||
@@ -89,7 +89,7 @@ namespace
|
||||
|
||||
p.process_event(Event<by_name("open_close_")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<Flag<by_name("CDLoaded")>>() == false, "CDLoaded should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<Flag<by_name("CDLoaded")>>() == false, "CDLoaded should not be active");
|
||||
|
||||
p.process_event(Event<by_name("open_close_")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
@@ -105,13 +105,13 @@ namespace
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.test_fct_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active < Flag<by_name("CDLoaded")>>() == true, "CDLoaded should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active < Flag<by_name("CDLoaded")>>() == true, "CDLoaded should be active");
|
||||
BOOST_CHECK_MESSAGE(p.entry_counter == 1, "Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.exit_counter == 0, "Playing exit not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("pause_")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active < Flag<by_name("CDLoaded")>>() == true, "CDLoaded should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active < Flag<by_name("CDLoaded")>>() == true, "CDLoaded should be active");
|
||||
BOOST_CHECK_MESSAGE(p.entry_counter == 1, "Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.exit_counter == 1, "Playing exit not called correctly");
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace
|
||||
|
||||
p.process_event(Event<by_name("stop_")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active < Flag<by_name("CDLoaded")>>() == true, "CDLoaded should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active < Flag<by_name("CDLoaded")>>() == true, "CDLoaded should be active");
|
||||
|
||||
p.process_event(Event<by_name("stop_")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
+110
-91
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE orthogonal_deferred_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -49,9 +49,14 @@ namespace
|
||||
std::string name;
|
||||
};
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(player_);
|
||||
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
unsigned int report_error_counter;
|
||||
@@ -104,6 +109,8 @@ namespace
|
||||
// by another team in another module. For simplicity I just declare it inside player
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Playing_);
|
||||
|
||||
// when playing, the CD is loaded and we are in either pause or playing (duh)
|
||||
typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
|
||||
|
||||
@@ -178,7 +185,7 @@ namespace
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back::state_machine<Playing_> Playing;
|
||||
typedef Back<Playing_, Policy> Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
@@ -282,206 +289,218 @@ namespace
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<player_::AllOk&>().entry_counter=0;
|
||||
fsm.template get_state<player_::AllOk&>().exit_counter=0;
|
||||
fsm.template get_state<player_::ErrorMode&>().entry_counter=0;
|
||||
fsm.template get_state<player_::ErrorMode&>().exit_counter=0;
|
||||
fsm.template get_state<player_::ErrorTerminate&>().entry_counter=0;
|
||||
fsm.template get_state<player_::ErrorTerminate&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::AllOk&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::AllOk&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorMode&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorMode&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorTerminate&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorTerminate&>().exit_counter=0;
|
||||
}
|
||||
};
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
//static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode" };
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( orthogonal_deferred_test, test_machine, test_machines )
|
||||
{
|
||||
player p;
|
||||
typename test_machine::player p;
|
||||
typedef typename test_machine::player_ player_;
|
||||
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
p.start();
|
||||
// test deferred event
|
||||
// deferred in Empty and Open, will be handled only after event cd_detected
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 0,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 0,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded>() == false,"CDLoaded should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded>() == false,"CDLoaded should not be active");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
//deferred event should have been processed
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<FirstSongPlaying>() == true,"FirstSongPlaying should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<FirstSongPlaying>() == true,"FirstSongPlaying should be active");
|
||||
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 0,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(PreviousSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 2,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
"submachine guard not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<FirstSongPlaying>() == false,"FirstSongPlaying should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<FirstSongPlaying>() == false,"FirstSongPlaying should not be active");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded,player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded,player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
//test interrupt
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(error_found());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().exit_counter == 1,"ErrorMode exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().entry_counter == 2,"AllOk entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().exit_counter == 1,"ErrorMode exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().entry_counter == 2,"AllOk entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 3,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 3,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 3,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 3,"Playing entry not called correctly");
|
||||
|
||||
//test terminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(do_terminate());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 2,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorTerminate&>().entry_counter == 1,"ErrorTerminate entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 2,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorTerminate&>().entry_counter == 1,"ErrorTerminate entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorTerminate&>().exit_counter == 0,"ErrorTerminate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorTerminate&>().exit_counter == 0,"ErrorTerminate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
+110
-91
@@ -9,13 +9,13 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE orthogonal_deferred_2_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -52,9 +52,14 @@ namespace
|
||||
std::string name;
|
||||
};
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(player_);
|
||||
|
||||
// we want deferred events and no state requires deferred events (only the fsm in the
|
||||
// transition table), so the fsm does.
|
||||
typedef int activate_deferred_events;
|
||||
@@ -109,6 +114,8 @@ namespace
|
||||
// by another team in another module. For simplicity I just declare it inside player
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Playing_);
|
||||
|
||||
// when playing, the CD is loaded and we are in either pause or playing (duh)
|
||||
typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
|
||||
|
||||
@@ -183,7 +190,7 @@ namespace
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back::state_machine<Playing_> Playing;
|
||||
typedef Back<Playing_, Policy> Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
@@ -289,206 +296,218 @@ namespace
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<player_::AllOk&>().entry_counter=0;
|
||||
fsm.template get_state<player_::AllOk&>().exit_counter=0;
|
||||
fsm.template get_state<player_::ErrorMode&>().entry_counter=0;
|
||||
fsm.template get_state<player_::ErrorMode&>().exit_counter=0;
|
||||
fsm.template get_state<player_::ErrorTerminate&>().entry_counter=0;
|
||||
fsm.template get_state<player_::ErrorTerminate&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::AllOk&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::AllOk&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorMode&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorMode&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorTerminate&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorTerminate&>().exit_counter=0;
|
||||
}
|
||||
};
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
//static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode" };
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( orthogonal_deferred_2_test, test_machine, test_machines )
|
||||
{
|
||||
player p;
|
||||
typename test_machine::player p;
|
||||
typedef typename test_machine::player_ player_;
|
||||
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
p.start();
|
||||
// test deferred event
|
||||
// deferred in Empty and Open, will be handled only after event cd_detected
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 0,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 0,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded>() == false,"CDLoaded should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded>() == false,"CDLoaded should not be active");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
//deferred event should have been processed
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<FirstSongPlaying>() == true,"FirstSongPlaying should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<FirstSongPlaying>() == true,"FirstSongPlaying should be active");
|
||||
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 0,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(PreviousSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 2,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
"submachine guard not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<FirstSongPlaying>() == false,"FirstSongPlaying should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<FirstSongPlaying>() == false,"FirstSongPlaying should not be active");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded,player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded,player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
//test interrupt
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(error_found());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().exit_counter == 1,"ErrorMode exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().entry_counter == 2,"AllOk entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().exit_counter == 1,"ErrorMode exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().entry_counter == 2,"AllOk entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 3,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 3,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 3,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 3,"Playing entry not called correctly");
|
||||
|
||||
//test terminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(do_terminate());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 2,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorTerminate&>().entry_counter == 1,"ErrorTerminate entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 2,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorTerminate&>().entry_counter == 1,"ErrorTerminate entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorTerminate&>().exit_counter == 0,"ErrorTerminate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorTerminate&>().exit_counter == 0,"ErrorTerminate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
+105
-92
@@ -9,12 +9,12 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE orthogonal_deferred3_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -51,9 +51,14 @@ namespace
|
||||
std::string name;
|
||||
};
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(player_);
|
||||
|
||||
// we want deferred events and no state requires deferred events (only the fsm in the
|
||||
// transition table), so the fsm does.
|
||||
typedef int activate_deferred_events;
|
||||
@@ -108,6 +113,8 @@ namespace
|
||||
// by another team in another module. For simplicity I just declare it inside player
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Playing_);
|
||||
|
||||
// when playing, the CD is loaded and we are in either pause or playing (duh)
|
||||
typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
|
||||
|
||||
@@ -182,7 +189,7 @@ namespace
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back::state_machine<Playing_> Playing;
|
||||
typedef Back<Playing_, Policy> Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
@@ -307,203 +314,209 @@ namespace
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<player_::AllOk&>().entry_counter=0;
|
||||
fsm.template get_state<player_::AllOk&>().exit_counter=0;
|
||||
fsm.template get_state<player_::ErrorMode&>().entry_counter=0;
|
||||
fsm.template get_state<player_::ErrorMode&>().exit_counter=0;
|
||||
fsm.template get_state<player_::ErrorTerminate&>().entry_counter=0;
|
||||
fsm.template get_state<player_::ErrorTerminate&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::AllOk&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::AllOk&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorMode&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorMode&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorTerminate&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::ErrorTerminate&>().exit_counter=0;
|
||||
}
|
||||
};
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
//static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode" };
|
||||
|
||||
BOOST_AUTO_TEST_CASE( orthogonal_deferred3_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( orthogonal_deferred3_test, test_machine, test_machines )
|
||||
{
|
||||
player p;
|
||||
typename test_machine::player p;
|
||||
typedef typename test_machine::player_ player_;
|
||||
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
p.start();
|
||||
// test deferred event
|
||||
// deferred in Empty and Open, will be handled only after event cd_detected
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 0,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 0,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded>() == false,"CDLoaded should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded>() == false,"CDLoaded should not be active");
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
//deferred event should have been processed
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<FirstSongPlaying>() == true,"FirstSongPlaying should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<FirstSongPlaying>() == true,"FirstSongPlaying should be active");
|
||||
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 0,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(PreviousSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 2,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
"submachine guard not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<FirstSongPlaying>() == false,"FirstSongPlaying should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<FirstSongPlaying>() == false,"FirstSongPlaying should not be active");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == true,"PlayingPaused should be active");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<PlayingPaused>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.is_flag_active<CDLoaded,player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<PlayingPaused>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.template is_flag_active<CDLoaded,player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
//test interrupt
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(error_found());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 1,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().entry_counter == 1,"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorMode&>().exit_counter == 1,"ErrorMode exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().entry_counter == 2,"AllOk entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorMode&>().exit_counter == 1,"ErrorMode exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().entry_counter == 2,"AllOk entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 3,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 3,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 3,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 3,"Playing entry not called correctly");
|
||||
|
||||
//test terminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(do_terminate());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::AllOk&>().exit_counter == 2,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorTerminate&>().entry_counter == 1,"ErrorTerminate entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::AllOk&>().exit_counter == 2,"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorTerminate&>().entry_counter == 1,"ErrorTerminate entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::ErrorTerminate&>().exit_counter == 0,"ErrorTerminate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::ErrorTerminate&>().exit_counter == 0,"ErrorTerminate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyOrthogonalDeferredEumlTest
|
||||
#define BOOST_TEST_MODULE orthogonal_deferred_euml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -65,15 +65,23 @@ namespace
|
||||
BOOST_MSM_EUML_INTERRUPT_STATE(( end_error,++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),
|
||||
ErrorMode)
|
||||
|
||||
// Playing is now a state machine itself.
|
||||
// State machine attributes.
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_playback_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,can_close_drawer_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,report_error_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,report_end_error_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_next_song_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_prev_song_guard_counter)
|
||||
|
||||
// Playing is now a state machine itself.
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),
|
||||
attributes_ << entry_counter << exit_counter, configure_<< FirstSongPlaying ),Song1)
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Song2)
|
||||
BOOST_MSM_EUML_STATE(( ++state_(entry_counter),++state_(exit_counter),attributes_ << entry_counter << exit_counter),Song3)
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// Playing has a transition table
|
||||
BOOST_MSM_EUML_TRANSITION_TABLE((
|
||||
// +------------------------------------------------------------------------------+
|
||||
@@ -95,14 +103,10 @@ namespace
|
||||
),Playing_)
|
||||
|
||||
// back-end
|
||||
typedef msm::back::state_machine<Playing_> Playing_type;
|
||||
typedef Back<Playing_, Policy> Playing_type;
|
||||
Playing_type const Playing;
|
||||
|
||||
//fsm
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,start_playback_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,can_close_drawer_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,report_error_counter)
|
||||
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(unsigned int,report_end_error_counter)
|
||||
BOOST_MSM_EUML_ACTION(No_Transition)
|
||||
{
|
||||
template <class FSM,class Event>
|
||||
@@ -146,213 +150,228 @@ namespace
|
||||
),
|
||||
player_) //fsm name
|
||||
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>
|
||||
// TODO:
|
||||
// Investigate reason for test failure in back11.
|
||||
// hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
//static char const* const state_names[] = { "Stopped", "Paused","Open", "Empty", "Playing" ,"AllOk","ErrorMode","ErrorTerminate" };
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MyOrthogonalDeferredEumlTest)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(orthogonal_deferred_euml_test, test_machine, test_machines)
|
||||
{
|
||||
player p;
|
||||
typename test_machine::player p;
|
||||
typedef typename test_machine::player_ player_;
|
||||
typedef typename test_machine::Playing_type Playing_type;
|
||||
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
p.start();
|
||||
// test deferred event
|
||||
// deferred in Empty and Open, will be handled only after event cd_detected
|
||||
p.process_event(play);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 0,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 0,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(entry_counter) == 0,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
"Empty entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded)>() == false,"CDLoaded should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded)>() == false,"CDLoaded should not be active");
|
||||
|
||||
p.process_event(open_close);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(can_close_drawer_counter) == 1,"guard not called correctly");
|
||||
|
||||
//deferred event should have been processed
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(entry_counter) == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song1)&>().get_attribute(entry_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song1)&>().get_attribute(entry_counter) == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(FirstSongPlaying)>() == true,"FirstSongPlaying should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(FirstSongPlaying)>() == true,"FirstSongPlaying should be active");
|
||||
|
||||
|
||||
p.process_event(next_song);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song1)&>().get_attribute(exit_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song1)&>().get_attribute(exit_counter) == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_attribute(start_next_song_counter) == 0,
|
||||
p.template get_state<Playing_type&>().get_attribute(start_next_song_counter) == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(next_song);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(entry_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(entry_counter) == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(exit_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(exit_counter) == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_attribute(start_next_song_counter) == 1,
|
||||
p.template get_state<Playing_type&>().get_attribute(start_next_song_counter) == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(previous_song);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 2,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song2)&>().get_attribute(entry_counter) == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(exit_counter) == 1,
|
||||
p.template get_state<Playing_type&>().template get_state<BOOST_MSM_EUML_STATE_NAME(Song3)&>().get_attribute(exit_counter) == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<Playing_type&>().get_attribute(start_prev_song_guard_counter) == 1,
|
||||
p.template get_state<Playing_type&>().get_attribute(start_prev_song_guard_counter) == 1,
|
||||
"submachine guard not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(FirstSongPlaying)>() == false,"FirstSongPlaying should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(FirstSongPlaying)>() == false,"FirstSongPlaying should not be active");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(exit_counter) == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
"Paused entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == true,"PlayingPaused should be active");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(entry_counter) == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
"Stopped entry not called correctly");
|
||||
//flags
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded)>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded),player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(PlayingPaused)>() == false,"PlayingPaused should not be active");
|
||||
BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded)>() == true,"CDLoaded should be active");
|
||||
//BOOST_CHECK_MESSAGE(p.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(CDLoaded),player::Flag_AND>() == false,"CDLoaded with AND should not be active");
|
||||
|
||||
p.process_event(stop);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
//test interrupt
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(error_found);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 1,
|
||||
"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(entry_counter) == 1,
|
||||
"ErrorMode entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(play);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 6,"ErrorMode should be active"); //ErrorMode
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 1,
|
||||
"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(entry_counter) == 1,
|
||||
"ErrorMode entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(ErrorMode)&>().get_attribute(exit_counter) == 1,
|
||||
"ErrorMode exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(entry_counter) == 2,
|
||||
"AllOk entry not called correctly");
|
||||
|
||||
p.process_event(play);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 3,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(entry_counter) == 3,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(entry_counter) == 3,"Playing entry not called correctly");
|
||||
|
||||
//test terminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 5,"AllOk should be active"); //AllOk
|
||||
p.process_event(do_terminate);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(AllOk)&>().get_attribute(exit_counter) == 2,
|
||||
"AllOk exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorTerminate)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(ErrorTerminate)&>().get_attribute(entry_counter) == 1,
|
||||
"ErrorTerminate entry not called correctly");
|
||||
|
||||
// try generating more events
|
||||
p.process_event(stop);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(ErrorTerminate)&>().get_attribute(exit_counter) == 0,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(ErrorTerminate)&>().get_attribute(exit_counter) == 0,
|
||||
"ErrorTerminate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(end_error());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 7,"ErrorTerminate should be active"); //ErrorTerminate
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Playing_type&>().get_attribute(exit_counter) == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Playing_type;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
+27
-27
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE serialize_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
// include headers that implement a archive in simple text format
|
||||
@@ -213,22 +213,22 @@ namespace
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( serialize_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
// test the serialization
|
||||
std::ostringstream ofs;
|
||||
@@ -249,62 +249,62 @@ namespace
|
||||
}
|
||||
// we now use p2 as it was loaded
|
||||
// check that we kept Empty's data value
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<player_::Empty&>().some_dummy_data == 3,"Empty not deserialized correctly");
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<player_::Empty&>().some_dummy_data == 3,"Empty not deserialized correctly");
|
||||
BOOST_CHECK_MESSAGE(p2.front_end_data == 4,"Front-end not deserialized correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
// eliminate object tracking (even if serialized through a pointer)
|
||||
// at the risk of a programming error creating duplicate objects.
|
||||
// this is to get rid of warning because p is not const
|
||||
BOOST_CLASS_TRACKING(player, boost::serialization::track_never)
|
||||
// BOOST_CLASS_TRACKING(player, boost::serialization::track_never)
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE serialize_simple_euml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
// include headers that implement a archive in simple text format
|
||||
@@ -112,24 +112,24 @@ namespace
|
||||
),
|
||||
player_) //fsm name
|
||||
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Paused", "Open", "Empty", "Playing" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( serialize_simple_euml_test, player, players )
|
||||
{
|
||||
player p2;
|
||||
|
||||
p2.start();
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p2.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p2.current_state()[0] == 2,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
"Open entry not called correctly");
|
||||
|
||||
// test the serialization
|
||||
@@ -156,55 +156,55 @@ namespace
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(test_fct_counter) == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
@@ -212,4 +212,4 @@ namespace
|
||||
// eliminate object tracking (even if serialized through a pointer)
|
||||
// at the risk of a programming error creating duplicate objects.
|
||||
// this is to get rid of warning because p is not const
|
||||
BOOST_CLASS_TRACKING(player, boost::serialization::track_never)
|
||||
// BOOST_CLASS_TRACKING(player, boost::serialization::track_never)
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE serialize_with_history_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
// include headers that implement a archive in simple text format
|
||||
@@ -44,9 +44,14 @@ namespace
|
||||
std::string name;
|
||||
};
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(player_);
|
||||
|
||||
unsigned int start_playback_counter;
|
||||
unsigned int can_close_drawer_counter;
|
||||
|
||||
@@ -87,6 +92,8 @@ namespace
|
||||
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Playing_);
|
||||
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
@@ -156,7 +163,7 @@ namespace
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back::state_machine<Playing_,msm::back::ShallowHistory<mpl::vector<end_pause> > > Playing;
|
||||
typedef Back<Playing_,Policy,msm::back::ShallowHistory<mpl::vector<end_pause> > > Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
@@ -223,107 +230,114 @@ namespace
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& fsm)
|
||||
{
|
||||
fsm.template get_state<player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Playing&>().template get_state<player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<player_::Paused&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Stopped&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Open&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Empty&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().entry_counter=0;
|
||||
fsm.template get_state<typename player_::Paused&>().exit_counter=0;
|
||||
}
|
||||
|
||||
};
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( serialize_with_history_test, test_machine, test_machines )
|
||||
{
|
||||
player p;
|
||||
typename test_machine::player p;
|
||||
typedef typename test_machine::player_ player_;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(cd_detected("louie, louie"));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().entry_counter == 1,
|
||||
"Song1 entry not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 1,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song1&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song1&>().exit_counter == 1,
|
||||
"Song1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 0,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 0,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(NextSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 2,"Song3 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().entry_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().entry_counter == 1,
|
||||
"Song3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().exit_counter == 1,
|
||||
"Song2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_next_song_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_next_song_counter == 1,
|
||||
"submachine action not called correctly");
|
||||
|
||||
p.process_event(PreviousSong());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song2&>().entry_counter == 2,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song2&>().entry_counter == 2,
|
||||
"Song2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().get_state<player_::Playing::Song3&>().exit_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing::Song3&>().exit_counter == 1,
|
||||
"Song3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(
|
||||
p.get_state<player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
p.template get_state<typename player_::Playing&>().start_prev_song_guard_counter == 1,
|
||||
"submachine guard not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
std::ostringstream ofs;
|
||||
// save fsm to archive (current state is Pause, Playing is in Song2)
|
||||
@@ -333,7 +347,7 @@ namespace
|
||||
oa << p;
|
||||
}
|
||||
// reload fsm in state Open
|
||||
player p2;
|
||||
typename test_machine::player p2;
|
||||
{
|
||||
// create and open an archive for input
|
||||
std::istringstream ifs(ofs.str());
|
||||
@@ -344,7 +358,7 @@ namespace
|
||||
// go back to Playing
|
||||
p2.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p2.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<typename player_::Playing&>().current_state()[0] == 1,"Song2 should be active");
|
||||
|
||||
p2.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p2.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
@@ -356,11 +370,15 @@ namespace
|
||||
BOOST_CHECK_MESSAGE(p2.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
|
||||
p2.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<typename player_::Playing&>().current_state()[0] == 0,"Song1 should be active");
|
||||
}
|
||||
}
|
||||
// eliminate object tracking (even if serialized through a pointer)
|
||||
// at the risk of a programming error creating duplicate objects.
|
||||
// this is to get rid of warning because p is not const
|
||||
BOOST_CLASS_TRACKING(player, boost::serialization::track_never)
|
||||
// BOOST_CLASS_TRACKING(player, boost::serialization::track_never)
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
@@ -9,13 +9,13 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_set_states_test
|
||||
#define BOOST_TEST_MODULE set_states_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -68,8 +68,13 @@ namespace
|
||||
{
|
||||
};
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
struct SubFsm_ : public msm::front::state_machine_def<SubFsm_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(SubFsm_);
|
||||
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const& e, FSM& fsm)
|
||||
{
|
||||
@@ -95,10 +100,12 @@ namespace
|
||||
<< " on event " << typeid(e).name() << std::endl;
|
||||
}
|
||||
};
|
||||
typedef msm::back11::state_machine<SubFsm_> SubFsm;
|
||||
typedef Back<SubFsm_, Policy> SubFsm;
|
||||
|
||||
struct Fsm_ : public msm::front::state_machine_def<Fsm_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Fsm_);
|
||||
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const& e, FSM& fsm)
|
||||
{
|
||||
@@ -114,7 +121,7 @@ namespace
|
||||
typedef SubFsm initial_state;
|
||||
|
||||
struct transition_table : mpl::vector<
|
||||
Row< SubFsm::exit_pt<PseudoExitState>, ExitEvent, TerminateState, none, none >
|
||||
Row< typename SubFsm::template exit_pt<PseudoExitState>, ExitEvent, TerminateState, none, none >
|
||||
> {};
|
||||
|
||||
template <class FSM, class Event>
|
||||
@@ -124,12 +131,21 @@ namespace
|
||||
<< " on event " << typeid(e).name() << std::endl;
|
||||
}
|
||||
};
|
||||
typedef msm::back11::state_machine<Fsm_> Fsm;
|
||||
typedef Back<Fsm_, Policy> Fsm;
|
||||
};
|
||||
// typedef msm::back11::state_machine<Fsm_> Fsm;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_set_states_test)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(set_states_test, test_machine, test_machines)
|
||||
{
|
||||
InputEvent input_event;
|
||||
typedef typename test_machine::Fsm Fsm;
|
||||
typedef typename test_machine::SubFsm SubFsm;
|
||||
|
||||
std::cout << "\nSubFsms created in constructor\n";
|
||||
Fsm fsm_subfsms_created_in_constructor(boost::msm::back::states_
|
||||
@@ -146,3 +162,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Fsm;
|
||||
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::SubFsm;
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
|
||||
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
|
||||
+25
-25
@@ -8,11 +8,11 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MySimpleEumlTest
|
||||
#define BOOST_TEST_MODULE simple_euml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -106,90 +106,90 @@ namespace
|
||||
),
|
||||
player_) //fsm name
|
||||
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Paused", "Open", "Empty", "Playing" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MySimpleEumlTest)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(simple_euml_test, player, players)
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(can_close_drawer_counter) == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(test_fct_counter) == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
+25
-25
@@ -8,11 +8,11 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MySimpleEuml2Test
|
||||
#define BOOST_TEST_MODULE simple_euml_2_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -106,90 +106,90 @@ namespace
|
||||
),
|
||||
player_) //fsm name
|
||||
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Paused", "Open", "Empty", "Playing" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MySimpleEuml2Test)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(simple_euml_2_test, player, players)
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 1,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 1,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(entry_counter) == 1,
|
||||
"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(can_close_drawer_counter) == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Empty)&>().get_attribute(exit_counter) == 2,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(test_fct_counter) == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
+25
-25
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE simple_internal_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -197,17 +197,17 @@ namespace
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( simple_internal_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
// internal events
|
||||
p.process_event(to_ignore());
|
||||
p.process_event(internal_evt());
|
||||
@@ -216,60 +216,60 @@ namespace
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 2,"Internal guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 3,"Internal guard not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-27
@@ -8,10 +8,10 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MySimpleInternalEumlTest
|
||||
#define BOOST_TEST_MODULE simple_internal_euml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -153,17 +153,18 @@ namespace
|
||||
),
|
||||
player_) //fsm name
|
||||
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
// typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Paused", "Open", "Empty", "Playing" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( simple_internal_euml_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( simple_internal_euml_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Empty_impl&>().get_attribute(entry_counter) == 1,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
// internal events
|
||||
@@ -171,82 +172,82 @@ namespace
|
||||
p.process_event(internal_evt);
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(internal_action_counter) == 1,"Internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(internal_guard_counter) == 1,"Internal guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(empty_internal_action_counter) == 0,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Empty_impl&>().get_attribute(empty_internal_action_counter) == 0,
|
||||
"Empty internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(empty_internal_guard_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Empty_impl&>().get_attribute(empty_internal_guard_counter) == 1,
|
||||
"Empty internal guard not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Empty_impl&>().get_attribute(exit_counter) == 1,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Empty_impl&>().get_attribute(entry_counter) == 1,
|
||||
"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Empty_impl&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(can_close_drawer_counter) == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Open)&>().get_attribute(exit_counter) == 1,
|
||||
"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Empty_impl&>().get_attribute(entry_counter) == 2,
|
||||
"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
p.process_event(play);
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<Empty_impl&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<Empty_impl&>().get_attribute(exit_counter) == 2,
|
||||
"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 1,
|
||||
"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 1,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 1,
|
||||
"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_attribute(start_playback_counter) == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 1,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 1,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 1,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(entry_counter) == 2,
|
||||
"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Playing)&>().get_attribute(exit_counter) == 2,
|
||||
"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(entry_counter) == 2,
|
||||
"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Paused)&>().get_attribute(exit_counter) == 2,
|
||||
"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 2,
|
||||
"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(exit_counter) == 2,
|
||||
"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<BOOST_MSM_EUML_STATE_NAME(Stopped)&>().get_attribute(entry_counter) == 3,
|
||||
"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#include <boost/msm/front/euml/common.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE simple_internal_functors_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -251,81 +251,81 @@ namespace
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( simple_internal_functors_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( simple_internal_functors_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
// internal events
|
||||
p.process_event(to_ignore());
|
||||
p.process_event(internal_evt());
|
||||
BOOST_CHECK_MESSAGE(p.internal_action_counter == 1,"Internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 1,"Internal guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().empty_internal_action_counter == 0,"Empty internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().empty_internal_guard_counter == 1,"Empty internal guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().empty_internal_action_counter == 0,"Empty internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().empty_internal_guard_counter == 1,"Empty internal guard not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 2,"Internal guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 3,"Internal guard not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/puml/puml.hpp>
|
||||
#include <PumlCommon.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_simple_internal_with_puml
|
||||
#define BOOST_TEST_MODULE simple_internal_with_puml
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -79,77 +79,77 @@ namespace
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_simple_internal_with_puml_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( simple_internal_with_puml_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().entry_counter == 1, "Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 1, "Empty entry not called correctly");
|
||||
// internal events
|
||||
p.process_event(Event<by_name("to_ignore")>{});
|
||||
p.process_event(Event<by_name("internal_evt")>{});
|
||||
BOOST_CHECK_MESSAGE(p.internal_action_counter == 1, "Internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 1, "Internal guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().empty_internal_action_counter == 0, "Empty internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().empty_internal_guard_counter == 1, "Empty internal guard not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().empty_internal_action_counter == 0, "Empty internal action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().empty_internal_guard_counter == 1, "Empty internal guard not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("open_close")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Open")>&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("open_close")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("cd_detected")>{"louie, louie", DISK_DVD});
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("cd_detected")>{"louie, louie", DISK_CD});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0, "Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.internal_guard_counter == 3, "Internal guard not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("play")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3, "Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().exit_counter == 1, "Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Playing")>&>().entry_counter == 1, "Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().exit_counter == 1, "Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing")>&>().entry_counter == 1, "Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1, "action not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("pause")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4, "Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().exit_counter == 1, "Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Paused")>&>().entry_counter == 1, "Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().exit_counter == 1, "Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().entry_counter == 1, "Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(Event<by_name("end_pause")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Paused")>&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Playing")>&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing")>&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("pause")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Playing")>&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Paused")>&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing")>&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("stop")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Paused")>&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("stop")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
+24
-24
@@ -9,7 +9,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
@@ -185,72 +185,72 @@ namespace
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( simple_machine_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( simple_machine_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(play());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+40
-31
@@ -9,7 +9,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
// functors
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <boost/msm/front/operator.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE SimpleWithFunctorsTest
|
||||
#define BOOST_TEST_MODULE simple_with_functors_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -26,11 +26,12 @@ using namespace std;
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace msm::front;
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct play {};
|
||||
struct end_pause {};
|
||||
struct play {int cpt_ = 0;};
|
||||
struct end_pause {int cpt_ = 0;};
|
||||
struct stop {};
|
||||
struct pause {};
|
||||
struct open_close {};
|
||||
@@ -99,14 +100,18 @@ namespace
|
||||
struct Playing : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
void on_entry(Event const& e,FSM& )
|
||||
{
|
||||
++entry_counter;
|
||||
event_counter = e.cpt_;
|
||||
}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {++exit_counter;}
|
||||
int entry_counter;
|
||||
int exit_counter;
|
||||
int event_counter=0;
|
||||
};
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
@@ -124,8 +129,9 @@ namespace
|
||||
struct TestFct
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const&, FSM& fsm,SourceState& ,TargetState& )
|
||||
void operator()(EVT& e, FSM& fsm,SourceState& ,TargetState& )
|
||||
{
|
||||
++e.cpt_;
|
||||
++fsm.test_fct_counter;
|
||||
}
|
||||
};
|
||||
@@ -176,8 +182,9 @@ namespace
|
||||
struct resume_playback
|
||||
{
|
||||
template <class EVT,class FSM,class SourceState,class TargetState>
|
||||
void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
|
||||
void operator()(EVT& e,FSM& ,SourceState& ,TargetState& )
|
||||
{
|
||||
++e.cpt_;
|
||||
}
|
||||
};
|
||||
struct stop_and_open
|
||||
@@ -287,70 +294,72 @@ namespace
|
||||
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
// static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( SimpleWithFunctorsTest )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( simple_with_functors_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 1,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(open_close());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_DVD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Open&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(
|
||||
cd_detected("louie, louie",DISK_CD));
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Empty&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 1,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.test_fct_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 1,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing
|
||||
p.process_event(end_pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().entry_counter == 2,"Playing entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().event_counter == 1,"Playing event counter incorrect");
|
||||
|
||||
p.process_event(pause());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Playing&>().exit_counter == 2,"Playing exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Paused&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(stop());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Stopped&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/puml/puml.hpp>
|
||||
#include <PumlCommon.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_simple_with_puml_test
|
||||
#define BOOST_TEST_MODULE simple_with_puml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -68,68 +68,68 @@ namespace
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( back11_simple_with_puml_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( simple_with_puml_test, player, players )
|
||||
{
|
||||
player p;
|
||||
|
||||
p.start();
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().entry_counter == 1, "Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 1, "Empty entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("open_close")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Open")>&>().entry_counter == 1,"Open entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().exit_counter == 1,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().entry_counter == 1,"Open entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("open_close")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("cd_detected")>{"louie, louie", DISK_DVD});
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("cd_detected")>{"louie, louie", DISK_CD});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing2 should be active"); //Playing2
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Empty")>&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Playing2")>&>().entry_counter == 1,"Playing2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().exit_counter == 2,"Empty exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 1,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().exit_counter == 1,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing2")>&>().entry_counter == 1,"Playing2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.start_playback_counter == 1,"action not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.test_fct_counter == 1,"action not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("pause")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Playing2")>&>().exit_counter == 1,"Playing2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Paused")>&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing2")>&>().exit_counter == 1,"Playing2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().entry_counter == 1,"Paused entry not called correctly");
|
||||
|
||||
// go back to Playing2
|
||||
p.process_event(Event<by_name("end_pause")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing2 should be active"); //Playing2
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Paused")>&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Playing2")>&>().entry_counter == 2,"Playing2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Playing2")>&>().event_counter == 1,"Playing2 event counter incorrect");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().exit_counter == 1,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing2")>&>().entry_counter == 2,"Playing2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing2")>&>().event_counter == 1,"Playing2 event counter incorrect");
|
||||
|
||||
p.process_event(Event<by_name("pause")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Playing2")>&>().exit_counter == 2,"Playing2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Paused")>&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing2")>&>().exit_counter == 2,"Playing2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().entry_counter == 2,"Paused entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("stop")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Paused")>&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().exit_counter == 2,"Paused exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 2,"Stopped entry not called correctly");
|
||||
|
||||
p.process_event(Event<by_name("stop")>{});
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<State<by_name("Stopped")>&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().exit_counter == 2,"Stopped exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 3,"Stopped entry not called correctly");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/puml/puml.hpp>
|
||||
#include <PumlCommon.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_only_string_puml_test
|
||||
#define BOOST_TEST_MODULE string_terminate_puml_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -58,10 +58,10 @@ namespace
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back11::state_machine<front_> machine;
|
||||
typedef get_test_machines<front_> machines;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_string_terminate_puml_test)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(string_terminate_puml_test, machine, machines)
|
||||
{
|
||||
machine p;
|
||||
static_assert(msm::back11::get_number_of_regions<typename machine::initial_state>::type::value == 2);
|
||||
@@ -9,7 +9,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
// functors
|
||||
@@ -18,6 +18,9 @@
|
||||
// for And_ operator
|
||||
#include <boost/msm/front/euml/operator.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE test_2_regions_anonymous
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
@@ -139,9 +142,9 @@ namespace
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<my_machine_> my_machine;
|
||||
typedef get_test_machines<my_machine_> my_machines;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( test_2_regions_anonymous, my_machine, my_machines )
|
||||
{
|
||||
my_machine p;
|
||||
|
||||
@@ -153,16 +156,16 @@ namespace
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"State3 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State1b should be active");
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().exit_counter == 0,"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State3&>().entry_counter == 1,"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1b&>().entry_counter == 1,"State1b entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State1b&>().exit_counter == 0,"State1b exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2b&>().entry_counter == 0,"State2b entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<my_machine_::State2b&>().exit_counter == 0,"State2b exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().exit_counter == 1,"State1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1&>().entry_counter == 1,"State1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().exit_counter == 1,"State2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2&>().entry_counter == 1,"State2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State3&>().exit_counter == 0,"State3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State3&>().entry_counter == 1,"State3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1b&>().entry_counter == 1,"State1b entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State1b&>().exit_counter == 0,"State1b exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2b&>().entry_counter == 0,"State2b entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<my_machine_::State2b&>().exit_counter == 0,"State2b exit not called correctly");
|
||||
|
||||
|
||||
}
|
||||
|
||||
+33
-16
@@ -9,11 +9,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE test_constructor
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
@@ -55,9 +55,14 @@ namespace
|
||||
DiskTypeEnum disc_type;
|
||||
};
|
||||
|
||||
template<template <typename...> class Back, typename Policy = void>
|
||||
struct hierarchical_state_machine
|
||||
{
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(player_);
|
||||
|
||||
player_(SomeExternalContext& context,int someint)
|
||||
:context_(context)
|
||||
{
|
||||
@@ -108,6 +113,8 @@ namespace
|
||||
|
||||
struct Playing_ : public msm::front::state_machine_def<Playing_>
|
||||
{
|
||||
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Playing_);
|
||||
|
||||
// when playing, the CD is loaded and we are in either pause or playing (duh)
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {std::cout << "entering: Playing" << std::endl;}
|
||||
@@ -168,7 +175,7 @@ namespace
|
||||
}
|
||||
};
|
||||
// back-end
|
||||
typedef msm::back::state_machine<Playing_> Playing;
|
||||
typedef Back<Playing_, Policy> Playing;
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused : public msm::front::state<>
|
||||
@@ -238,26 +245,36 @@ namespace
|
||||
BOOST_FAIL("no_transition called!");
|
||||
}
|
||||
};
|
||||
typedef Back<player_, Policy> player;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
// typedef msm::back::state_machine<player_> player;
|
||||
typedef boost::mpl::vector<
|
||||
hierarchical_state_machine<boost::msm::back::state_machine>,
|
||||
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
|
||||
hierarchical_state_machine<boost::msm::back11::state_machine>
|
||||
> test_machines;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( my_test )
|
||||
{
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( test_constructor, test_machine, test_machines )
|
||||
{
|
||||
typedef typename test_machine::player player;
|
||||
typedef typename test_machine::player_ player_;
|
||||
|
||||
SomeExternalContext ctx(3);
|
||||
player p1(boost::ref(ctx),5);
|
||||
BOOST_CHECK_MESSAGE(p1.context_.bla == 10,"Wrong returned context value");
|
||||
|
||||
ctx.bla = 3;
|
||||
player p2(msm::back::states_ << player_::Empty(1),boost::ref(ctx),5);
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<player_::Empty&>().data_ == 1,"Wrong Empty value");
|
||||
player p2(msm::back::states_ << typename player_::Empty(1),boost::ref(ctx),5);
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<typename player_::Empty&>().data_ == 1,"Wrong Empty value");
|
||||
|
||||
p2.set_states(msm::back::states_ << player_::Empty(5));
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<player_::Empty&>().data_ == 5,"Wrong Empty value");
|
||||
p2.set_states(msm::back::states_ << typename player_::Empty(5));
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<typename player_::Empty&>().data_ == 5,"Wrong Empty value");
|
||||
|
||||
p2.set_states(msm::back::states_ << player_::Empty(7) << player_::Open(2));
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<player_::Empty&>().data_ == 7,"Wrong Empty value");
|
||||
BOOST_CHECK_MESSAGE(p2.get_state<player_::Open&>().data_ == 2,"Wrong Open value");
|
||||
p2.set_states(msm::back::states_ << typename player_::Empty(7) << typename player_::Open(2));
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<typename player_::Empty&>().data_ == 7,"Wrong Empty value");
|
||||
BOOST_CHECK_MESSAGE(p2.template get_state<typename player_::Open&>().data_ == 2,"Wrong Open value");
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC >= 1910 && BOOST_MSVC < 1930
|
||||
|
||||
@@ -270,10 +287,10 @@ namespace
|
||||
#else
|
||||
|
||||
ctx.bla = 3;
|
||||
player p(msm::back::states_ << player_::Empty(1)
|
||||
<< player_::Playing(msm::back::states_ << player_::Playing_::Song1(8)),
|
||||
player p(msm::back::states_ << typename player_::Empty(1)
|
||||
<< typename player_::Playing(msm::back::states_ << typename player_::Playing_::Song1(8)),
|
||||
boost::ref(ctx),5);
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Playing&>().get_state<player_::Playing_::Song1&>().data_ == 8,"Wrong Open value");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing_::Song1&>().data_ == 8,"Wrong Open value");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
#include <memory>
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE MyTest
|
||||
#define BOOST_TEST_MODULE test_constructor_movable_only_types
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -94,9 +94,9 @@ namespace
|
||||
};
|
||||
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<bistable_switch_> bistable_switch;
|
||||
typedef get_test_machines<bistable_switch_> bistable_switches;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(my_test)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test_constructor_movable_only_types, bistable_switch, bistable_switches)
|
||||
{
|
||||
auto bulp = std::make_unique<Lightbulp>(3);
|
||||
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE test_defer_and_message_queue
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
@@ -162,9 +165,9 @@ namespace
|
||||
int expected_action_counter;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestDeferAndMessageQueue )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( test_defer_and_message_queue, player, players )
|
||||
{
|
||||
player p;
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
@@ -173,17 +176,17 @@ namespace
|
||||
p.process_event(eventConnect());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Resolving should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 3,"State22 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Unresolved&>().exit_counter == 1,"Unresolved exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Unresolved&>().entry_counter == 1,"Unresolved entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Resolving&>().entry_counter == 1,"Resolving entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Unresolved&>().exit_counter == 1,"Unresolved exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Unresolved&>().entry_counter == 1,"Unresolved entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Resolving&>().entry_counter == 1,"Resolving entry not called correctly");
|
||||
|
||||
p.process_event(eventResolved());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Connecting should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 3,"State22 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Resolved&>().exit_counter == 1,"Resolved exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Resolved&>().entry_counter == 1,"Resolved entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Resolving&>().exit_counter == 1,"Resolving exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::Connecting&>().entry_counter == 1,"Connecting entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Resolved&>().exit_counter == 1,"Resolved exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Resolved&>().entry_counter == 1,"Resolved entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Resolving&>().exit_counter == 1,"Resolving exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::Connecting&>().entry_counter == 1,"Connecting entry not called correctly");
|
||||
|
||||
BOOST_CHECK_MESSAGE(p.expected_action_counter == 1,"expected_action should have been called");
|
||||
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE test_defer_and_message_queue_2
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
@@ -126,9 +129,9 @@ namespace
|
||||
int expected_action2_counter;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestDeferAndMessageQueue2 )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( test_defer_and_message_queue_2, player, players )
|
||||
{
|
||||
player p;
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
@@ -136,16 +139,16 @@ namespace
|
||||
|
||||
p.process_event(eventd());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State11 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State11 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().exit_counter == 1,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 2,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State13&>().exit_counter == 1,"State13 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State13&>().entry_counter == 1,"State13 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State12&>().exit_counter == 1,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().entry_counter == 2,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State13&>().exit_counter == 1,"State13 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State13&>().entry_counter == 1,"State13 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.expected_action_counter == 1,"expected_action should have been called");
|
||||
BOOST_CHECK_MESSAGE(p.expected_action2_counter == 0,"expected_action2 should not have been called");
|
||||
}
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE test_defer_and_message_queue_3
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
@@ -129,9 +132,9 @@ namespace
|
||||
int expected_action2_counter;
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestDeferAndMessageQueue2 )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( test_defer_and_message_queue_3, player, players )
|
||||
{
|
||||
player p;
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
@@ -139,16 +142,16 @@ namespace
|
||||
|
||||
p.process_event(eventd());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State11 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"State11 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().exit_counter == 1,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 2,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State13&>().exit_counter == 1,"State13 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State13&>().entry_counter == 1,"State13 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State12&>().exit_counter == 1,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().entry_counter == 2,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State13&>().exit_counter == 1,"State13 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State13&>().entry_counter == 1,"State13 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.expected_action_counter == 0,"expected_action should have been called");
|
||||
BOOST_CHECK_MESSAGE(p.expected_action2_counter == 1,"expected_action2 should not have been called");
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE Back11TestDeferIn2Regions
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
@@ -44,7 +46,7 @@ namespace
|
||||
};
|
||||
struct State12 : public msm::front::state<>
|
||||
{
|
||||
typedef mpl::vector<eventd> deferred_events;
|
||||
typedef boost::fusion::vector<eventd> deferred_events;
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {++entry_counter;}
|
||||
template <class Event,class FSM>
|
||||
@@ -80,11 +82,11 @@ namespace
|
||||
int exit_counter;
|
||||
};
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef mpl::vector<State11,State21> initial_state;
|
||||
typedef boost::fusion::vector<State11,State21> initial_state;
|
||||
|
||||
|
||||
// Transition table for player
|
||||
struct transition_table : mpl::vector<
|
||||
struct transition_table : boost::fusion::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+-------------+---------+---------------------+----------------------+
|
||||
Row < State11 , event1 , State12 >,
|
||||
@@ -116,9 +118,9 @@ namespace
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
typedef get_test_machines<player_> players;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestDeferIn2Regions )
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE( Back11TestDeferIn2Regions, player, players )
|
||||
{
|
||||
player p;
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
@@ -127,40 +129,40 @@ namespace
|
||||
p.process_event(event1());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
|
||||
// deferred
|
||||
p.process_event(eventd());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State12&>().exit_counter == 0,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 0,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 1,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 0,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 0,"State22 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().exit_counter == 1,"State11 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State11&>().entry_counter == 1,"State11 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State12&>().entry_counter == 1,"State12 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State12&>().exit_counter == 0,"State12 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State21&>().exit_counter == 0,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State21&>().entry_counter == 1,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State22&>().exit_counter == 0,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State22&>().entry_counter == 0,"State22 entry not called correctly");
|
||||
|
||||
p.process_event(event3());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"State12 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 1,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 2,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 1,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 1,"State22 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State21&>().exit_counter == 1,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State21&>().entry_counter == 2,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State22&>().exit_counter == 1,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State22&>().entry_counter == 1,"State22 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_deferred_queue().size() == 1,"Deferred queue should have one element");
|
||||
p.clear_deferred_queue();
|
||||
|
||||
p.process_event(event2());
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"State13 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.current_state()[1] == 2,"State21 should be active");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().exit_counter == 1,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State21&>().entry_counter == 2,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().exit_counter == 1,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_state<player_::State22&>().entry_counter == 1,"State22 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State21&>().exit_counter == 1,"State21 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State21&>().entry_counter == 2,"State21 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State22&>().exit_counter == 1,"State22 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.template get_state<player_::State22&>().entry_counter == 1,"State22 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(p.get_deferred_queue().size() == 0,"Deferred queue should have no element");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE Back11ThrowingTest
|
||||
#define BOOST_TEST_MODULE throwing_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -113,23 +113,23 @@ namespace
|
||||
}
|
||||
};
|
||||
|
||||
using MyMachine = boost::msm::back11::state_machine<MyMachineFrontend>;
|
||||
using MyMachines = get_test_machines<MyMachineFrontend>;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Back11ThrowingTest)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(throwing_test, MyMachine, MyMachines)
|
||||
{
|
||||
MyMachine m;
|
||||
m.start();
|
||||
|
||||
BOOST_CHECK_MESSAGE(m.get_state<Init&>().entry_counter == 1, "Init entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.get_state<Init&>().exit_counter == 1, "Init exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.get_state<Intermediate&>().entry_counter == 0, "Intermediate entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.get_state<Intermediate&>().exit_counter == 0, "Intermediate exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.template get_state<Init&>().entry_counter == 1, "Init entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.template get_state<Init&>().exit_counter == 1, "Init exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.template get_state<Intermediate&>().entry_counter == 0, "Intermediate entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.template get_state<Intermediate&>().exit_counter == 0, "Intermediate exit not called correctly");
|
||||
|
||||
BOOST_CHECK_MESSAGE(m.get_state<WaitingForException&>().entry_counter == 1, "WaitingForException entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.get_state<WaitingForException&>().exit_counter == 1, "WaitingForException exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.get_state<End&>().entry_counter == 1, "End entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.get_state<End&>().exit_counter == 0, "End exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.template get_state<WaitingForException&>().entry_counter == 1, "WaitingForException entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.template get_state<WaitingForException&>().exit_counter == 1, "WaitingForException exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.template get_state<End&>().entry_counter == 1, "End entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(m.template get_state<End&>().exit_counter == 0, "End exit not called correctly");
|
||||
|
||||
|
||||
BOOST_CHECK_MESSAGE(m.current_state()[0] == 0, "Init should be active");
|
||||
@@ -11,20 +11,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_transition_skipping
|
||||
#define BOOST_TEST_MODULE transition_skipping_test
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
//#define USE_PRE11_MSM_BACKEND // <- toggle this to switch between back vs back11
|
||||
|
||||
// back-end
|
||||
#if defined(USE_PRE11_MSM_BACKEND)
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
namespace msm_back = boost::msm::back;
|
||||
#else
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
namespace msm_back = boost::msm::back11;
|
||||
#endif
|
||||
#include "BackCommon.hpp"
|
||||
|
||||
// front-end
|
||||
#include <boost/fusion/include/insert_range.hpp>
|
||||
@@ -135,26 +126,26 @@ struct top_ : public msmf::state_machine_def<top_> {
|
||||
>;
|
||||
};
|
||||
|
||||
using top = msm_back::state_machine<top_>;
|
||||
using tops = get_test_machines<top_>;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_transition_skipping)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(transition_skipping_test, top, tops)
|
||||
{
|
||||
top msm;
|
||||
msm.start();
|
||||
BOOST_CHECK_MESSAGE(msm.count_guard_true == 1, "guard_true should be called once");
|
||||
BOOST_CHECK_MESSAGE(msm.count_guard_false == 2, "guard_false should be called once");
|
||||
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::nested&>().exit_counter == 1, "nested exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::nested&>().entry_counter == 1, "nested entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other2&>().exit_counter == 0, "other2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other2&>().entry_counter == 1, "other2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other1&>().exit_counter == 0, "other1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other1&>().entry_counter == 0, "other1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other3&>().exit_counter == 0, "other3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other3&>().entry_counter == 0, "other3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other4&>().exit_counter == 0, "other4 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other4&>().entry_counter == 0, "other4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::nested&>().exit_counter == 1, "nested exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::nested&>().entry_counter == 1, "nested entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::other2&>().exit_counter == 0, "other2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::other2&>().entry_counter == 1, "other2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::other1&>().exit_counter == 0, "other1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::other1&>().entry_counter == 0, "other1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::other3&>().exit_counter == 0, "other3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::other3&>().entry_counter == 0, "other3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::other4&>().exit_counter == 0, "other4 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.template get_state<top_::other4&>().entry_counter == 0, "other4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.current_state()[0] == 2, "other2 should be active"); //Open
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user