Как стать автором
Обновить

Комментарии 14

Ваш инструмент подходит только для C#?
Этот инструмент вам не попадался?
github.com/unclebob/CC_SMC
Здравствуйте, спасибо за комментарий
1. Да, инструмент подходит только для C#
2. Такой инструмент (CC_SMC) не видел, сейчас вот быстренько ознакомился.

Тут немного разные подходы:
1. Судя по скриншотам схема конечного автомата рисуется на консоли. То есть мы получаем статическое изображение, которое не можем редактировать. При большом количестве состояний схема может стать совсем тяжело читаемой.
2. Реализованный мной подход более прост и понятен.

Но это лишь мое мнение:)

Возможно, как я и описывал в статье, кодо-генерация в моем подходе может быть использована для реализации более удобной работы с состояниями их схемы.
Да, ваш подход удобнее для описания автомата и работы с ним. Но, выходит, я не смогу, описав некую схему, генерировать автоматы на других языках — мне это было бы ценнее (и что есть в CC_SMC), т.к. мой основной язык не C# (web-стек), а идея применения FSM (для GUI например, говорят подходит) мне интересна.
(вот еще один попался, посвежее: github.com/SuperJMN/StateMachineCompiler )
Просто тогда, может такая возможность была бы интересна для вашего инструмента в плане на будущее? Или это архитектурно невозможно?

Графический редактор работает отдельно от библиотеки, взаимодействие между ними происходит через 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>

Также вы можете написать и обратное преобразование из ваше структуры — в xml. Тогда вы сможете экспортировать схему из вашей библиотеки в графический редактор.


Таким образом, написав не большое количество кода вы реализуете полноценную работу между редактором и вашей библиотекой. Работа с xml поддерживается на любом языке программирования.


Если ваш предыдущий вопрос был именно про это — прошу прощения, не правильно вас понял.

Извините, имея в голове другую картину не до конца рассмотрел ваше решение. Просто CC_SMC выдает автомат как непосредственно компилируемую языковую конструкцию и набор/иерархию классов (состояния, переходы), тогда, как ваше решение, как я теперь понимаю — мета-описание (xml) для библиотеки, которая сама отрабатывает автомат (и xml-ку еще читает). Т.е. разные принципы. И на другой язык нужно переносить не правила создания классов состояний и переходов, а библиотеку (с чтением xml, логированием, событиями). Ну да, тогда, реализовав преобразование схем, можно скрестить ежа с ужом. :)

Благодарю и поздравляю с дипломом. :)

Если кодо-генерация, действительно нужна — можно это сделать:)


Необходимые языки: С, С++, C#, Java, Python?)


Создайте issue и опишите свою идею в репозиторий редактора, чтобы другие могли поддержать идею

Если кодо-генерация, действительно нужна — можно это сделать:)

Ну не то, чтобы прям нужна, просто чуть более интересна) Проще и быстрее, кажется, научить редактор сохранять в формат CC_SMC/SMC и использовать их самих для генерации.


Необходимые языки: С, С++, C#, Java, Python?)

Если уж так ставить вопрос — то неопределенные, динамически добавляемые)


Создайте issue и опишите свою идею в репозиторий редактора, чтобы другие могли поддержать идею

Попробую.

Во-1, «стейт-машина» — это по определению не задача, а абстрактная модель. Про саму задачу вы ни слова не сказали.

Во-2, не знаю чему учили вас про конечный автомат, меня же — что его можно описать в виде графа переходов, из которого может быть получена таблица переходов. А именно — в виде размеченного ориентированного графа плюс начальное состояние. Для визуального проектирования графа и создания по нему списков смежности для любого ЯП существует огромное количество качественного и проверенного временем софта. Например, Graphviz. Вам бы стоило про это хотя бы в википедии почитать прежде чем демонстрировать наивный драндулет.

В-3, имхо в вузах лучше всё таки на теорграф делать упор. А все эти ваши авлония-уи изучать на реальных проектах, решая конкретную задачу бизнеса, а не на коне в вакууме

1. Так как конечный автомат — это "абстрактная модель", её реализация почти одинаковая для большинства задач. В данном случае, суть задачи можно опустить + основная идея задачи заключалась именно в реализации конечного автомата, с целью закрепления теории.


2. Перед реализации мной был проведен анализ и сравнение существующих решений.


