Кто-нибудь имеел удовольствие делать такую штуку? Мне нужно для GUI, хочу услышать good & bad design decisions от уже наступавших на грабли.
Если кому интересно, расскажу подробнее. Может, сам лучше разберусь.
Кто-нибудь имеел удовольствие делать такую штуку? Мне нужно для GUI, хочу услышать good & bad design decisions от уже наступавших на грабли.
Если кому интересно, расскажу подробнее. Может, сам лучше разберусь.
Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.
15 августа 2007 в 22:03
У меня все состояния от класса State, подклассов нет. Функции входа и выхода я задаю анонимными функциями.
Про файловую систему ничего посоветовать не могу.
15 августа 2007 в 21:04
Что упростить? Механизм. Ты видимо каждое состояние создаёшь как отдельный класс, но в большинстве случаев, думаю можно обойтись одним классом "состояние", для которого написан соответствующий интерфейс (имя, добавление/удаление специфических свойств, добавление/удаление определённых методов/событий, возможно чтото ещё). У меня как раз сейчас основной проект посвящён графам… Кстати, где почитать про то, как грамотно спроектировать файловую систему (на физическом уровне, какие должны быть структуры)? Желательно чтобы кратко и по существу. Больше всего интересует вопрос, как свести фрагментацию к минимуму.
13 августа 2007 в 2:00
Еще новости с фронта: указывать родительское состояние в таблице переходов наравне с его детьми не стоит. Если окажется, что некоторое событие обрабатывается родителем и ребенком, то в состоянии-ребенке, оно приведет к непредсказуемому двойному переходу (даже если указано одно и то же новое состояние, вход в него будет осуществлен два раза).
Мне понадобилось сделать так только один раз: для состояния "объект подсвечен". Для состояния deselected я сделал ребенка hilited и при входе/выходе из хайлайтед довольно хитрую анимацию с задержкой и колбеком после анимации. Получил кучу глюков и, в итоге, сделал очевидное разделение: у deselected двое детей: shadowed, hilited. И вместо deselected в таблице переходов прописал shadowed. Общие ресурс (обработка onClick) для этих состояний остался в deselected.
12 августа 2007 в 20:04
Еще новости с фронта. Есть такие состояния, которые условно назовем параметрическими. Есть набор превьюх, между которыми можно выбирать, что играть. У плейлиста есть состояния "играет", "не играет" и их родительское состояние – "выбрано" (где ставится прослушивание событий выбранного объекта). Одна из превьюх всегда выбрана.
Суть в том, что когда выбирается другая превьюха и нужно перейти, скажем, в состояние "не играет", нужно выйти из родительского "выбрано" и войтив него снова, дойдя до "не играет". Хотя базовый механизм использует наикратчайший путь: от "играет" до "не играет" без выхода из "выбрано".
Решить проблему можно двумя способами (правильным и неправильным
1) Ввести механизм параметрических состояний. В матрице переходов нужно указать параметры для состояний (причем lazy eval, в не какие-то фиксированные) и составить логику выхода из родителей, пока параметр не тот, который нужен. Это не так-то просто.
2) Ввести редирект. Создать дополнительное состояние на нужном уровне вложенности, которое в момент входа делает переход в другое состояние.Так можно будет перейти из А в Б более длинным путем, с выходом из их родителя.
Синтаксис в этом случае вообще рулит (AS3): в матрице нужно указать прокси-состояние, но его не нужно заранее содавать. Нужно его создать при необходимости:
base.to(child)
в строке матрицы (см. ссылки выше для пояснения):
[playlist, Playlist.SELECT_ITEM,null,stopped,loaded.to(stopped),loaded.to(playing) ]
Ну, и чудо-сорцы (class State):
public function to(dest:State)
{
return new State(this, { enter:function(…args){ dest.enter.apply(dest, args) } });
}
12 августа 2007 в 0:01
Да, верно. "Освобождение ресурсов происходит до первого общего родителя". Это нужно для расшаривания ресурсов между состояниями.
На графе в силу моей лени состояния-родители не показаны. Их можно изобразить, объединив светлой линией дочерние состояния. В представленном графе перехода к родителю нет, зато есть в новой версии – под deselected добавлено состояние highlighted. Соответственно, переход в него происходит по mouse_over с включением подсветки. Ну и выход соответствующий.
Исходное – deselected (а какое это имеет значение?)
"Видеосервер" – класс, реализующий доступ к скачиванию видеофайла с сервера. V.stop – это событие, выкидываемое "видеосервером" когда стриминг прекратился. V.full – сообщение о заполнении буфера на 100%. И т.д.
12 августа 2007 в 0:01
Проблема, собственно, в том, как этот КА описать (что уже придумано совместно с Костей Олениным (id499348) — смотри картинки) и в том, каких принципов придерживаться при работе с ним. Мне пока рано что-то рассказывать – штука еще не доделана, все может поменяться.
А что бы ты упростил?
11 августа 2007 в 23:02
я правильно понял?
существует иерархия состояний и в случае если состояние перетекает из одного в другое, освобождение ресурсов происходит до первого общего родителя?
на графе непонятно:
– какое состояние от какого наследуется
– какое состояние исходное
– что такое видеосервер?
11 августа 2007 в 23:00
клёвая идея надо будет взять на заметку, чуть упростить, и реализовать в своих проектах. а в чём, собственно, проблема?
10 августа 2007 в 22:03
Полный граф все-тки пришлось нарисовать. Иначе вообще ничего не понятно.
Картинка: //vkontakte.ru/photos.php?act=show&id=28533530
Код: //vkontakte.ru/photos.php?act=show&id=28533533
9 августа 2007 в 23:00
"Множество входов не раздувается", т.к. переходы из А в Б разбиты на три части, каждая из которых используется повторно: выход, событие перехода, вход. Выход и вход, понятное дело, используются повторно при любых переходах. А вот событие перехода может работать, как для конкретной пары А-Б, так и для группы пар: А-Б, А-В, Б-В, например. Но это уже относится к ТЗ, которое считаем фиксированным.
9 августа 2007 в 22:05
Нужно для непосредственного кодирования — чтобы не сломать голову. Есть MVC-приложение: M – модели, которые хранят бизнес-логику, V – views, графические интерактивные куски (считай, "компоненты"), C (controllers) — это механизм подписки и рассылки событий. Язык — ActionScript 3 (Flash). Работает так: виды подписываются на события от моделей и о самих себя, включая внутренние виды (например, ThumbnailList содержит десяток Thumbnail-ов). Такие события приводят к переходу из состояния в состояние. Сами состояния описываются как объекты с парой функций и указателем на состояние-родителя ("контейнера"). Пара функций – это вход и выход из состояния. В этих функциях происходит выделение и освобождение ресурсов соответственно. Такими действиями с ресурсами, в первую очередь, являются addListener и removeListener. Во вторую очередь, это включение-выключение других компонентов (кнопок всяких).
Таким образом, переход из состояния А в состояние Б – это отлов события, вызов выхода из А и всех его предков вплоть до общего предка А и Б, затем вход во всех предков Б вплоть до Б.
Вот, например, иерархия состояний (тире для отступов):
— loadingState
— loadedState
— — browsingState
— — — selectedState
— — watchingState
Причем, selectedState – параметрическое состояние. В него можно заходить многократно с разными параметрами и каждый раз будет осуществляться выход и вход.
При переходе из selectedState в watchingState, выход из loadedState не производится (общий предок). Т.е. это общее состояние характеризует общие для дочерних состояний ресурсы.
9 августа 2007 в 19:03
Мы на это смотрели, но не с точки зрения UI, а с точки зрения реализации торговых стратегий, поэтому мы смотрели на готовые решения (а есть некоторый набор форматов и гуевых редакторов для разных FSM).
А в чем польза этого для GUI? Overview, документирование и тестирование? Если да, то для простых гуев это наверное overkill, а для сложных – скорее всего еще добавит сложности. Например, если у вас куча контролов (а не несколько как в типичных примерах про CD-player), то множество входов раздувается, и, если интерфейс не сильно модальный, их придется обрабатывать почти в каждом состоянии. Поэтому IMHO граф – плохая абстракция здесь. Вот если граф + что-то (есть набор входов, которые обрабатываются поичти всегда одинаково вне зависимости от состояния) – это, наверное, интереснее.
9 августа 2007 в 19:03
У этих вот вроде есть что-то типа отдельной обработки стандартных входов: //smc.sourceforge.net/