📄 state_machine.hpp
字号:
}
typedef detail::state_base< allocator_type, rtti_policy_type >
state_base_type;
class state_iterator : public std::iterator<
std::forward_iterator_tag,
state_base_type, std::ptrdiff_t
#ifndef BOOST_MSVC_STD_ITERATOR
, const state_base_type *, const state_base_type &
#endif
>
{
public:
//////////////////////////////////////////////////////////////////////
explicit state_iterator(
typename state_base_type::state_list_type::const_iterator
baseIterator
) : baseIterator_( baseIterator ) {}
const state_base_type & operator*() const { return **baseIterator_; }
const state_base_type * operator->() const
{
return &**baseIterator_;
}
state_iterator & operator++() { ++baseIterator_; return *this; }
state_iterator operator++( int )
{
return state_iterator( baseIterator_++ );
}
bool operator==( const state_iterator & right ) const
{
return baseIterator_ == right.baseIterator_;
}
bool operator!=( const state_iterator & right ) const
{
return !( *this == right );
}
private:
typename state_base_type::state_list_type::const_iterator
baseIterator_;
};
state_iterator state_begin() const
{
return state_iterator( currentStates_.begin() );
}
state_iterator state_end() const
{
return state_iterator( currentStatesEnd_ );
}
void unconsumed_event( const event_base & ) {}
protected:
//////////////////////////////////////////////////////////////////////////
state_machine() :
currentStatesEnd_( currentStates_.end() ),
pOutermostState_( 0 ),
isInnermostCommonOuter_( false ),
performFullExit_( true )
{
}
// This destructor was only made virtual so that that
// polymorphic_downcast can be used to cast to MostDerived.
virtual ~state_machine()
{
terminate_impl( false );
}
public:
//////////////////////////////////////////////////////////////////////////
// The following declarations should be protected.
// They are only public because many compilers lack template friends.
//////////////////////////////////////////////////////////////////////////
void post_event( const event_base_ptr_type & pEvent )
{
BOOST_ASSERT( get_pointer( pEvent ) != 0 );
eventQueue_.push_back( pEvent );
}
void post_event( const event_base & evt )
{
post_event( evt.intrusive_from_this() );
}
public:
//////////////////////////////////////////////////////////////////////////
// The following declarations should be private.
// They are only public because many compilers lack template friends.
//////////////////////////////////////////////////////////////////////////
typedef MostDerived inner_context_type;
typedef mpl::integral_c< detail::orthogonal_position_type, 0 >
inner_orthogonal_position;
typedef mpl::integral_c< detail::orthogonal_position_type, 1 >
no_of_orthogonal_regions;
typedef MostDerived outermost_context_type;
typedef state_machine outermost_context_base_type;
typedef state_machine * inner_context_ptr_type;
typedef typename state_base_type::node_state_base_ptr_type
node_state_base_ptr_type;
typedef typename state_base_type::leaf_state_ptr_type leaf_state_ptr_type;
typedef typename state_base_type::state_list_type state_list_type;
typedef mpl::clear< mpl::list<> >::type context_type_list;
typedef mpl::bool_< false > shallow_history;
typedef mpl::bool_< false > deep_history;
typedef mpl::bool_< false > inherited_deep_history;
detail::reaction_result react_impl(
const event_base_type &,
typename rtti_policy_type::id_type )
{
return detail::do_forward_event;
}
void exit_impl(
inner_context_ptr_type &,
typename state_base_type::node_state_base_ptr_type &,
bool ) {}
void set_outermost_unstable_state(
typename state_base_type::node_state_base_ptr_type &
pOutermostUnstableState )
{
pOutermostUnstableState = 0;
}
// Returns a reference to the context identified by the template
// parameter. This can either be _this_ object or one of its direct or
// indirect contexts.
template< class Context >
Context & context()
{
// As we are in the outermost context here, only this object can be
// returned.
return *polymorphic_downcast< MostDerived * >( this );
}
template< class Context >
const Context & context() const
{
// As we are in the outermost context here, only this object can be
// returned.
return *polymorphic_downcast< const MostDerived * >( this );
}
outermost_context_type & outermost_context()
{
return *polymorphic_downcast< MostDerived * >( this );
}
const outermost_context_type & outermost_context() const
{
return *polymorphic_downcast< const MostDerived * >( this );
}
outermost_context_base_type & outermost_context_base()
{
return *this;
}
const outermost_context_base_type & outermost_context_base() const
{
return *this;
}
void terminate_as_reaction( state_base_type & theState )
{
terminate_impl( theState, performFullExit_ );
pOutermostUnstableState_ = 0;
}
void terminate_as_part_of_transit( state_base_type & theState )
{
terminate_impl( theState, performFullExit_ );
isInnermostCommonOuter_ = true;
}
void terminate_as_part_of_transit( state_machine & )
{
terminate_impl( *pOutermostState_, performFullExit_ );
isInnermostCommonOuter_ = true;
}
template< class State >
void add( const intrusive_ptr< State > & pState )
{
// The second dummy argument is necessary because the call to the
// overloaded function add_impl would otherwise be ambiguous.
node_state_base_ptr_type pNewOutermostUnstableStateCandidate =
add_impl( pState, *pState );
if ( isInnermostCommonOuter_ ||
is_in_highest_orthogonal_region< State >() &&
( get_pointer( pOutermostUnstableState_ ) ==
pState->State::outer_state_ptr() ) )
{
isInnermostCommonOuter_ = false;
pOutermostUnstableState_ = pNewOutermostUnstableStateCandidate;
}
}
void add_inner_state(
detail::orthogonal_position_type position,
state_base_type * pOutermostState )
{
BOOST_ASSERT( position == 0 );
detail::avoid_unused_warning( position );
pOutermostState_ = pOutermostState;
}
void remove_inner_state( detail::orthogonal_position_type position )
{
BOOST_ASSERT( position == 0 );
detail::avoid_unused_warning( position );
pOutermostState_ = 0;
}
void defer_event(
const event_base_type & evt,
const state_base_type * pForState )
{
deferredMap_[ pForState ].push_back( evt.intrusive_from_this() );
}
void release_events( const state_base_type * pForState )
{
const typename deferred_map_type::iterator pFound =
deferredMap_.find( pForState );
// We are not guaranteed to find an entry because a state is marked for
// having deferred events _before_ the event is actually deferred. An
// exception might be thrown during deferral.
if ( pFound != deferredMap_.end() )
{
eventQueue_.splice( eventQueue_.end(), pFound->second );
deferredMap_.erase( pFound );
}
}
template< class HistorizedState >
void store_shallow_history()
{
// 5.2.10.6 declares that reinterpret_casting a function pointer to a
// different function pointer and back must yield the same value. The
// following reinterpret_cast is the first half of such a sequence.
store_history_impl(
shallowHistoryMap_,
history_key_type::make_history_key< HistorizedState >(),
reinterpret_cast< void (*)() >( &HistorizedState::deep_construct ) );
}
template<
class HistoryContext,
detail::orthogonal_position_type orthogonalPosition >
void clear_shallow_history()
{
// If you receive a
// "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
// similar compiler error here then you tried to clear shallow history
// for a state that does not have shallow history. That is, the state
// does not pass either statechart::has_shallow_history or
// statechart::has_full_history to its base class template.
BOOST_STATIC_ASSERT( HistoryContext::shallow_history::value );
typedef typename mpl::at_c<
typename HistoryContext::inner_initial_list,
orthogonalPosition >::type historized_state;
store_history_impl(
shallowHistoryMap_,
history_key_type::make_history_key< historized_state >(),
0 );
}
template< class DefaultState >
void construct_with_shallow_history(
const typename DefaultState::context_ptr_type & pContext )
{
construct_with_history_impl< DefaultState >(
shallowHistoryMap_, pContext );
}
template< class HistorizedState, class LeafState >
void store_deep_history()
{
typedef typename detail::make_context_list<
typename HistorizedState::context_type,
LeafState >::type history_context_list;
typedef detail::constructor<
history_context_list, outermost_context_base_type > constructor_type;
// 5.2.10.6 declares that reinterpret_casting a function pointer to a
// different function pointer and back must yield the same value. The
// following reinterpret_cast is the first half of such a sequence.
store_history_impl(
deepHistoryMap_,
history_key_type::make_history_key< HistorizedState >(),
reinterpret_cast< void (*)() >( &constructor_type::construct ) );
}
template<
class HistoryContext,
detail::orthogonal_position_type orthogonalPosition >
void clear_deep_history()
{
// If you receive a
// "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
// similar compiler error here then you tried to clear deep history for
// a state that does not have deep history. That is, the state does not
// pass either statechart::has_deep_history or
// statechart::has_full_history to its base class template
BOOST_STATIC_ASSERT( HistoryContext::deep_history::value );
typedef typename mpl::at_c<
typename HistoryContext::inner_initial_list,
orthogonalPosition >::type historized_state;
store_history_impl(
deepHistoryMap_,
history_key_type::make_history_key< historized_state >(),
0 );
}
template< class DefaultState >
void construct_with_deep_history(
const typename DefaultState::context_ptr_type & pContext )
{
construct_with_history_impl< DefaultState >(
deepHistoryMap_, pContext );
}
private: // implementation
//////////////////////////////////////////////////////////////////////////
void initial_construct()
{
InitialState::initial_deep_construct(
*polymorphic_downcast< MostDerived * >( this ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -