sl@0: #ifndef BOOST_STATECHART_TRANSITION_HPP_INCLUDED sl@0: #define BOOST_STATECHART_TRANSITION_HPP_INCLUDED sl@0: ////////////////////////////////////////////////////////////////////////////// sl@0: // Copyright 2002-2006 Andreas Huber Doenni sl@0: // Distributed under the Boost Software License, Version 1.0. (See accompany- sl@0: // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) sl@0: ////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: sl@0: sl@0: #include sl@0: sl@0: #include sl@0: sl@0: #include // boost::polymorphic_downcast sl@0: #include sl@0: sl@0: sl@0: sl@0: namespace boost sl@0: { sl@0: namespace statechart sl@0: { sl@0: namespace detail sl@0: { sl@0: sl@0: sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////// sl@0: template< class Event > sl@0: struct no_context sl@0: { sl@0: void no_function( const Event & ); sl@0: }; sl@0: sl@0: sl@0: sl@0: } // namespace detail sl@0: sl@0: sl@0: sl@0: class event_base; sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////// sl@0: template< class Event, class Destination, sl@0: class TransitionContext = detail::no_context< Event >, sl@0: void ( TransitionContext::*pTransitionAction )( const Event & ) = sl@0: &detail::no_context< Event >::no_function > sl@0: class transition sl@0: { sl@0: private: sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: struct react_without_transition_action_impl sl@0: { sl@0: template< class State, class EventBase > sl@0: static detail::reaction_result react( State & stt, const EventBase & ) sl@0: { sl@0: return detail::result_utility::get_result( sl@0: stt.template transit< Destination >() ); sl@0: } sl@0: }; sl@0: sl@0: struct react_base_with_transition_action_impl sl@0: { sl@0: template< class State, class EventBase > sl@0: static detail::reaction_result react( sl@0: State & stt, const EventBase & toEvent ) sl@0: { sl@0: return detail::result_utility::get_result( sl@0: stt.template transit< Destination >( pTransitionAction, toEvent ) ); sl@0: } sl@0: }; sl@0: sl@0: struct react_base sl@0: { sl@0: template< class State, class EventBase, class IdType > sl@0: static detail::reaction_result react( sl@0: State & stt, const EventBase & evt, const IdType & ) sl@0: { sl@0: typedef typename mpl::if_< sl@0: is_same< TransitionContext, detail::no_context< Event > >, sl@0: react_without_transition_action_impl, sl@0: react_base_with_transition_action_impl sl@0: >::type impl; sl@0: return impl::react( stt, evt ); sl@0: } sl@0: }; sl@0: sl@0: struct react_derived_with_transition_action_impl sl@0: { sl@0: template< class State, class EventBase > sl@0: static detail::reaction_result react( sl@0: State & stt, const EventBase & toEvent ) sl@0: { sl@0: return detail::result_utility::get_result( sl@0: stt.template transit< Destination >( sl@0: pTransitionAction, sl@0: *polymorphic_downcast< const Event * >( &toEvent ) ) ); sl@0: } sl@0: }; sl@0: sl@0: struct react_derived sl@0: { sl@0: template< class State, class EventBase, class IdType > sl@0: static detail::reaction_result react( sl@0: State & stt, const EventBase & evt, const IdType & eventType ) sl@0: { sl@0: if ( eventType == Event::static_type() ) sl@0: { sl@0: typedef typename mpl::if_< sl@0: is_same< TransitionContext, detail::no_context< Event > >, sl@0: react_without_transition_action_impl, sl@0: react_derived_with_transition_action_impl sl@0: >::type impl; sl@0: return impl::react( stt, evt ); sl@0: } sl@0: else sl@0: { sl@0: return detail::no_reaction; sl@0: } sl@0: } sl@0: }; sl@0: sl@0: public: sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: // The following declarations should be private. sl@0: // They are only public because many compilers lack template friends. sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: template< class State, class EventBase, class IdType > sl@0: static detail::reaction_result react( sl@0: State & stt, const EventBase & evt, const IdType & eventType ) sl@0: { sl@0: typedef typename mpl::if_< sl@0: is_same< Event, event_base >, react_base, react_derived sl@0: >::type impl; sl@0: sl@0: return impl::react( stt, evt, eventType ); sl@0: } sl@0: }; sl@0: sl@0: sl@0: sl@0: } // namespace statechart sl@0: } // namespace boost sl@0: sl@0: sl@0: sl@0: #endif