8

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

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

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

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

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

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

4

1 回答 1

2

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

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

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

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

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

于 2012-09-12T05:57:29.633 回答