【问题标题】:How to utilize sqlite for undo/redo features?如何利用 sqlite 进行撤消/重做功能?
【发布时间】:2010-10-16 14:20:09
【问题描述】:

我正在编写一个桌面应用程序来使用 C++ 进行矢量绘图,并考虑使用 sqlite 来支持我的撤消/重做功能。

有人使用 sqlite 来实现撤销/重做功能吗?你觉得效果如何?

澄清:

我知道堆栈方法,我什至用这种方法实现了一个应用程序。我遇到的问题是用了一段时间就很难维护了。

我使用 sqlite 的意思是,我将把我的整个内存数据结构映射到一个 sqlite 数据库中,并让 sqlite 为我做差异和修订。 如果我创建内存数据库,速度应该不是问题。

这就是我的想法,我想知道这是否可行。

【问题讨论】:

  • 这似乎有点矫枉过正。正常的有界堆栈/命令模式方法有什么问题?
  • 我同意皮特的观点。从基于堆栈的方法开始;如果这不能解决问题,请考虑让每个命令能够将自身序列化/反序列化到数据库。但实际上,除非您正在做一些非常奇怪的事情,否则基于堆栈的方法将削减它。

标签: c++ sqlite undo undo-redo


【解决方案1】:

当 SQLite 数据库是应用程序的数据文件格式时,使用 SQLite 支持撤消/重做是有意义的。有关如何使用 SQLite 触发器执行此操作的说明,请参阅 the SQLite website。

【讨论】:

  • 如果我的声望超过 15 个,我会投票赞成这个回复。
  • 如果您乐于使用 GPL 许可的库,那么有一个源代码伪造项目已经为您完成了大量工作。 (我还没有使用它;我只是阅读了文档。)您可以在 sourceforge.net/projects/sqlite-undo 找到它
【解决方案2】:

这是在 sqlite3 中对我有用的方法

BEGIN;
-- enter your INSERT, UPDATE or DELETE command
-- if you want to keep it then run command below
COMMIT;
-- to undo - run command below
ROLLBACK;

来源SQLite Transactions (Begin, Commit, Rollback)

【讨论】:

    【解决方案3】:

    【讨论】:

      【解决方案4】:

      基本上可以使用堆栈来实现撤消/重做功能:当用户执行操作时,您将一个表示操作前后状态之间差异的对象压入堆栈,而当您撤消时,您“展开”三角洲。因为用户执行的每个操作都会在堆栈上创建一个新的增量对象,所以 sqlite 可能不是您选择的技术,因为它可能太慢了。我建议考虑仅将撤消/重做信息存储在内存中的可能性,并且仅当您想要实际保存撤消/重做历史记录时才将其线性化到磁盘上。

      【讨论】:

      • 不一定是图形应用程序的最佳方法。知道最后一个操作是将每个像素更改为黑色并不足以撤消该操作。
      • @mgb 当然不是——但无论如何你都不是这样做的。未优化的实现将具有更改像素颜色的基本操作。 delta 对象将是三元组(X、Y、old_color)。当您将 (X, Y) 更改为新颜色时,您会推动增量三元组,包括。堆栈上的旧颜色。稍后,当您撤消时,您会弹出 delta 对象并将旧颜色写回屏幕。将 1000x1000 画布上的每个像素设置为黑色将创建 100 万个增量对象。在实践中,图形程序当然会以更优化的方式进行。
      • 除了使用堆栈,您还可以使用带有“现在”指针的队列。这允许通过在队列中前后移动轻松实现撤消和重做功能(即撤消备份队列中的一个对象并重做向前步进并重做操作)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-26
      • 2013-10-03
      • 1970-01-01
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      相关资源
      最近更新 更多