【发布时间】:2023-10-22 01:41:01
【问题描述】:
我正在尝试为移动设备(即 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 个图层的临时副本。
你怎么看?它比我希望的要复杂得多,但我看不到任何其他方式。还有其他有用的模式可以让我的生活更轻松吗?
【问题讨论】:
标签: algorithm design-patterns optimization undo