Expand Cut Tags

No cut tags
vorona_n: (nebula)
[personal profile] vorona_n
Которая цитировалась в записи «Об укладывании в воображении перпендикулярного времени (а также 4-х, 5-ти и 6-ти измерений)».

Оригинал взят у [livejournal.com profile] nabbla1 в Граф Андуку.


Два года назад я написал свой первый прототип древовидного Undo, где при возвращении назад и "изменении прошлого" вся дальнейшая история не стирается, а просто "уходит вбок" - мы создаём параллельную реальность, но при желании можем вернуться в исходную.

Этот древовидный Undo мне казался промежуточной ступенью к еще более продвинутому механизму графового Undo, когда история может не только ветвиться, но и склеиваться назад, у нас могут появиться временные петли, например, удалив все объекты, мы тем самым вернемся в самое начало, к пустому документу. Использование хэш-функций позволяет реализовать такой подход - выполнив очередную команду, мы подсчитываем хэш документа и сравниваем с ранее посчитанными хэшами (неплохая идея хранить хэши в хэш-таблице, и замечу, это не вовсе не тавтология), если совпало, то не создаём новое состояние, а переходим к найденному.

У этого подхода есть положительные моменты - закончится, наконец, путаница, что означает выделенное действие в History - что оно уже сделано, или сделано все, что было до него? А проблема вся в том, что у нас всё время смешивалось два совершенно различных понятия - "состояние документа", вершина графа, и "действие", которое переводит одно состояние в другое, т.е ребро графа. Когда мы жмем undo/redo или жмем на одно из действий в History, мы хотим вернуть определенное состояние документа, но нам упорно показывают действия. Из этой же оперы - неизбежный фиктивный элемент в History, как правило, первая запись "новый документ" - он нужен, потому что в линейном Undo состояний на одно больше, чем действий, а мы должны уметь переходить на каждое из состояний!

Но проблем тоже хватает: в линейном undo определено и прошлое, и будущее, так что кнопок undo/redo вполне достаточно. В древовидном undo определено по крайней мере прошлое, так что действие кнопки undo определяется однозначно, а redo можно заставить работать по "текущей альтернативной вселенной". В графовом же undo уже и прошлое становится неопределенным, поскольку в один узел мы могли попасть разными путями, и какой из них выбрать при нажатии undo - уже неясно. Скорее всего, на этот граф все-таки придется наложить "нашу мировую линию" - линейный список пройденных нами узлов, и при нажатии на undo/redo путешествовать по этому списку, иногда даже по кругу.

Техническую реализацию я как будто бы продумал, каждая команда может находиться в одном из трех состояний - "вперед", "назад" и "фиктивная", в первом случае внутри команды хранится достаточно информации, чтобы выполниться, и если это сделать, она сохранит внутри себя информацию, достаточную для отмены ("назад"). Фиктивная же команда вообще не хранит ничего, поскольку выяснилось, что из одного состояния в другое можно перейти окольным путем, и именно так мы и сделаем, чтобы случайно не "зайти с тыла" и не дублировать информацию почем зря. То есть, в реальности мы будем путешествовать по остовному дереву графа, а остальные ребра - "для красоты".

Тяжелее всего для меня - красивая визуализация всего этого дела, вот где можно поломать голову. И еще одна проблема - код древовидного undo за 2 года "эволюции" пришел в совершенно непотребный вид, все обросло взаимозависимостями, так что просто поменять дерево на граф, не порушив все остальное, практически невозможно.

Сейчас занялся рефакторингом всего этого бреда, и по мере выхода более-менее юзабельного кода собираюсь выкладывать его в ЖЖ, вдруг кому будет интересно. Вещь специфическая - код написан на Delphi, меня многие после этой фразы перестают воспринимать всерьез, но привести мне пример другого языка, который компилировался бы в нормальный машинный код, а не промежуточный, как java/dotnet/ruby/python, и при этом поддерживал бы интроспекцию (метаклассы, просмотр свойств и методов объектов, автоматическая сериализация/десериализация без тьмы кода), и еще и обходился бы без зверских Фреймворков на сотни мегабайт, они не могут. Хорошо, что я не программист, а то мог бы и обидеться.

Из-за специфичности я подумываю описывать всё это не здесь, а от имени ЖЖ-юзера [livejournal.com profile] undooku, созданного с этой целью.

September 2017

M T W T F S S
    123
45678910
111213141516 17
18192021222324
252627282930 

Style Credit

Page generated Oct. 19th, 2017 23:23
Powered by Dreamwidth Studios