Я немного не понимаю, как реализовать мои конечный автомат.
Я уже знаю, что он иерархический, поскольку некоторые состояния используют одно и то же действие.
Я определяю, что мне нужно делать, с помощью следующих параметров:
My иерархия определяется классом, а код операции представляет действие.
Производный может использовать OpCodes из Base и Specific ] может использовать OpCodes обоих Base ] и Получено .
Наивная реализация заключается в следующем:
void (*const state_table [MAX_CLASSES][MAX_OPCODES]) (state *) {
{base_state1, base_state2, NULL, NULL},
{base_state1, base_state2, derived_state1, NULL},
{base_state1,base_state2, derived_state1, specific_state3},
};
void dispatch(state *s)
{
if (state_table[s->Class][s->OpCode] != NULL)
state_table[s->Class][s->OpCode](s);
}
Это очень быстро станет недоступным для обслуживания.
Есть ли другой способ сопоставить состояние с суперклассом?
РЕДАКТИРОВАТЬ:
Дальнейшие вычисления наводят меня на мысль, что я, вероятно, буду использовать большинство, если не все OpCodes , но я не буду использовать все доступные мне классы .
Другое пояснение:
Некоторые операционные коды могут совместно использоваться несколькими производными и базовыми классами .
Например:
У меня есть еще один класс под названием MyGroup , который является производным классом. Он имеет OpCodes : STATE_FLIP , STATE_FLOP .
Третий класс - это специальный класс с именем ThingInMyGroup , который имеет код операции : STATE_FLIP_FLOP_AND_FLOOP .
Таким образом, сообщение с классом Any отправляется с сервера, принимается всеми клиентами и обрабатывается.
Сообщение с классом MyGroup отправляется с сервера, принимается всеми клиентами и обрабатывается только на клиентах, принадлежащих к MyGroup , любым OpCodes , которые являются допустимы для Любые классы допустимы для класса MyGroup .
Сообщение с классом ThingInMyGroup отправляется с сервера, принимается всеми клиентами и обрабатывается только на клиентах, которые принадлежат к MyGroup и являются ThingInMyGroup *, любой * * Коды операций , действительные для класса Any и класса MyGroup , действительны для класса ThingInMyGroup .
После того, как сообщение получено, клиент соответственно ACK / NACK.
Я предпочитаю не использовать варианты переключения или константные массивы, так как они станут недоступны для обслуживания, когда станут больше.
Мне нужен гибкий дизайн, который позволяет мне: