У меня есть конечный автомат в системе реального времени с очень немногими (3) состояниями.
typedef enum {
STATE1,
STATE2,
STATE3
} state_t;
Однако переходы между этими состояниями требуют значительного времени и имеют свои подразделения. Итак, у меня есть два варианта: либо я расширяю главный конечный автомат так, чтобы были представлены все промежуточные состояния:
typedef enum {
STATE1,
STATE1_PREPARE_TRANSITION_TO_STATE2,
STATE1_DO_TRANSITION_TO_STATE2,
STATE1_PREPARE_TRANSITION_TO_STATE3,
STATE1_DO_TRANSITION_TO_STATE3,
STATE2,
...
} state_t;
или я создаю вложенный конечный автомат для соответствующих основных состояний:
typedef enum {
STATE1_NOT_ACTIVE,
STATE1_NORMAL,
STATE1_PREPARE_TRANSITION_TO_STATE2,
STATE1_DO_TRANSITION_TO_STATE2,
STATE1_PREPARE_TRANSITION_TO_STATE3,
STATE1_DO_TRANSITION_TO_STATE3
} sub_state1_t;
...
Обе возможности имеют свои преимущества и недостатки. Большая машина состояний очень легко запутывается и усложняется. Однако согласование всех состояний во втором случае также не является тривиальным, и многим функциям потребуется информация как о глобальном состоянии, так и о подсостояниях.
Я хотел бы избежать сложного кода, который должен обрабатывать несколько параллельных состояний, например:
if ((global_state == STATE1) &&
(sub_state_1 == STATE1_DO_TRANSITION_TO_STATE2))
{
...
if (transition_xy_done(...))
{
global_state = STATE2;
sub_state_1 = STATE1_NOT_ACTIVE;
sub_state_2 = STATE2_NORMAL;
}
}
Каков общий наилучший подход к такой проблеме: много маленьких и вложенных конечных автоматов (со многими недопустимыми комбинациями), один большой конечный автомат или что-то еще?