📄 simple_state.hpp
字号:
outermost_context_base().template clear_shallow_history<
HistoryContext, orthogonalPosition >();
}
template<
class HistoryContext,
detail::orthogonal_position_type orthogonalPosition >
void clear_deep_history()
{
outermost_context_base().template clear_deep_history<
HistoryContext, orthogonalPosition >();
}
protected:
//////////////////////////////////////////////////////////////////////////
simple_state() : pContext_( 0 ) {}
~simple_state()
{
// As a result of a throwing derived class constructor, this destructor
// can be called before the context is set.
if ( get_pointer( pContext_ ) != 0 )
{
if ( this->deferred_events() )
{
outermost_context_base().release_events( this );
}
pContext_->remove_inner_state( orthogonal_position::value );
}
}
public:
//////////////////////////////////////////////////////////////////////////
// The following declarations should be private.
// They are only public because many compilers lack template friends.
//////////////////////////////////////////////////////////////////////////
typedef typename Context::inner_orthogonal_position orthogonal_position;
// If you receive a
// "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
// compiler error here then either this state resides in a non-existent
// orthogonal region of the outer state or the outer state does not have
// inner states.
BOOST_STATIC_ASSERT( ( mpl::less<
orthogonal_position,
typename context_type::no_of_orthogonal_regions >::value ) );
typedef MostDerived inner_context_type;
typedef mpl::integral_c< detail::orthogonal_position_type, 0 >
inner_orthogonal_position;
typedef typename context_type::event_base_type event_base_type;
typedef typename context_type::rtti_policy_type rtti_policy_type;
typedef typename context_type::outermost_context_base_type
outermost_context_base_type;
typedef typename context_type::inner_context_ptr_type context_ptr_type;
typedef typename context_type::state_list_type state_list_type;
typedef intrusive_ptr< inner_context_type > inner_context_ptr_type;
typedef typename detail::make_list< InnerInitial >::type
inner_initial_list;
typedef typename mpl::size< inner_initial_list >::type
inner_initial_list_size;
typedef mpl::integral_c<
detail::orthogonal_position_type,
inner_initial_list_size::value > no_of_orthogonal_regions;
typedef typename mpl::push_front<
typename context_type::context_type_list,
context_type >::type context_type_list;
// If you receive a
// "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
// compiler error here then the direct or indirect context of this state
// has deep history _and_ this state has two or more orthogonal regions.
// Boost.Statechart does not currently support deep history in a state whose
// direct or indirect inner states have two or more orthogonal regions.
// Please consult the documentation on how to work around this limitation.
BOOST_STATIC_ASSERT( ( mpl::or_<
mpl::less<
no_of_orthogonal_regions,
mpl::integral_c< detail::orthogonal_position_type, 2 > >,
mpl::not_<
typename context_type::inherited_deep_history > >::value ) );
typedef mpl::bool_< ( historyMode & has_shallow_history ) != 0 >
shallow_history;
typedef typename context_type::shallow_history stores_shallow_history;
typedef mpl::bool_< ( historyMode & has_deep_history ) != 0 >
deep_history;
typedef typename mpl::or_<
deep_history,
typename context_type::inherited_deep_history
>::type inherited_deep_history;
typedef typename mpl::and_<
inherited_deep_history,
mpl::empty< inner_initial_list > >::type stores_deep_history;
void * operator new( std::size_t size )
{
return detail::allocate< MostDerived,
typename outermost_context_type::allocator_type >( size );
}
void operator delete( void * pState )
{
detail::deallocate< MostDerived,
typename outermost_context_type::allocator_type >( pState );
}
outermost_context_base_type & outermost_context_base()
{
// This assert fails when an attempt is made to access the state machine
// from a constructor of a state that is *not* a subtype of state<>.
// To correct this, derive from state<> instead of simple_state<>.
BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
return pContext_->outermost_context_base();
}
const outermost_context_base_type & outermost_context_base() const
{
// This assert fails when an attempt is made to access the state machine
// from a constructor of a state that is *not* a subtype of state<>.
// To correct this, derive from state<> instead of simple_state<>.
BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
return pContext_->outermost_context_base();
}
virtual const state_base_type * outer_state_ptr() const
{
typedef typename mpl::if_<
is_same< outermost_context_type, context_type >,
outer_state_ptr_impl_outermost,
outer_state_ptr_impl_non_outermost
>::type impl;
return impl::outer_state_ptr_impl( *this );
}
virtual detail::reaction_result react_impl(
const event_base_type & evt,
typename rtti_policy_type::id_type eventType )
{
typedef typename detail::make_list<
typename MostDerived::reactions >::type reaction_list;
detail::reaction_result reactionResult =
local_react< reaction_list >( evt, eventType );
// At this point we can only safely access pContext_ if the handler did
// not return do_discard_event!
switch ( reactionResult )
{
case detail::do_forward_event:
// TODO: The following call to react_impl of our outer state should
// be made with a context_type:: prefix to call directly instead of
// virtually. For some reason the compiler complains...
reactionResult = pContext_->react_impl( evt, eventType );
break;
case detail::do_defer_event:
outermost_context_base().defer_event( evt, this );
break;
default:
break;
}
return reactionResult;
}
virtual void exit_impl(
typename base_type::direct_state_base_ptr_type & pSelf,
typename state_base_type::node_state_base_ptr_type &
pOutermostUnstableState,
bool performFullExit )
{
inner_context_ptr_type pMostDerivedSelf =
polymorphic_downcast< MostDerived * >( this );
pSelf = 0;
exit_impl( pMostDerivedSelf, pOutermostUnstableState, performFullExit );
}
void exit_impl(
inner_context_ptr_type & pSelf,
typename state_base_type::node_state_base_ptr_type &
pOutermostUnstableState,
bool performFullExit )
{
switch ( this->ref_count() )
{
case 2:
if ( get_pointer( pOutermostUnstableState ) ==
static_cast< state_base_type * >( this ) )
{
pContext_->set_outermost_unstable_state(
pOutermostUnstableState );
// fall through to next case intended
}
else
{
break;
}
case 1:
{
if ( get_pointer( pOutermostUnstableState ) == 0 )
{
pContext_->set_outermost_unstable_state(
pOutermostUnstableState );
}
if ( performFullExit )
{
pSelf->exit();
check_store_shallow_history< stores_shallow_history >();
check_store_deep_history< stores_deep_history >();
}
context_ptr_type pContext = pContext_;
pSelf = 0;
pContext->exit_impl(
pContext, pOutermostUnstableState, performFullExit );
break;
}
default:
break;
}
}
void set_outermost_unstable_state(
typename state_base_type::node_state_base_ptr_type &
pOutermostUnstableState )
{
pOutermostUnstableState = this;
}
template< class OtherContext >
const typename OtherContext::inner_context_ptr_type & context_ptr() const
{
typedef typename mpl::if_<
is_same< OtherContext, context_type >,
context_ptr_impl_my_context,
context_ptr_impl_other_context
>::type impl;
return impl::template context_ptr_impl< OtherContext >( *this );
}
static void initial_deep_construct(
outermost_context_base_type & outermostContextBase )
{
deep_construct( &outermostContextBase, outermostContextBase );
}
static void deep_construct(
const context_ptr_type & pContext,
outermost_context_base_type & outermostContextBase )
{
const inner_context_ptr_type pInnerContext(
shallow_construct( pContext, outermostContextBase ) );
deep_construct_inner< inner_initial_list >(
pInnerContext, outermostContextBase );
}
static inner_context_ptr_type shallow_construct(
const context_ptr_type & pContext,
outermost_context_base_type & outermostContextBase )
{
const inner_context_ptr_type pInnerContext( new MostDerived );
pInnerContext->set_context( pContext );
outermostContextBase.add( pInnerContext );
return pInnerContext;
}
void set_context( const context_ptr_type & pContext )
{
BOOST_ASSERT( get_pointer( pContext ) != 0 );
pContext_ = pContext;
base_type::set_context(
orthogonal_position::value, get_pointer( pContext ) );
}
template< class InnerList >
static void deep_construct_inner(
const inner_context_ptr_type & pInnerContext,
outermost_context_base_type & outermostContextBase )
{
typedef typename mpl::if_<
mpl::empty< InnerList >,
deep_construct_inner_impl_empty,
deep_construct_inner_impl_non_empty
>::type impl;
impl::template deep_construct_inner_impl< InnerList >(
pInnerContext, outermostContextBase );
}
template< class LeafState >
void store_deep_history_impl()
{
detail::deep_history_storer<
context_type::inherited_deep_history::value,
context_type::deep_history::value
>::template store_deep_history< MostDerived, LeafState >(
*pContext_ );
}
private:
//////////////////////////////////////////////////////////////////////////
struct context_ptr_impl_other_context
{
template< class OtherContext, class State >
static const typename OtherContext::inner_context_ptr_type &
context_ptr_impl( const State & stt )
{
// This assert fails when an attempt is made to access an outer
// context from a constructor of a state that is *not* a subtype of
// state<>. To correct this, derive from state<> instead of
// simple_state<>.
BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
return stt.pContext_->template context_ptr< OtherContext >();
}
};
friend struct context_ptr_impl_other_context;
struct context_ptr_impl_my_context
{
template< class OtherContext, class State >
static const typename OtherContext::inner_context_ptr_type &
context_ptr_impl( const State & stt )
{
// This assert fails when an attempt is made to access an outer
// context from a constructor of a state that is *not* a subtype of
// state<>. To correct this, derive from state<> instead of
// simple_state<>.
BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
return stt.pContext_;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -