Comments 9
А в Vim undo — это дерево. Иногда очень выручает, несмотря даже на то, что я не использую дополнения для визуализации undo состояний. Также позволяет иметь команды вида :earlier 10m
(использовать состояние, которое было 10 минут назад по сравнению с текущим) — при использовании пользователем undo в этот промежуток времени без дерева (для корректной работы обыкновенного undo) и списка с временными метками, ссылающегося на узлы дерева (для корректной работы :earlier
/:later
) ничего не выйдет.
А если серьезно, то под каждый проект надо самому это допиливать и определять, что делает каждое действие — от полного сохранения всего состояния модели данных в сериализованном виде (что проще, легче и зачастую — лучший вариант), до выполнения действий над текущим состоянием модели (что сложнее, т.к. требует детерминированного результата этих самых действий, возможности создания обратных операций, и при достаточно большом цикле Undo-Redo может в итоге изменить данные — привет float, double & co!).
Из-за этого undo-redo функционал в каждом фреймворке должен быть минимальным и простым, чтобы в него было легко вставить свою логику.
Тут уже есть какое-то переусложнение с этим вашим (с) interface UndoWatcher.
Это какбы намекает на то, что действия в undo-стэке отличаются от тех, которые выполняет сам пользователь, и больше похоже на тот вариант, где данные тупо сериализируются. Во 1х это подойдет не всем, а во 2х — если это не так, то остальная часть программы без undo-redo функционала не должна знать о нем и для нее любое undo-redo действие должно быть таким же, как и остальные действия пользователя.
Вы верно отметили, Qt-шный фреймворк был для меня стартовой точкой, с ним я работал лет пять, наверное. Отличное решение, я в него добавлял сериализацию (так для ясности я назову store/restore) для проектов нашей группы, а так же версионность. Макросы там реализованы неправильно, имхо. Пришлось поправлять.
Именно это все я собрал воедино в Java, так как на сегодня Java/JavaFx/Android — мое направление развития.
UndoWatcher
всего лишь qt-шные signals/slots, реализованные средствами Java. Это read-only информация о происходящем со стеком. QUndoStack
, раз уж Вы его упомянули, именно так сигналит клиентам о своем состоянии.
А так-то да, на вкус и цвет, как говорится.
Наверное, следует рассматривать разные подходы. Делать профилирование каждой операции. Некоторые можно заменить "действиями", а где-то возможно, придется сбрасывать 20 метров на диск. Сразу так и не скажешь. Специфика в том, битмапы, это не векторая графика, тут после ряда undo/redo можно такое на выходе получить…
На первый взгляд, все-таки лучше сохранять действия — выглядит так, словно это будет компактнее и быстрее загружаться.
К примеру
CropUndo
: хранит координаты прямоугольника обрезки.Redo()
— применяет обрезку, сохраняя обрезанное,Undo()
— возвращает обрезанное, совершая операцию "склеивания"BlurUndo
: сохраняет процент размытия.Redo()
— накладывает маску (слой) с размытием на текущий битмап,Undo()
— удаляет маску (слой)StretchUndo
: с растягиваниями уже посложнее,Undo()
вряд ли вернет прежнее качество
Я бы поинтересовался на профильных форумах, присмотрелся к Фотошопу. Не пользуюсь им уже более 10 лет, со времен Photoshop v.6. Там довольно шустро все было.
Вдогон к предыдущему комментарию.
Вы знаете, а ведь я вспомнил, что Фотошоп был очень прожорлив по памяти, так вот скоре всего тяжелые операции с битмапами для скорости маппировались там прямо в память.
JUndo — undo библиотека для Java