Список состояний конечного автомата

Подсмотрел у коллеги простой и довольно удобный способ держать список состояний/событий конечного автомата в одном месте. А то обычно они норовят расползтись по разным углам: enum, объявляющий соответствующие константы, массив имен состояний для отладки, большой switch, выбирающий что делать, в зависимости от состояния…

Делается примерно следующее (препроцессорная магия):

#define FOR_ALL_STATES(Action) \
    Action(StateInitial) \
    Action(StateInitializing) \
    Action(StateReady) \
    Action(StateTerminating)

После этого сами можно объявлять константы:

#define DEFINE_ENUM(Name) Name,

enum States {
    FOR_ALL_STATES(DEFINE_ENUM)
};

#undef DEFINE_ENUM

А можно – объявить прототипы функций-обработчиков для каждого из состояний:

#define DEFINE_HANDLER(Name) \
    States On ##Name(Events Event);

FOR_ALL_STATES(DEFINE_HANDLER)

#undef DEFINE_HANDLER

Или массив имен состояний, удобный для отладки:

#define DEFINE_NAME(Name) #Name,

static const char* StateNames[] = {
    FOR_ALL_STATES(DEFINE_NAME)
};

#undef DEFINE_NAME
comments powered by Disqus