Waiting.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. #include "Player.hpp"
  9. #include <boost/statechart/state.hpp>
  10. #include <boost/statechart/transition.hpp>
  11. #include <boost/statechart/custom_reaction.hpp>
  12. #include <boost/intrusive_ptr.hpp>
  13. #include <boost/mpl/list.hpp>
  14. #include <boost/function.hpp>
  15. #include <boost/bind.hpp>
  16. namespace sc = boost::statechart;
  17. namespace mpl = boost::mpl;
  18. //////////////////////////////////////////////////////////////////////////////
  19. struct Waiting : sc::state< Waiting, Player >
  20. {
  21. public:
  22. //////////////////////////////////////////////////////////////////////////
  23. typedef mpl::list<
  24. sc::custom_reaction< BallReturned >,
  25. sc::custom_reaction< GameAborted >
  26. > reactions;
  27. Waiting( my_context ctx ) :
  28. my_base( ctx ),
  29. noOfReturns_( 0 ),
  30. pBallReturned_( new BallReturned() )
  31. {
  32. outermost_context_type & machine = outermost_context();
  33. // as we will always return the same event to the opponent, we construct
  34. // and fill it here so that we can reuse it over and over
  35. pBallReturned_->returnToOpponent = boost::bind(
  36. &MyScheduler::queue_event,
  37. &machine.my_scheduler(), machine.my_handle(), _1 );
  38. pBallReturned_->abortGame = boost::bind(
  39. &MyScheduler::queue_event,
  40. &machine.my_scheduler(), machine.my_handle(),
  41. MakeIntrusive( new GameAborted() ) );
  42. }
  43. sc::result react( const GameAborted & )
  44. {
  45. return DestroyMyself();
  46. }
  47. sc::result react( const BallReturned & ballReturned )
  48. {
  49. outermost_context_type & machine = outermost_context();
  50. ++machine.TotalNoOfProcessedEvents();
  51. if ( noOfReturns_++ < machine.GetMaxNoOfReturns() )
  52. {
  53. ballReturned.returnToOpponent( pBallReturned_ );
  54. return discard_event();
  55. }
  56. else
  57. {
  58. ballReturned.abortGame();
  59. return DestroyMyself();
  60. }
  61. }
  62. private:
  63. //////////////////////////////////////////////////////////////////////////
  64. sc::result DestroyMyself()
  65. {
  66. outermost_context_type & machine = outermost_context();
  67. machine.my_scheduler().destroy_processor( machine.my_handle() );
  68. machine.my_scheduler().terminate();
  69. return terminate();
  70. }
  71. // avoids C4512 (assignment operator could not be generated)
  72. Waiting & operator=( const Waiting & );
  73. unsigned int noOfReturns_;
  74. const boost::intrusive_ptr< BallReturned > pBallReturned_;
  75. };
  76. #endif