192 lines
5.6 KiB
C++
192 lines
5.6 KiB
C++
#ifndef BOOST_STATECHART_DETAIL_STATE_BASE_HPP_INCLUDED
|
|
#define BOOST_STATECHART_DETAIL_STATE_BASE_HPP_INCLUDED
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Copyright 2002-2008 Andreas Huber Doenni
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompany-
|
|
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include <boost/statechart/result.hpp>
|
|
#include <boost/statechart/event.hpp>
|
|
|
|
#include <boost/statechart/detail/counted_base.hpp>
|
|
|
|
#include <boost/intrusive_ptr.hpp>
|
|
#include <boost/noncopyable.hpp>
|
|
#include <boost/assert.hpp>
|
|
#include <boost/config.hpp> // BOOST_MSVC
|
|
|
|
#include <boost/detail/workaround.hpp>
|
|
#include <boost/detail/allocator_utilities.hpp>
|
|
|
|
#ifdef BOOST_MSVC
|
|
# pragma warning( push )
|
|
# pragma warning( disable: 4702 ) // unreachable code (in release mode only)
|
|
#endif
|
|
|
|
#include <list>
|
|
|
|
#ifdef BOOST_MSVC
|
|
# pragma warning( pop )
|
|
#endif
|
|
|
|
|
|
|
|
namespace boost
|
|
{
|
|
namespace statechart
|
|
{
|
|
namespace detail
|
|
{
|
|
|
|
|
|
|
|
template< class Allocator, class RttiPolicy >
|
|
class leaf_state;
|
|
template< class Allocator, class RttiPolicy >
|
|
class node_state_base;
|
|
|
|
typedef unsigned char orthogonal_position_type;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
template< class Allocator, class RttiPolicy >
|
|
class state_base :
|
|
#ifndef NDEBUG
|
|
noncopyable,
|
|
#endif
|
|
public RttiPolicy::template rtti_base_type<
|
|
// Derived class objects will be created, handled and destroyed by exactly
|
|
// one thread --> locking is not necessary
|
|
counted_base< false > >
|
|
{
|
|
typedef typename RttiPolicy::template rtti_base_type<
|
|
counted_base< false > > base_type;
|
|
|
|
public:
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void exit() {}
|
|
|
|
virtual const state_base * outer_state_ptr() const = 0;
|
|
|
|
protected:
|
|
//////////////////////////////////////////////////////////////////////////
|
|
state_base( typename RttiPolicy::id_provider_type idProvider ) :
|
|
base_type( idProvider ),
|
|
deferredEvents_( false )
|
|
{
|
|
}
|
|
|
|
#if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT( 4 ) )
|
|
// We make the destructor virtual for GCC because with this compiler there
|
|
// is currently no way to disable the "has virtual functions but
|
|
// non-virtual destructor" warning on a class by class basis. Although it
|
|
// can be done on the compiler command line with -Wno-non-virtual-dtor,
|
|
// this is undesirable as this would also suppress legitimate warnings for
|
|
// types that are not states.
|
|
virtual ~state_base() {}
|
|
#else
|
|
// This destructor is not virtual for performance reasons. The library
|
|
// ensures that a state object is never deleted through a state_base
|
|
// pointer but only through a pointer to the most-derived type.
|
|
~state_base() {}
|
|
#endif
|
|
|
|
protected:
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// The following declarations should be private.
|
|
// They are only protected because many compilers lack template friends.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void defer_event()
|
|
{
|
|
deferredEvents_ = true;
|
|
}
|
|
|
|
bool deferred_events() const
|
|
{
|
|
return deferredEvents_;
|
|
}
|
|
|
|
template< class Context >
|
|
void set_context( orthogonal_position_type position, Context * pContext )
|
|
{
|
|
pContext->add_inner_state( position, this );
|
|
}
|
|
|
|
public:
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// The following declarations should be private.
|
|
// They are only public because many compilers lack template friends.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
virtual detail::reaction_result react_impl(
|
|
const event_base & evt,
|
|
typename RttiPolicy::id_type eventType ) = 0;
|
|
|
|
typedef intrusive_ptr< node_state_base< Allocator, RttiPolicy > >
|
|
node_state_base_ptr_type;
|
|
typedef intrusive_ptr< leaf_state< Allocator, RttiPolicy > >
|
|
leaf_state_ptr_type;
|
|
typedef std::list<
|
|
leaf_state_ptr_type,
|
|
typename boost::detail::allocator::rebind_to<
|
|
Allocator, leaf_state_ptr_type >::type
|
|
> state_list_type;
|
|
|
|
virtual void remove_from_state_list(
|
|
typename state_list_type::iterator & statesEnd,
|
|
node_state_base_ptr_type & pOutermostUnstableState,
|
|
bool performFullExit ) = 0;
|
|
|
|
private:
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool deferredEvents_;
|
|
};
|
|
|
|
|
|
|
|
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
|
} // namespace detail
|
|
} // namespace statechart
|
|
#endif
|
|
|
|
|
|
|
|
template< class Allocator, class RttiPolicy >
|
|
inline void intrusive_ptr_add_ref(
|
|
const ::boost::statechart::detail::state_base< Allocator, RttiPolicy > * pBase )
|
|
{
|
|
pBase->add_ref();
|
|
}
|
|
|
|
template< class Allocator, class RttiPolicy >
|
|
inline void intrusive_ptr_release(
|
|
const ::boost::statechart::detail::state_base< Allocator, RttiPolicy > * pBase )
|
|
{
|
|
if ( pBase->release() )
|
|
{
|
|
// The state_base destructor is *not* virtual for performance reasons
|
|
// but intrusive_ptr< state_base > objects are nevertheless used to point
|
|
// to states. This assert ensures that such a pointer is never the last
|
|
// one referencing a state object.
|
|
BOOST_ASSERT( false );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
|
} // namespace detail
|
|
} // namespace statechart
|
|
#endif
|
|
|
|
|
|
|
|
} // namespace boost
|
|
|
|
|
|
|
|
#endif
|