• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
WaitingWaiting38     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         &MyScheduler::queue_event,
48         &machine.my_scheduler(), machine.my_handle(), _1 );
49       pBallReturned_->abortGame = boost::bind(
50         &MyScheduler::queue_event,
51         &machine.my_scheduler(), machine.my_handle(),
52         MakeIntrusive( new GameAborted() ) );
53     }
54 
reactWaiting55     sc::result react( const GameAborted & )
56     {
57       return DestroyMyself();
58     }
59 
reactWaiting60     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     //////////////////////////////////////////////////////////////////////////
DestroyMyselfWaiting79     sc::result DestroyMyself()
80     {
81       outermost_context_type & machine = outermost_context();
82       machine.my_scheduler().destroy_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