1 | #ifndef BOOST_STATECHART_EXAMPLE_WAITING_HPP_INCLUDED |
2 | #define BOOST_STATECHART_EXAMPLE_WAITING_HPP_INCLUDED |
3 | ////////////////////////////////////////////////////////////////////////////// |
4 | // Copyright 2008 Andreas Huber Doenni |
5 | // Distributed under the Boost Software License, Version 1.0. (See accompany- |
6 | // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7 | ////////////////////////////////////////////////////////////////////////////// |
8 | |
9 | |
10 | #include "Player.hpp" |
11 | |
12 | #include <boost/statechart/state.hpp> |
13 | #include <boost/statechart/transition.hpp> |
14 | #include <boost/statechart/custom_reaction.hpp> |
15 | |
16 | #include <boost/intrusive_ptr.hpp> |
17 | #include <boost/mpl/list.hpp> |
18 | #include <boost/function.hpp> |
19 | #include <boost/bind.hpp> |
20 | |
21 | |
22 | |
23 | namespace sc = boost::statechart; |
24 | namespace mpl = boost::mpl; |
25 | |
26 | |
27 | |
28 | ////////////////////////////////////////////////////////////////////////////// |
29 | struct Waiting : sc::state< Waiting, Player > |
30 | { |
31 | public: |
32 | ////////////////////////////////////////////////////////////////////////// |
33 | typedef mpl::list< |
34 | sc::custom_reaction< BallReturned >, |
35 | sc::custom_reaction< GameAborted > |
36 | > reactions; |
37 | |
38 | Waiting( my_context ctx ) : |
39 | my_base( ctx ), |
40 | noOfReturns_( 0 ), |
41 | pBallReturned_( new BallReturned() ) |
42 | { |
43 | outermost_context_type & machine = outermost_context(); |
44 | // as we will always return the same event to the opponent, we construct |
45 | // and fill it here so that we can reuse it over and over |
46 | pBallReturned_->returnToOpponent = boost::bind( |
47 | f: &MyScheduler::queue_event, |
48 | a1: &machine.my_scheduler(), a2: machine.my_handle(), a3: _1 ); |
49 | pBallReturned_->abortGame = boost::bind( |
50 | f: &MyScheduler::queue_event, |
51 | a1: &machine.my_scheduler(), a2: machine.my_handle(), |
52 | a3: MakeIntrusive( pObject: new GameAborted() ) ); |
53 | } |
54 | |
55 | sc::result react( const GameAborted & ) |
56 | { |
57 | return DestroyMyself(); |
58 | } |
59 | |
60 | sc::result react( const BallReturned & ballReturned ) |
61 | { |
62 | outermost_context_type & machine = outermost_context(); |
63 | ++machine.TotalNoOfProcessedEvents(); |
64 | |
65 | if ( noOfReturns_++ < machine.GetMaxNoOfReturns() ) |
66 | { |
67 | ballReturned.returnToOpponent( pBallReturned_ ); |
68 | return discard_event(); |
69 | } |
70 | else |
71 | { |
72 | ballReturned.abortGame(); |
73 | return DestroyMyself(); |
74 | } |
75 | } |
76 | |
77 | private: |
78 | ////////////////////////////////////////////////////////////////////////// |
79 | sc::result DestroyMyself() |
80 | { |
81 | outermost_context_type & machine = outermost_context(); |
82 | machine.my_scheduler().destroy_processor( processor: machine.my_handle() ); |
83 | machine.my_scheduler().terminate(); |
84 | return terminate(); |
85 | } |
86 | |
87 | // avoids C4512 (assignment operator could not be generated) |
88 | Waiting & operator=( const Waiting & ); |
89 | |
90 | unsigned int noOfReturns_; |
91 | const boost::intrusive_ptr< BallReturned > pBallReturned_; |
92 | }; |
93 | |
94 | |
95 | |
96 | #endif |
97 | |