用于基于节点的编辑器的数据结构应该使用哪些?

4
一些程序(如声音合成、过程纹理生成等)通过图形编辑器给予用户完全自由地安排程序的各种功能能力。用户可以放置一个或多个“节点”(每个节点代表某种从一个或多个输入生成一个或多个输出的函数),并以任何希望的方式将它们连接在一起,以生成最终输出。
我想知道这种软件在必要数据结构方面的最佳表示方式,无论是对于生成系统本身还是对于其图形表示。我特别困惑于如何模拟节点输入和输出可能具有不同数据类型的事实,并且根据节点类型只有一些可能有效。
因此,如何建模:
- 节点输入/输出值 - 节点本身(继承?)及其连接 - 从起始节点到输出节点传播的生成过程

2
这个问题相当开放,虽然很有趣。 - Caribou
1
这里看不到任何C++代码。 - Peter Wood
听起来值得研究一下 boost::graph 库。 - mark
@Peter Wood:当然,你是对的。我只是在考虑从性能角度来看,人们可能会使用C++,所以我加上了它,以防万一它会有所不同(但很可能不会)。 - Askaga
2个回答

2
我曾经涉足过一些类似这样的系统。有许多不同的实现方式。但我过去常用的一种方法是,将节点对象链接到其他节点对象。节点通过某个IAction接口包含一个操作对象。用户以某种方式指定在特定节点上实现IAction接口的具体操作对象(这通常还涉及为对象指定一些状态,例如要应用的过滤器参数)。

然后,有一个框架来初始化(编译)和执行(运行)图形,并安排在输入准备就绪时调用节点的IAction接口,并将输出传递给下游节点。这是一个相当简单的算法:并行运行所有具有所有输入的节点(从没有输入的节点开始),并将其余节点放入等待队列,直到它们的输入准备就绪。

这只是其中一种实现方式;还有许多变体,正如您所指出的,很多系统都使用了这种技术。也有一些框架(如TPL Dataflow,如果我理解正确的话)。

关于如何确保节点之间的连接一致性的问题,我认为这取决于框架和节点分别承担多少责任。在一个极端,框架可以在图形“编译时”严格匹配连接类型;在另一个极端,框架可以让节点在“运行时”检查连接是否正确。如果大多数连接都是相同类型的,比如都是字节流,那么后者可能更合适。
顺便说一句,在Java或C#(或其他高级语言)中可能比在C++中更容易实现,因为有更多的接口、反射、动态加载对象等支持(例如,在C#中,您可以轻松地为对象指定类型,并从流中动态创建它,而在C++中您必须自己编写代码来实现)。

1
您可能需要查看观察者模式,特别是信号/插槽系统,以处理此类事情。 Observer Pattern, Boost.Signals 我曾经参与的一个使用C++的项目使用信号/插槽,允许用户在运行时动态连接不同的音频合成模块。但这可能会牺牲一些性能。
至于对不同可能输入进行建模,您可以创建一个信号对象来包含实际数据作为void指针和字符串或枚举,指定接收类在处理期间假定为正确数据类型。当用户最初连接这些对象时,可以返回一种契约(“这些是该对象发送的类型”),并且可以在处理开始前进行实际验证。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接