我正在尝试为移动设备(即有限版本的 Photoshop)编写位图编辑器。用户的文档由大约 4 个位图组成,每个位图大小约为 1000x500。
我想要一个尽可能简单的强大且高效的撤消/重做系统。我的目标是大约 0.2 秒来撤消或重做编辑。我正在寻找一些关于我当前预期方法的反馈或一些我可以使用的新想法。我认为我所拥有的太复杂了,所以我对继续进行持谨慎态度,所以只要知道这是我能做的最好的事情就很好了。
我已经为我的撤消/重做系统尝试了使用命令模式和备忘录模式的组合。到目前为止,我得出的一些结论是:
我没有足够的内存,并且我无法将内存写入磁盘的速度足够快,无法在许多情况下使用备忘录来支持对上一个命令的“未执行”操作,例如,如果用户非常快速地完成了几个单独的笔画,我不会能够存储代表用户绘制内容的位图,而无需让用户等待它们被保存。
如果我将文档恢复到其初始状态并重播除最后一个执行撤消的命令之外的所有命令,即使是适度数量的命令(例如重播 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.)
在编辑过程中,我会跟踪自上一个检查点以来哪些图层已被修改。当我恢复检查点时,我只恢复已更改的层,例如在修改第 2 层和第 3 层后恢复 Checkpoint4,我从磁盘重新加载第 2 层和第 3 层的备份。添加检查点时,我只保存到目前为止已修改的图层。我可以使所有这些大部分自动化,除非我的界面中需要用户被迫等待检查点被保存的地方,因为我一次只能在内存中保留大约 1 个图层的临时副本。
你怎么看?它比我希望的要复杂得多,但我看不到任何其他方式。还有其他有用的模式可以让我的生活更轻松吗?