Основные выявленные недостатки:


  1. Многие из них платные
  2. Отсутствие "верификации".
    Под верификацией я подразумеваю проверку на уникальность имен состояний и переходов. По определению конечного автомата, состояния — это множество, а не мультимножество. Данной проверки у многих редакторов нет.
  3. В ряде случаев таблица переходов понятнее, чем граф. Графических редакторов с возможностью посмотреть таблицу переходов — я не нашел.

Реализованное графическое представление отличается от стандартного представления в виде графа. Наименования переходов находятся внутри узла. Такой подход используется в gamedev, например, в Unity и Unreal engine, где конечные автоматы огромные. Это позволяет "разгрузить" схему и сделать её более читабельной.


Подход с Graphviz используется, например, в библиотеке stateless. И если я правильно понял — то Graphviz по описанному на языке DOT формату отображает статичную картинку.


В таком случае алгоритм работы будет такой:


  1. Меняем код
  2. Делаем экспорт в DOT и смотрим на картинке что получилось
  3. Меняем код
  4. Делаем экспорт в ...

Это не удобно. Мой подход позволяет отредактировать структуру графически.


Поэтому сейчас я предложил использовать в stateless свой редактор(issue).


3. Разве плохо в свободное время изучать новые технологии?


Как обсуждалось ранее, редактор может быть использован с другими библиотеками. Поэтому кроссплатформенность сделает его более универсальным.

Здравствуйте. Каким образом вы реализовали в графическом редакторе отрисовку кривых, представляющих связи (переходы) между узлами (состояниями), включая их динамическую перерисовку при перетаскивании узлов мышкой?

Добрый день, переходы представляются кривыми Безье 3-го порядка. Реализовываются с помощью BezierSegment — встроенного геометрического примитива.


Перерисовка реализована за счет отслеживания позиции узла.


Спасибо за вопрос, постараюсь раскрыть подробнее этот момент в следующей статье

Немного советов из собственного опыта:


  1. Переход (он же transition) это линия между состояниями, запускать переход лучше triggerом. У перехода может быть условие доступности (guard) который может запретить выполнять переход.
  2. OnEnter/OnExit не очень удобно использовать на практике, действие должно принадлежать переходу и запускаться на выполнение по triggerу если guard этого перехода разрешает.
  3. Благодаря паре trigger + guard можно делать всякие интересные вещи: один trigger может быть указан для нескольких переходов с условиями доступности и выполнять только первый доступный переход, можно готовить список доступных переходов например для отображения кнопок в UI, можно сделать несколько разных переходов из состояния 1 в состояние 2.
  4. Визуально удобно располагать статусы горизонтально от начального, размещая на этой линии основные переходы и статусы, выше/ниже этой линии располагать альтернативные пути переходов и чем дальше от основной, тем они менее вероятны. При этом выше основной линии — "хорошие" переходы, ниже — "плохие" или "нежелательные". Так же нужны обратные переходы. при таком подходе схема будет читаться намного легче.
  5. В XML с описанием конечного автомата лучше отделить описание структуры состояний/переходов от данных для отображения этой структуры — будет проще понимать что там происходит.

1. В данном случае имя перехода и является триггером. Логика определения "доступности" перехода описывается в OnEnter/OnExit, как раз там определяется следующий переход.
2. Возможно, вы правы и OnEnter/OnExit стоит объединить в одно событие.
3. Вы можете вынести некую проверку в отдельный метод и вызвать его в необходимых OnEnter/OnExit событиях, тем самым избежать дублирования кода.
4. Графический редактор позволяет описать лишь структуру и не содержит какую-либо логику самой работы автомата. Для схемы все переходы равновероятны, так как все зависит от логики, которая будет описана при использовании.


Графический редактор позволяет создавать обратные перехода:


Скриншот примера с обратным переходом

image


И циклы (переход из состояния в это же состояние):


Скриншот примера с циклом

image


Для циклов удалось придумать удобное решение (по моему мнению).
Обратные переходы не очень наглядны. Пока что не придумал как сделать это наиболее наглядным, сохранив название перехода внутри узла.


Если у вас есть идеи, как сделать схему в редакторе удобнее — пожалуйста, напишите здесь или создайте issue. Так же вы можете принять участие в проекте, за что я буду вам очень благодарен :)


5. Отличная идея, спасибо :)

3 В библиотеке есть возможность получить список переходов из состояния :


 Dictionary<string, Transition> transitionsFromThis= state.GetTransitionsFromThis();

И список переходов в состояние:


Dictionary<string, Transition> transitionsToThis = state.GetTransitionsToThis();

Документацию вы можете найти здесь

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации