1 //////////////////////////////////////////////////////////////////////////////
2 // Copyright 2005-2008 Andreas Huber Doenni
3 // Distributed under the Boost Software License, Version 1.0. (See accompany-
4 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //////////////////////////////////////////////////////////////////////////////
6 
7 
8 
9 #include <boost/statechart/state_machine.hpp>
10 #include <boost/statechart/event.hpp>
11 #include <boost/statechart/simple_state.hpp>
12 #include <boost/statechart/in_state_reaction.hpp>
13 #include <boost/statechart/result.hpp>
14 
15 #include <boost/mpl/list.hpp>
16 
17 #include <boost/test/test_tools.hpp>
18 
19 namespace sc = boost::statechart;
20 namespace mpl = boost::mpl;
21 
22 
23 struct E : sc::event< E > {};
24 struct F : sc::event< F > {};
25 struct G : sc::event< G > {};
26 struct H : sc::event< H > {};
27 struct I : sc::event< I > {};
28 
29 struct A;
30 struct InStateReactionTest : sc::state_machine< InStateReactionTest, A > {};
31 
32 struct B;
33 struct A : sc::simple_state< A, InStateReactionTest, B >
34 {
AA35   A() : eventCount_( 0 ) {}
36 
37   // The following 3 functions could be implemented with one function
38   // template, but this causes problems with CW and Intel 9.1.
IncrementCountA39   void IncrementCount( const sc::event_base & ) { ++eventCount_; }
IncrementCountA40   void IncrementCount( const E & ) { ++eventCount_; }
IncrementCountA41   void IncrementCount( const G & ) { ++eventCount_; }
42 
43   typedef mpl::list<
44     sc::in_state_reaction< E, A, &A::IncrementCount >,
45     sc::in_state_reaction< sc::event_base, A, &A::IncrementCount >
46   > reactions;
47 
48   unsigned int eventCount_;
49 };
50 
51   struct B : sc::simple_state< B, A >
52   {
BB53     B() : eventCount_( 0 ) {}
54 
IncrementCountB55     void IncrementCount( const F & )
56     {
57       ++eventCount_;
58     }
59 
60     typedef mpl::list<
61       sc::in_state_reaction< F, B, &B::IncrementCount >,
62       sc::in_state_reaction< G, A, &A::IncrementCount >,
63       sc::in_state_reaction< I >
64     > reactions;
65 
66     unsigned int eventCount_;
67   };
68 
69 
70 
RequireEventCounts(const InStateReactionTest & machine,unsigned int aCount,unsigned int bCount)71 void RequireEventCounts(
72   const InStateReactionTest & machine,
73   unsigned int aCount, unsigned int bCount)
74 {
75   BOOST_REQUIRE(
76     machine.state_downcast< const A & >().eventCount_ == aCount );
77   BOOST_REQUIRE(
78     machine.state_downcast< const B & >().eventCount_ == bCount );
79 }
80 
test_main(int,char * [])81 int test_main( int, char* [] )
82 {
83   InStateReactionTest machine;
84   machine.initiate();
85 
86   RequireEventCounts(machine, 0, 0);
87   machine.process_event( F() );
88   RequireEventCounts(machine, 0, 1);
89   machine.process_event( E() );
90   RequireEventCounts(machine, 1, 1);
91   machine.process_event( E() );
92   machine.process_event( F() );
93   RequireEventCounts(machine, 2, 2);
94   machine.process_event( G() );
95   RequireEventCounts(machine, 3, 2);
96   machine.process_event( H() );
97   RequireEventCounts(machine, 4, 2);
98   machine.process_event( I() );
99   RequireEventCounts(machine, 4, 2);
100 
101   return 0;
102 }
103