Визуальное моделирование сложных реагирующих систем при помощи диаграмм состояния UML Harel - Как определять масштаб конечных автоматов
ОГЛАВЛЕНИЕ
Как определять масштаб конечных автоматов?
В сложных больших реагирующих системах объект конечного автомата может состоять более чем из 100 состояний, поэтому не очень разумно помещать все определения состояний в файл с исходным кодом программы.
Определения различных сложных состояний можно распределить по разным исходным файлам.
Например, сложное состояние Player можно определить в Player.c. Существует субсостояние под названием PowerUp, тоже являющееся сложным состоянием. Блок SME_BEGIN_SUB_STATE_DEF_P(PowerUp) объявляется в теле определения сложного состояния Player. Общие атрибуты и поведение сложного состояния PowerUp определены в блоке SME_BEGIN_SUB_STATE_DEF_P(PowerUp), например, переход из состояния PowerUp в PowerDown, независимо от того, какое состояние активно в текущий момент (PowerUp, Pause) или (PowerUp, Playing).
// Файл: Player.c
#define SME_CURR_DEFAULT_PARENT Player
SME_BEGIN_ROOT_COMP_STATE_DEF(Player, PlayerEntry, PlayerExit)
SME_ON_INIT_STATE(SME_NULL_ACTION, PowerDown)
SME_END_STATE_DEF
SME_BEGIN_LEAF_STATE_DEF_P(PowerDown, PowerDownEntry, PowerDownExit)
SME_ON_EVENT_WITH_GUARD(EXT_EVENT_ID_POWER, Guard1_func,
OnPowerDownEXT_EVENT_ID_POWER, Join1)
SME_END_STATE_DEF
SME_BEGIN_SUB_STATE_DEF_P(PowerUp)
SME_ON_EVENT(EXT_EVENT_ID_POWER,OnPowerUpEXT_EVENT_ID_POWER,PowerDown)
SME_END_STATE_DEF
SME_END_COMP_STATE_DEF(Player)
Подробно сложное состояние PowerUp с его потомками можно определить в Player2.c.
// Файл: Player2.c
#define SME_CURR_DEFAULT_PARENT PowerUp
SME_BEGIN_COMP_STATE_DEF(PowerUp, Player, PowerUpEntry, PowerUpExit)
SME_ON_INIT_STATE(OnPowerUpInitChild, Playing)
SME_ON_STATE_TIMEOUT_INTERNAL_TRAN(3000, PowerUpTimeOut)
SME_END_STATE_DEF
SME_BEGIN_LEAF_STATE_DEF_P(Playing, PlayingEntry, PlayingExit)
SME_ON_EVENT(EXT_EVENT_ID_PAUSE_RESUME,OnPlayingEXT_EVENT_ID_PAUSE_RESUME,Pause)
SME_END_STATE_DEF
SME_BEGIN_LEAF_STATE_DEF_P(Pause, PauseEntry, PauseExit)
SME_ON_EVENT(EXT_EVENT_ID_PAUSE_RESUME,OnPauseEXT_EVENT_ID_PAUSE_RESUME,Playing)
SME_END_STATE_DEF
SME_END_COMP_STATE_DEF(PowerUp)
Как активировать экземпляр конечного автомата?
Приложение конечного автомата – это экземпляр конечного автомата, или копия области, являющейся ортогональной частью сложного состояния или конечного автомата. Приложения могут иметь два режима работы: активный или неактивный. Активные приложения работают на конечном автомате в определённый момент, а неактивные приложения нет. Иными словами, только активные приложения могут обрабатывать события. Ядро конечного автомата отвечает за управление этими приложениями и передачу событий конкретным приложениям.
Следующий макрос определяет экземпляр приложения, Player1, основанный на конечном автомате Player. SmeActivateObj() активирует экземпляр Player1. Второй параметр – это родительское приложение для приложения, которое будет активировано, причем NULL обозначает отсутствие родительского приложения.
SME_OBJ_DEF(Player1, Player)
SmeActivateObj(&Player1,NULL);