【问题标题】:Zipper data structure for graphical model editor图形模型编辑器的 Zipper 数据结构
【发布时间】:2012-09-09 14:12:56
【问题描述】:

我正在为“模型”(即具有某种语义的框和线的集合,例如 UML,其细节在这里无关紧要)编写一个图形编辑器。所以我想要一个表示模型的数据结构和一个图表,其中对图表的编辑会导致模型发生相应的变化。因此,例如,如果模型元素的属性中有一些文本,而我在图表中编辑文本,我希望更新模型元素。

模型可能会表示为一棵树,但我希望图表编辑器尽可能少地了解模型表示。 (我使用的是diagrams 框架,因此将任意信息与图形元素关联起来很容易)。如果我能弄清楚应该是什么,可能会有一个“模型”类来对接口进行编码。

如果我用命令式语言来做这件事,那就很简单了:我只需要从图表中的图形元素到模型元素的引用。理论上,我仍然可以通过从大量 IORef 集合中构建模型来做到这一点,但这将是在 Haskell 中编写 Java 程序。

很明显,每个图形元素都会有某种 cookie 与之相关联,这将使模型更新发生。一个简单的答案是给每个模型元素一个唯一的标识符并将模型存储在 Data.Map 查找表中。但这需要大量的簿记以确保没有两个模型元素获得相同的标识符。我也觉得它是一个"stringly typed" 解决方案;您必须处理对象被删除但在其他地方有悬空引用的情况,并且很难说出您的类型中模型的内部结构。

另一方面,Oleg's writings 关于带有多个孔的拉链和具有清晰事务共享的游标听起来是一个更好的选择,如果我能理解的话。我了解了列表和树拉链的基本概念以及数据结构的差异化。图表中的每个元素是否有可能将光标放入模型的拉链中?因此,如果进行了更改,则可以将其提交给所有其他游标?包括树操作(例如将子树从一个地方移动到另一个地方)?

如果有某种关于定界延续的教程,以及它们如何使 Oleg 的多光标拉链工作的解释,这将特别帮助我,这比 Oleg 的帖子稍微不那么陡峭?

【问题讨论】:

  • 也许是钟杰山的博客? :conway.rutgers.edu/~ccshan/wiki/blog/posts/WalkZip1。请注意,Blobs (wxHaskell) 是一个用于编写“网络编辑器”的库——它可能已经有点腐烂了,但更新它可能比使用 Diagrams 重新开始要少。
  • 谢谢。我已经开始解决它了。如果有答案,我会告诉你的。

标签: haskell data-structures zipper


【解决方案1】:

我认为您目前的设计中模型树中的每个节点都由一个单独的图形小部件表示,并且这些小部件中的每一个都可以独立更新模型。如果是这样,我不相信多孔拉链会很实用。问题是拉链的复杂性会随着您希望支撑的孔的数量而迅速增长。当你超过 2 项时,拉链的尺寸会变得很大。从区分的角度来看,2孔拉链是1孔拉链上的拉链,因此复杂性随着链式法则的运算而增长。

相反,您可以从 MVC 中借用一个想法。每个节点仍然与一个小部件相关联,但它们不直接通信。相反,它们会通过一个中间控制器,该控制器维护一个拉链。当小部件更新时,它们会通知控制器,控制器会序列化所有更新并相应地修改拉链。

小部件仍然需要某种标识符来引用模型节点。我发现使用节点的路径通常最容易,例如[0] 用于根,[1,0] 用于根的第二个孩子,等等。这有一些优点。确定路径所指的节点很容易,并且拉链也很容易计算从当前位置到给定节点的最短路径。对于树结构,它们在删除和重新插入之前也是唯一的。即使这通常不是问题,因为当通知控制器应该删除节点时,它可以删除相应的小部件并忽略任何相关的更新。只要小部件的生命周期与每个节点的生命周期相关联,路径就足够独特,可以识别任何修改。

对于树操作,我可能会先销毁然后重新创建图形小部件。

例如,我有一些代码 does this sort of thing。在此模型中,每个节点都没有单独的小部件,而是我使用图表呈现所有内容,然后根据单击位置查询图表以获取进入数据模型的路径。远未完成,也有一段时间没看,所以可能无法构建,但代码可能会给你一些想法。

【讨论】:

  • 关于 Oleg 版本的 zippers 的一点是,它不涉及区分数据结构,而是使用延续来捕获部分行走。
  • @PaulJohnson - 即使连续捕获部分行走,仍然需要表示相同数量的状态,这就是复杂性的来源。它的管理方式不同,因为 Oleg 在延续之间使用显式排序,这意味着您必须通过确保延续以正确的顺序更新来管理复杂性。我不确定哪个在实践中更简单,但我希望这两种方法都不是微不足道的。
猜你喜欢
  • 2011-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
相关资源
最近更新 更多