Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/statechart/detail/node_state.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 5.1 KB
Line 
1#ifndef BOOST_STATECHART_DETAIL_NODE_STATE_HPP_INCLUDED
2#define BOOST_STATECHART_DETAIL_NODE_STATE_HPP_INCLUDED
3//////////////////////////////////////////////////////////////////////////////
4// Copyright 2002-2006 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
9
10
11#include <boost/statechart/detail/state_base.hpp>
12
13#include <boost/intrusive_ptr.hpp>
14#include <boost/assert.hpp>  // BOOST_ASSERT
15
16#include <algorithm> // std::find_if
17
18
19
20namespace boost
21{
22namespace statechart
23{
24namespace detail
25{
26
27
28
29template< class Allocator, class RttiPolicy >
30class node_state_base : public state_base< Allocator, RttiPolicy >
31{
32  typedef state_base< Allocator, RttiPolicy > base_type;
33  protected:
34    //////////////////////////////////////////////////////////////////////////
35    node_state_base( typename RttiPolicy::id_provider_type idProvider ) :
36      base_type( idProvider )
37    {
38    }
39
40    ~node_state_base() {}
41
42  public:
43    //////////////////////////////////////////////////////////////////////////
44    // The following declarations should be private.
45    // They are only public because many compilers lack template friends.
46    //////////////////////////////////////////////////////////////////////////
47    typedef base_type state_base_type;
48    typedef intrusive_ptr< node_state_base > direct_state_base_ptr_type;
49    virtual void exit_impl(
50      direct_state_base_ptr_type & pSelf,
51      typename base_type::node_state_base_ptr_type & pOutermostUnstableState,
52      bool performFullExit ) = 0;
53};
54
55//////////////////////////////////////////////////////////////////////////////
56template< class OrthogonalRegionCount, class Allocator, class RttiPolicy >
57class node_state : public node_state_base< Allocator, RttiPolicy >
58{
59  typedef node_state_base< Allocator, RttiPolicy > base_type;
60  protected:
61    //////////////////////////////////////////////////////////////////////////
62    node_state( typename RttiPolicy::id_provider_type idProvider ) :
63      base_type( idProvider )
64    {
65      for ( orthogonal_position_type pos = 0; 
66            pos < OrthogonalRegionCount::value; ++pos )
67      {
68        pInnerStates[ pos ] = 0;
69      }
70    }
71
72    ~node_state() {}
73
74  public:
75    //////////////////////////////////////////////////////////////////////////
76    // The following declarations should be private.
77    // They are only public because many compilers lack template friends.
78    //////////////////////////////////////////////////////////////////////////
79    typedef typename base_type::state_base_type state_base_type;
80
81    void add_inner_state( orthogonal_position_type position,
82                          state_base_type * pInnerState )
83    {
84      BOOST_ASSERT( ( position < OrthogonalRegionCount::value ) &&
85                    ( pInnerStates[ position ] == 0 ) );
86      pInnerStates[ position ] = pInnerState;
87    }
88
89    void remove_inner_state( orthogonal_position_type position )
90    {
91      BOOST_ASSERT( position < OrthogonalRegionCount::value );
92      pInnerStates[ position ] = 0;
93    }
94
95    virtual void remove_from_state_list(
96      typename state_base_type::state_list_type::iterator & statesEnd,
97      typename state_base_type::node_state_base_ptr_type &
98        pOutermostUnstableState,
99      bool performFullExit )
100    {
101      state_base_type ** const pPastEnd =
102        &pInnerStates[ OrthogonalRegionCount::value ];
103      // We must not iterate past the last inner state because *this* state
104      // will no longer exist when the last inner state has been removed
105      state_base_type ** const pFirstNonNull = std::find_if(
106        &pInnerStates[ 0 ], pPastEnd, &node_state::is_not_null );
107
108      if ( pFirstNonNull == pPastEnd )
109      {
110        // The state does not have inner states but is still alive, this must
111        // be the outermost unstable state then.
112        BOOST_ASSERT( get_pointer( pOutermostUnstableState ) == this );
113        typename state_base_type::node_state_base_ptr_type pSelf =
114          pOutermostUnstableState;
115        pSelf->exit_impl( pSelf, pOutermostUnstableState, performFullExit );
116      }
117      else
118      {
119        // Destroy inner states in the reverse order of construction
120        for ( state_base_type ** pState = pPastEnd; pState != pFirstNonNull; )
121        {
122          --pState;
123
124          // An inner orthogonal state might have been terminated long before,
125          // that's why we have to check for 0 pointers
126          if ( *pState != 0 )
127          {
128            ( *pState )->remove_from_state_list(
129              statesEnd, pOutermostUnstableState, performFullExit );
130          }
131        }
132      }
133    }
134
135    typedef typename base_type::direct_state_base_ptr_type
136      direct_state_base_ptr_type;
137
138  private:
139    //////////////////////////////////////////////////////////////////////////
140    static bool is_not_null( const state_base_type * pInner )
141    {
142      return pInner != 0;
143    }
144
145    state_base_type * pInnerStates[ OrthogonalRegionCount::value ];
146};
147
148
149
150} // namespace detail
151} // namespace statechart
152} // namespace boost
153
154
155
156#endif
Note: See TracBrowser for help on using the repository browser.