有没有典型的状态机实现模式? [英] Is there a typical state machine implementation pattern?
问题描述
我们需要在 C 中实现一个简单的状态机.
标准的 switch 语句是最好的方法吗?
我们有一个当前状态(state)和一个转换触发器.
We need to implement a simple state machine in C.
Is a standard switch statement the best way to go?
We have a current state (state) and a trigger for the transition.
switch(state)
{
case STATE_1:
state = DoState1(transition);
break;
case STATE_2:
state = DoState2(transition);
break;
}
...
DoState2(int transition)
{
// Do State Work
...
if(transition == FROM_STATE_2) {
// New state when doing STATE 2 -> STATE 2
}
if(transition == FROM_STATE_1) {
// New State when moving STATE 1 -> STATE 2
}
return new_state;
}
是否有更好的方法用于简单状态机
对于 C++,我认为 Boost Statechart 库可能是要走的路.但是,它对 C 没有帮助没有.让我们专注于 C 用例.
For C++, I think the Boost Statechart library might be the way to go. However, it does not help with C. Lets concentrate on the C use case.
推荐答案
对于大多数状态机,我更喜欢使用表驱动的方法:
I prefer to use a table driven approach for most state machines:
typedef enum { STATE_INITIAL, STATE_FOO, STATE_BAR, NUM_STATES } state_t;
typedef struct instance_data instance_data_t;
typedef state_t state_func_t( instance_data_t *data );
state_t do_state_initial( instance_data_t *data );
state_t do_state_foo( instance_data_t *data );
state_t do_state_bar( instance_data_t *data );
state_func_t* const state_table[ NUM_STATES ] = {
do_state_initial, do_state_foo, do_state_bar
};
state_t run_state( state_t cur_state, instance_data_t *data ) {
return state_table[ cur_state ]( data );
};
int main( void ) {
state_t cur_state = STATE_INITIAL;
instance_data_t data;
while ( 1 ) {
cur_state = run_state( cur_state, &data );
// do other program logic, run other state machines, etc
}
}
这当然可以扩展到支持多个状态机等.也可以适应转换操作:
This can of course be extended to support multiple state machines, etc. Transition actions can be accommodated as well:
typedef void transition_func_t( instance_data_t *data );
void do_initial_to_foo( instance_data_t *data );
void do_foo_to_bar( instance_data_t *data );
void do_bar_to_initial( instance_data_t *data );
void do_bar_to_foo( instance_data_t *data );
void do_bar_to_bar( instance_data_t *data );
transition_func_t * const transition_table[ NUM_STATES ][ NUM_STATES ] = {
{ NULL, do_initial_to_foo, NULL },
{ NULL, NULL, do_foo_to_bar },
{ do_bar_to_initial, do_bar_to_foo, do_bar_to_bar }
};
state_t run_state( state_t cur_state, instance_data_t *data ) {
state_t new_state = state_table[ cur_state ]( data );
transition_func_t *transition =
transition_table[ cur_state ][ new_state ];
if ( transition ) {
transition( data );
}
return new_state;
};
表格驱动的方法更容易维护和扩展,更容易映射到状态图.
The table driven approach is easier to maintain and extend and simpler to map to state diagrams.
这篇关于有没有典型的状态机实现模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!