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