57 #ifdef CHSM_MULTITHREADED
65 #define CHSM_NS Concurrent_Hierarchical_State_Machine
77 #define CHSM_FORMAL(X) X
78 #define CHSM_ACTUAL(X)
80 #ifdef CHSM_MULTITHREADED
104 mutex_lock( pthread_mutex_t &m );
112 int prev_cancel_state_;
113 pthread_mutex_t &mutex_;
115 mutex_lock( mutex_lock& );
116 mutex_lock& operator=( mutex_lock
const& );
121 inline mutex_lock::mutex_lock( pthread_mutex_t &m ) : mutex_( m ) {
122 pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &prev_cancel_state_ );
123 pthread_mutex_lock( &mutex_ );
126 inline mutex_lock::~mutex_lock() {
127 pthread_mutex_unlock( &mutex_ );
128 pthread_setcancelstate( prev_cancel_state_, 0 );
129 pthread_testcancel();
152 # define CHSM_STATE_ARG_LIST(A) \
153 A(CHSM_NS::machine&) chsm_machine_, \
154 A(char const*) chsm_name_, \
155 A(CHSM_NS::parent*) chsm_parent_, \
156 A(CHSM_NS::state::action) chsm_enter_action_, \
157 A(CHSM_NS::state::action) chsm_exit_action_, \
158 A(CHSM_NS::event*) chsm_enter_event_, \
159 A(CHSM_NS::event*) chsm_exit_event_
166 # define CHSM_STATE_ARGS CHSM_STATE_ARG_LIST(CHSM_FORMAL)
174 # define CHSM_STATE_INIT CHSM_STATE_ARG_LIST(CHSM_ACTUAL)
188 typedef void (
machine::*action)(
state const &s,
event const &trigger );
217 bool active()
const {
return state_ & S_active; }
225 virtual void deep_clear();
232 char const*
name()
const {
return name_; }
272 virtual bool enter(
event const &trigger,
state *from_child = 0 );
296 virtual bool exit(
event const &trigger,
state *to = 0 );
299 char const *
const name_;
310 S_active_disabled = 0x02 | S_active
319 event *
const enter_event_, *
const exit_event_;
324 action
const enter_action_, exit_action_;
326 friend class cluster;
328 friend class machine;
359 typedef bool (
machine::*condition)(
event const &trigger );
367 typedef void (
machine::*action)(
event const &trigger );
411 bool is_internal()
const;
422 static bool is_legal(
state const *s1,
state const *s2 );
446 typedef int transition_id;
447 typedef transition_id
const *transition_list;
463 # define CHSM_EVENT_ARG_LIST(A) \
464 A(CHSM_NS::machine*) chsm_machine_, \
465 A(transition_list) chsm_transition_list_, \
466 A(char const*) chsm_name_, \
467 A(CHSM_NS::event*) chsm_base_event_
474 # define CHSM_EVENT_ARGS CHSM_EVENT_ARG_LIST(CHSM_FORMAL)
482 # define CHSM_EVENT_INIT CHSM_EVENT_ARG_LIST(CHSM_ACTUAL)
507 template<
typename EventClass>
bool is_type()
const {
508 return dynamic_cast<EventClass const*
>( this );
516 char const*
name()
const {
return name_; }
528 friend struct param_block;
543 param_block(
event const &e ) : chsm_event_( e ) { }
548 virtual ~param_block();
560 event const &chsm_event_;
568 machine& chsm()
const {
return chsm_event_.machine_; }
577 virtual bool precondition()
const;
597 unsigned in_progress_;
616 void broadcast(
void *param_block );
618 #ifdef CHSM_MULTITHREADED
626 class machine_lock :
public mutex_lock {
628 machine_lock( machine& );
638 transition_list
const transitions_;
640 char const *
const name_;
641 event *
const base_event_;
642 static int const no_transition_id_;
654 void lock_broadcast();
657 typedef transition value_type;
660 typedef value_type
const* const_pointer;
663 typedef value_type
const& const_reference;
665 class const_iterator;
666 friend class const_iterator;
672 class const_iterator {
683 transition_id id()
const {
return *t_id_; }
690 const_reference operator*()
const {
return t_[ *t_id_ ]; }
697 const_pointer operator->()
const {
return &operator*(); }
704 const_iterator& operator++() {
716 const_iterator operator++(
int) {
717 const_iterator
const temp = *
this;
729 friend bool operator==( const_iterator
const &i,
730 const_iterator
const &j ) {
731 return *i.t_id_ == *j.t_id_;
741 friend bool operator!=( const_iterator
const &i,
742 const_iterator
const &j ) {
748 transition_list t_id_;
749 event const *base_event_;
751 const_iterator( const_pointer, transition_list, event
const* );
764 const_iterator begin()
const;
771 const_iterator end()
const {
772 return const_iterator( 0, &no_transition_id_, 0 );
782 friend class machine;
783 friend bool state::enter( event
const&, state* );
784 friend bool state::exit ( event
const&, state* );
789 inline bool event::empty()
const {
790 return *transitions_ == no_transition_id_;
804 inline bool operator==( event
const &a, event
const &b ) {
819 inline bool operator!=( event
const &a, event
const &b ) {
850 # define CHSM_MACHINE_ARG_LIST(A) \
851 A(CHSM_NS::state*) chsm_state_ A([]), \
852 A(CHSM_NS::cluster&) chsm_root_, \
853 A(CHSM_NS::transition const) chsm_transition_ A([]), \
854 A(CHSM_NS::event const*) chsm_taken_ A([]), \
855 A(CHSM_NS::state*) chsm_target_ A([]), \
856 A(int) chsm_transitions_in_machine_
863 # define CHSM_MACHINE_ARGS CHSM_MACHINE_ARG_LIST(CHSM_FORMAL)
871 # define CHSM_MACHINE_INIT CHSM_MACHINE_ARG_LIST(CHSM_ACTUAL)
892 virtual bool enter( event
const &trigger = prime_ );
901 virtual bool exit( event
const &trigger = prime_ );
960 return *i.p_ == *j.p_;
1028 D_all = D_enex | D_event | D_alg
1036 unsigned debug()
const {
return debug_; }
1047 unsigned const temp = debug_;
1057 void dump_state()
const;
1084 typedef std::list<event*> event_queue;
1090 state *
const *
const state_;
1107 int const transitions_in_machine_;
1114 event const **
const taken_;
1120 state **
const target_;
1128 event_queue event_queue_;
1130 static void *
const nil_;
1131 static int const no_state_id_;
1133 #ifdef CHSM_MULTITHREADED
1134 mutable pthread_mutex_t machine_lock_;
1142 friend class event::machine_lock;
1163 typedef int const* child_list;
1166 # define CHSM_PARENT_ARG_LIST(A) \
1167 CHSM_STATE_ARG_LIST(A), \
1168 A(child_list) chsm_children_
1175 # define CHSM_PARENT_ARGS CHSM_PARENT_ARG_LIST(CHSM_FORMAL)
1183 # define CHSM_PARENT_INIT CHSM_PARENT_ARG_LIST(CHSM_ACTUAL)
1205 virtual void deep_clear();
1211 bool empty()
const {
return *children_ == no_child_id_; }
1226 friend class iterator;
1278 return *i.c_ == *j.c_;
1305 return iterator( machine_.state_, children_ );
1314 return iterator( 0, &no_child_id_ );
1317 class const_iterator;
1318 friend class const_iterator;
1371 return *i.c_ == *j.c_;
1431 virtual bool switch_child(
state *child );
1434 friend bool state::enter(
event const&,
state* );
1437 child_list
const children_;
1438 static int const no_child_id_;
1465 # define CHSM_CLUSTER_ARG_LIST(A) \
1466 CHSM_PARENT_ARG_LIST(A), \
1467 A(bool) chsm_history_
1474 # define CHSM_CLUSTER_ARGS CHSM_CLUSTER_ARG_LIST(CHSM_FORMAL)
1482 # define CHSM_CLUSTER_INIT CHSM_CLUSTER_ARG_LIST(CHSM_ACTUAL)
1495 void clear() { last_child_ = &front(); }
1501 virtual void deep_clear();
1513 virtual bool enter(
event const &trigger,
state *from_child = 0 );
1524 virtual bool exit(
event const &trigger,
state *to = 0 );
1529 bool const history_;
1530 state *active_child_, *last_child_;
1533 virtual bool switch_child(
state* );
1550 # define CHSM_SET_ARG_LIST(A) \
1551 CHSM_PARENT_ARG_LIST(A)
1558 # define CHSM_SET_ARGS CHSM_SET_ARG_LIST(CHSM_FORMAL)
1566 # define CHSM_SET_INIT CHSM_SET_ARG_LIST(CHSM_ACTUAL)
1584 virtual bool enter(
event const &trigger,
state *from_child = 0 );
1594 virtual bool exit(
event const &trigger,
state *to = 0 );
1599 inline event::const_iterator event::begin()
const {
1604 return const_iterator( machine_.transition_, transitions_, base_event_ );
1607 #ifdef CHSM_MULTITHREADED
1608 inline event::machine_lock::machine_lock( machine &m ) :
1609 mutex_lock( m.machine_lock_ )
1633 #ifndef CHSM_NO_ALIAS_NS
1638 # ifndef CHSM_NS_ALIAS
1639 # define CHSM_NS_ALIAS CHSM