В этой главе описаны внутренние механизмы бэкэнда, которые могут быть полезны для экспертов UML, но могут быть безопасно проигнорированы для большинства пользователей. Для реализаторов также подробно описан интерфейс между передним и задним концами.
Backend: Run To Completion
Back-end реализует следующий алгоритм выполнения:
Проверьте, находится ли одна область конкретной машины состояния в состоянии завершения или прерывания. Если да, обработка событий отключена, пока условие длится (навсегда для прекращения псевдосостояния, в то время как активен для прерывания псевдосостояния).
Если включена функция очереди сообщений и если государственная машина уже обрабатывает событие, выталкивайте обработанное в настоящее время событие в очередь и завершайте обработку. В противном случае помните, что государственная машина сейчас обрабатывает событие и продолжает.
Если машина состояния обнаружила, что не используется отложенное событие, пропустите этот шаг. В противном случае отметьте первое отложенное событие из отложенной очереди как активное.
Теперь начните отправку ядра события. Если обработка исключений активирована, это произойдет внутри блока «попробовать/поймать», и интерфейс<exception_caught>называется, если происходит исключение.
Мероприятие теперь рассылается по очереди в каждый регион в порядке, определенном начальным государственным фронтенд-определением. Для каждого региона это будет называться соответствующим определением перехода на переднюю часть (ряд или ряд таблицы перехода).
Без переходного конфликта, если для данного региона возможен переход, состояние охраны проверяется. Если он возвращается<true>, обработка перехода продолжается, и называется действие выхода текущего состояния, за которым следует поведение действия перехода и поведение входа нового активного состояния.
При конфликтах переходов (несколько возможных переходов, размытых взаимоисключающими условиями охраны), условия охраны рассматриваются в обратном порядке их определения перехода в таблице переходов. Первый, возвращающийся<true>, выбирает свой переход. Обратите внимание, что это не определено стандартом UML, который просто указывает, что если условия охраны не являются взаимоисключающими, государственная машина плохо сформирована и поведение не определено. Опираясь на это поведение, характерное для конкретной реализации, разработчику будет сложнее поддерживать другую структуру государственной машины.
Если хотя бы один регион обрабатывает событие, это событие считается принятым. Если нет, то библиотека вызывает<no_transition>на государственную машину для каждого содержащегося в ней региона.
Если действующее в настоящее время состояние является субмашиной, то поведение несколько отличается. Стандарт UML указывает, что сначала необходимо опробовать внутренние переходы, поэтому событие сначала отправляется в подмашину. Только в том случае, если субмашина не принимает событие, испробованы другие (не внутренние) переходы.
Этот бэкэнд поддерживает внутренние переходы простых состояний и подмашин. Они представлены в виде<internal_transition_table>. Переходы, определенные в этой таблице, добавляются в конце таблицы перехода основной машины состояния, но с меньшим приоритетом, чем переходы подмашины (определяется в<transition_table>). Это означает, что для простых состояний эти переходы имеют более высокий приоритет, чем невнутренние переходы, соответствуют стандарту UML, который придает более высокий приоритет переходам более глубокого уровня. Для подмашин это нестандартное дополнение, которое может помочь ускорить обработку событий, давая возможность обойти обработку субрегионов. При стандартном УМЛ необходимо будет добавить субрегион только для обработки этих внутренних переходов, что будет медленнее.
После самой отправки отложенное событие, отмеченное на этапе 3 (если таковое имеется), теперь получает возможность обработки.
Затем события, стоящие в очереди сообщений, также получают шанс отправки
.
Наконец, завершение/анонимные переходы, если их найти в таблице переходов, также получают возможность отправки.
Этот алгоритм иллюстрирует, как бэкэнд настраивает себя в максимально возможное время компиляции. Каждая функция, не найденная в данном определении машины состояния, деактивирована и, следовательно, не имеет себестоимости. Завершение событий, отсроченные события, прекращение состояний, отправка в несколько регионов, внутренние переходы все деактивированы, если не используются. Конфигурация пользователя необходима только для обработки исключений и очереди сообщений.
Статья Chapter 6. Internals раздела Meta State Machine (MSM) Part I. User' guide может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.