C# 实现撤销/重做
在绘图应用程序中,我正在使用实现多级撤消/重做。我面临的一个问题是,如果图形包含一个或多个图像对象(我的图形对象可以嵌入base64编码的图像对象,就像Visual Studio的resx文件一样),memento(状态对象)将变得太大,这将使撤销/重做堆栈很快攀升到数兆字节,因为频繁的鼠标操作在绘图应用程序中很常见。为了解决这个问题,我在其中引入了gzip压缩,所以现在我将memento的压缩版本保存到堆栈中。这导致整个堆栈大小减少了约90% 现在,这导致了另一个问题。压缩/解压纪念品所需的时间给对象定位/调整大小带来了相当大的困难C# 实现撤销/重做,c#,.net,performance,undo-redo,C#,.net,Performance,Undo Redo,在绘图应用程序中,我正在使用实现多级撤消/重做。我面临的一个问题是,如果图形包含一个或多个图像对象(我的图形对象可以嵌入base64编码的图像对象,就像Visual Studio的resx文件一样),memento(状态对象)将变得太大,这将使撤销/重做堆栈很快攀升到数兆字节,因为频繁的鼠标操作在绘图应用程序中很常见。为了解决这个问题,我在其中引入了gzip压缩,所以现在我将memento的压缩版本保存到堆栈中。这导致整个堆栈大小减少了约90% 现在,这导致了另一个问题。压缩/解压纪念品所需的时
解决这个问题的一种方法是使用,但我不愿意这样做,因为它会在应用程序的许多部分引入大量的工作。您还看到了其他替代方法吗?在不完全切换到命令模式的情况下,我能想到的唯一解决方案是生成一种对象作为纪念品,而不是使用整个对象 这个想法是,你可以从memento中删除任何没有改变的数据。然后,您将只存储差异 在执行撤消操作时,您将使用对象的当前状态和差异来生成一个memento并将其注入到过程中 下面是它的基本外观:
您将使用一个memento对象并仅存储diff对象,如果需要,这些对象也可以进行压缩,但可能会很小。当我在90年代用Delphi做类似的事情时,每当重新绘制速度太慢时,我都会拍摄快照,即当前状态的位图,在堆栈/队列/列表上执行大量绘制操作后。但是,不确定您是否可以这样做。您只能压缩比X早的纪念品,或者保持最后一个Y纪念品始终解压缩,然后随着堆栈的增长进行压缩。这样,您总是可以快速撤消最后的Y命令,但仍然可以压缩大部分历史以节省空间。@这是一个非常有趣的想法,但是如果堆栈中包含的内存超过Y,您将如何处理这种情况?每次操作都需要压缩一个新对象。@poke:正如Samy所指出的,这会在我现在所在的位置结束,只是在Y mementos之后。啊,不,这不是我的选择。这是一个矢量绘图应用程序。现在这似乎是一个非常好的主意。我的memento是字符串(xml中的序列化对象图),因此如果我可以计算当前和以前状态的“差异”,我可以将其存储为memento。现在的问题是如何计算“差异”。关于这一点,我问了几个问题,但似乎它们都是逐行处理字符串,而不是我需要的逐字符处理。查找两个字符串之间的差异是一个众所周知的算法问题,可以找到许多解决方案。编辑距离是计算两个字符串(逐字符)之间差异的度量,Levenshtein距离和LCS(最长公共子序列)就是这样的编辑距离,可以调整为返回两个字符串之间的差异。我还可以说,您不需要最佳解,只需要一个良好的近似值。您可以将长字符串拆分为块,并将它们作为行进行比较。因为您有一个XML表示,所以还可以查找树比较算法。