Привет, Хабр!
Давайте сразу к делу, но небольшая предыстория все же необходима: полтора года назад возникла необходимость реализовать простой автомат (конечный автомат), освоив теорию еще в университете, я был уверен в тривиальности этой задачи (мы все оптимисты).
Время, проведенное с Google, прошло безрезультатно, поскольку существующие решения не только имели Роковая ошибка , но и ряд других серьезных недостатков, таких как сложная структура и отсутствие документации.
Вскоре я наткнулся Эта статья , что подтвердило отсутствие удобных решений.
Что ты сделал потом?
Поскольку задачу нужно было решить быстро (ну как обычно), мой конечный автомат был реализован с помощью словарей, то есть:- есть список состояний (Enum)
- список сигналов (замена классическому входному алфавиту)
- словарь (карта): состояние-сигнал-состояние
Но что дальше?
Это был третий год обучения в университете по специальности «Инженер-программист» и пришло время определиться с темой диплома.Посоветовавшись с предложенным руководителем, возникла идея, что хорошо бы не просто написать библиотеку для реализации конечных автоматов, но и как-то их визуально представить.
Решение: библиотека и графический редактор.
Подробнее о реализации каждого из них я расскажу в следующих статьях, а пока покажу, что получилось.
Спустя год разработки.
Графический редактор
Реализовано в wpf с использованием Реактивный пользовательский интерфейс .Здесь мы имеем структуру конечного автомата в виде графа и в виде таблицы переходов.
Накидываем ноды, соединяем их и сохраняем в xml файл.
В целом я постарался сделать удобно и стильно, и как бонус поддерживается куча горячих клавиш.
В конце прикреплю ссылку на репозиторий с документацией в виде гифки.
Для тех кому неохота переходить по ссылке (лень зайти в репозиторий)
Возможности
Две темы
Два представления конечного автомата:
- как график
- в виде таблицы переходов
Проверка
- уникальные имена для состояний и переходов
- отсутствие достижимых состояний (состояний без переходов)
Добавление узлов и соединений
Отменить действия
Свертывание и перемещение узлов
Масштабирование
Выбор элементов
Имена состояний и переходов
Перемещение переходов
Удаление переходов
Импорт/Ээкспорт из/в xml
<Эxml version="1.0" encoding="utf-8"?> <StateMachine> <States> <State Name="Start" Position="37, 80" IsCollapse="False" /> <State Name="State 1" Position="471, 195.54" IsCollapse="False" /> <State Name="State 2" Position="276, 83.03999999999999" IsCollapse="False" /> </States> <StartState Name="Start" /> <Transitions> <Transition Name="Transition 2" From="State 2" To="State 1" /> <Transition Name="Transition 1" From="Start" To="State 2" /> </Transitions> </StateMachine>
Сохранение диаграммы в формате PNG/JPEG.
Библиотека Мы реализуем конечный автомат в три этапа:
- Мы создаем конечный автомат и инициализируем его структуру файлом, сохраненным из редактора.
StateMachine stateMachine = new StateMachine("scheme.xml");
- Основную логику мы описываем в методах, которые потом «навешиваем» на события, которых достаточно.
stateMachine.GetState("State1").
OnExit(Action1); stateMachine.GetState("State2").
OnEntry(Action2); stateMachine.GetTransition("Transition1").
OnInvoke(Action3); stateMachine.OnChangeState(Action4);
- Запустим.
stateMachine.Start(parameters);
А как насчет переходов? Для перехода внутри функции, обрабатывающей вход/выход в состоянии, мы вызываем:
StateMachine.InvokeTransition("Transition1", parameters);
Переход произойдет не сразу, просто указанный переход будет помечен как следующий, то есть сначала будут обработаны все события состояния, а затем будет вызван переход. Что еще там?
- Параметры переходов и состояний.
- Данные — это словарь данных, который хранится внутри StateMachine и используется для обмена данными между состояниями.
Для тех кому неохота переходить по ссылке (лень зайти в репозиторий)
Возможности:
- Начальное состояние
- Государственные события входа и выхода
- Выполнить событие для перехода
- Варианты перехода
- Параметры для ввода/вывода состояния
- Событие изменения состояния
- Данные для обмена между государствами
- Событие изменения данных
- Импорт/Ээкспорт из/в xml
- Ведение журнала
Поэтому буду рад помочь с реализацией описанных ниже пунктов.
Так же если найдете ошибки или есть другие идеи - пишите, буду очень рад!
Библиотека.
Возможные улучшения:
- Асинхронность
- Таймеры
- Вложенные конечные автоматы
- Магия работы с элементами диаграммы
Теперь пользователю необходимо запомнить, под какими именами описаны переходы и состояния внутри файла.
И работа с ними выглядит следующим образом: stateMachine.GetState("State1");
Я бы хотел, чтобы это было так stateMachine.State1;
Скажу сразу, что динамический не подойдет, потому что вам еще нужно запомнить название.
Вероятно, это требует какой-то генерации кода, но я пока не нашел решения.
Графический редактор.
Возможные улучшения:
- Локализация
- Шейдеры для рисования элементов схемы.
- Вложенные конечные автоматы
- Автоматическое распределение узлов — волшебная кнопка для авторазметки элементов на холсте
- Кросс-платформенный — Перевод проекта на АвалонияUI
- Мы создаем конечную машину в три шага и в любой момент можем визуально отобразить и отредактировать структуру машины.
- Дальнейшее развитие проекта
NET #конечный автомат #Конечный автомат #SimpleStateMachine
-
Кататония
19 Oct, 24 -
Как Выбрать Подходящий Курс Обучения?
19 Oct, 24 -
Таинственные Устройства – 4
19 Oct, 24 -
Sony: 3D-Телевизоры В Каждый Дом!
19 Oct, 24 -
Вышел Друпал 6.0
19 Oct, 24 -
Arsights - Дополненная Реальность
19 Oct, 24 -
Дайджест Мблт Дев :: Выпуск №200
19 Oct, 24