Я пытаюсь написать редактор растровых изображений для мобильного устройства (то есть ограниченную версию Photoshop). Документ пользователя состоит из ~ 4 растровых изображений размером около 1000x500 каждая.
Мне нужна надежная и эффективная система отмены / повтора, максимально простая. Я стремлюсь примерно на ~ 0,2 с отменить или повторить редактирование. Мне нужны отзывы о моем нынешнем подходе или о новых идеях, которые я могу использовать. Я думаю, что то, что у меня есть, слишком сложно, поэтому я осторожен в продолжении, поэтому просто знать, что это лучшее из того, что я мог сделать, было бы хорошо.
Я экспериментировал с комбинациями использования шаблона Command и Memento для моей системы отмены / возврата. Вот некоторые выводы, к которым я пришел:
У меня недостаточно памяти, и я не могу записать память на диск достаточно быстро, чтобы использовать память для поддержки операции «неисполнение» предыдущей команды во многих ситуациях, например, если пользователь делает несколько отдельных мазков очень быстро, я не смогу хранить растровые изображения, представляющие то, что пользователь закрасил, не заставляя пользователя ждать их сохранения.
Если я восстановлю документ в его начальном состоянии и воспроизведу все команды, кроме последней, которая должна была отменить, это будет слишком медленно даже после небольшого количества команд, например, воспроизведение 10 мазков или 5 мазков занимает ~ 1 с, что слишком вяло.
Я могу обойти предыдущую точку, периодически сохраняя весь документ в фоновом режиме на диск и восстанавливая эту контрольную точку перед воспроизведением команд. Чтобы отменить дальше, чем последняя контрольная точка, мы перезагружаем контрольную точку перед этим и воспроизводим команды.
Подход 2 с 3 работает хорошо, за исключением того, что сохранение всего документа становится все медленнее и медленнее, поскольку добавляется больше слоев, и это уже медленно с 4 растровыми изображениями (ожидание ~ 5 - 10 секунд). Поэтому мне нужно изменить 3, чтобы сохранить только то, что изменилось с прошлого раза.
Поскольку многие команды работают только на одном слое, имеет смысл сохранять только те слои, которые были изменены с момента последней контрольной точки. Например, мой стек команд может выглядеть так, если у меня есть 3 начальных слоя, где я указал, где могут быть сохранены контрольные точки.
(Checkpoint1: Save layer 1, 2 and 3.)
Paint on layer 1
Paint on layer 1
(Checkpoint2: Save layer 1. Reuse saved layers 2 and 3 from Checkpoint1.)
Paint on layer 2
Paint on layer 2
(Checkpoint3: Save layer 2. Reuse saved layers 1 and 3 from Checkpoint2.)
Paint on layer 3
Paint on layer 3
Flip layer 3 horizontally.
(Checkpoint4: Save layer 3. Reuse saved layers 1 and 2 from Checkpoint3.)
Resize layer 1, 2 and 3.
(Checkpoint5: Save layer 1, 2, 3.)
Во время редактирования я отслеживаю, какие слои были изменены со времени предыдущей контрольной точки. Когда я восстанавливаю контрольную точку, я восстанавливаю только те слои, которые изменились, например, чтобы восстановить Checkpoint4 после изменения слоев 2 и 3, я перезагружаю резервные копии слоев 2 и 3 с диска. При добавлении контрольной точки я сохраняю только слой, который был изменен до сих пор. Я могу сделать все это в основном автоматически, за исключением того, что в моем интерфейсе должны быть места, где пользователь вынужден ждать сохранения контрольных точек, потому что я могу хранить только 1 временную копию слоя в памяти за раз.
Что ты думаешь? Это гораздо сложнее, чем хотелось бы, но я не вижу другого пути. Есть ли другие полезные шаблоны, которые я могу использовать, чтобы облегчить мне жизнь?