c – 在painter程序中实现undo redo

c – 在painter程序中实现undo redo,第1张

概述我正在写一个画家程序,我想在其中实现基本 *** 作的撤消和重做,如绘制线条,绘制椭圆等. 有没有好的方法呢?一项 *** 作应包含哪些属性? 编辑: 实际上我知道Command模式,但我想弄清楚的是,应该在Command对象中记录哪些数据,以便完成撤消. 因此,在栅格应用程序中撤消/重做有点棘手. 首先,花25分钟看this talk(通过@chris).它可能会让你大吃一惊,而且速度很快.然后继续阅读. 最简 我正在写一个画家程序,我想在其中实现基本 *** 作的撤消和重做,如绘制线条,绘制椭圆等.
有没有好的方法呢?一项 *** 作应包含哪些属性?
编辑:
实际上我知道Command模式,但我想弄清楚的是,应该在Command对象中记录哪些数据,以便完成撤消.解决方法 因此,在栅格应用程序中撤消/重做有点棘手.

首先,花25分钟看this talk(通过@chris).它可能会让你大吃一惊,而且速度很快.然后继续阅读.

最简单的方法是在每次 *** 作之前简单地制作光栅画布的副本.将这些列表存储在撤消/重做缓冲区中,您可以愉快地前进和后退. (您可能还想存储工具状态).

这样做的缺点是它很大而且价格昂贵.有很多方法可以缓解这个问题.

首先,您可以平铺图像(无论如何),并使用copy-on-write.现在,通过撤消列表共享未修改的切片.

其次,而不是完整的栅格,记录重新创建效果所需的参数.只要你有一个合理的附近(在重建的时间)“之前”的图像你可以重建,这可以非常快.

第三,记录“擦除”效果所需的信息和信息.这有时比您触摸的所有图块的副本便宜(并且您触摸的所有图块的副本是实现此目的的一种方式).

您可以将撤消/重做堆栈与此混合.对于可重构的舞台,您需要光栅副本或先前的光栅副本以及一组可以重复以重新生成它的前向 *** 作,或者将来的光栅副本和一组向后 *** 作可以重复以重新生成它.

除此之外,您还可以将所述撤消信息推出内存并将其保存到磁盘.

在某些情况下,您还希望能够将多个步骤折叠为一个撤消/重做步骤.这可以让你为“最近”的 *** 作保持细粒度的撤销/重做,同时仍然能够一直撤消到“你打开文件”.

通常,您关心从当前步骤到达撤消/重做步骤(这意味着您只需要重做步骤的向前差异信息,向后撤销),但这会增加管理撤消/重做堆栈的复杂性(有时它是更容易存储两个).

还有一个问题是“您是否要在保存文件时保存撤消/重做 *** 作数据”(是否可以序列化?).您想支持撤消/重做树还是仅支持线性历史记录? (即,如果你撤消3次,然后画一个像素,你应该能够“回到”原始历史,还是被像素绘制破坏?)

但是,实际上您从画布的简单光栅副本开始.这是必须测量任何其他实现的标准,因此对于单元测试目的,无论如何都需要“完整光栅”撤销/重做功能.添加“在撤消/重做上花费的总内存”设置和磁盘序列化(以及“撤消/重做时的总磁盘空间”)和下一个折叠规则(因为这些是简单的步骤).然后平铺您的光栅图像并实现写入时复制图块,您的效率将达到90%.

之后,开始担心为某些工具进行优化的撤消/重做,以便可以对基于图块的栅格信息进行大规模打击.

现在,回到帖子开头的视频.再看一遍.使用暂停可在每个代码点停止视频.自己输入代码.试着理解你写的是什么.如果你不明白你写的是什么,那就去学习吧.你将成为一个更好的程序员,如果你在谈话结束时,你将编写一个更强大的撤销/重做更好的光栅绘画应用程序.

该实现的基础是文档数据的写入类型擦除系统的副本,使用类型擦除来允许值语义.它没有立即推广到文档模型,但即使你做的唯一的事情就是在你的tile系统中使用类似的东西(使用use_count()== 1导致你打破const for write-on-write)你将会领先于比赛.

总结

以上是内存溢出为你收集整理的c – 在painter程序中实现undo redo全部内容,希望文章能够帮你解决c – 在painter程序中实现undo redo所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1216149.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存