我一直在比较只拉取的FRP(例如netwire)和推-拉混合的FRP(例如reactive-bannana)在游戏实现中的优劣。它们之间有什么优势吗?我注意到的是:
- 推送事件使来自GLFW或GLUT的鼠标点击/按键事件变得容易。
- Netwire使用的箭头化FRP拥有很少的
IO
,这总是更好的。 - 貌似对鼠标移动等事情只有拉取响应可能会导致时间泄漏。
我还错过了什么?
编辑,为了使这个问题不再基于观点:主要目标是尽可能地具有表达力/简洁性,没有时间泄露。
更新:我发现Netwire存在一个很大的问题,就是似乎没有方便的方法来拥有多个帧速率,正如文章“修复你的时间步长”中所描述的那样。
更新2: 我解决这个问题的方式是使我的游戏模拟电线返回一个Float -> IO()
,它接收Alpha值并通过该Alpha值插值所有的GL调用。理想情况下,我应该能够通过一个MVar
将此“绘制函数”传递给另一个线程并在该线程中运行它。Haskell真是太棒了。
更新3:自提出此问题六个月以来,我基于Netwire和“实体-组件编程”这一概念开发了一个简单的渲染引擎。在这个过程中,我实际上并没有发现使用FRP非常有帮助。事实上,Wire
的可表达性在某些情况下实际上成为了阻碍。问题集中在对象的“身份”上。当定义Wire
类型的值时,它没有身份,即它可能在整个网络中被多次重复使用,并且每次都代表不同的物理对象。当您想要执行碰撞检测之类的操作时,由于不能存在而不被融合成单个不透明的线,因此无法遍历场景图。这是一个巨大的痛苦。这个问题在“玩具”示例中不会发生,因为可以轻松地指定哪些对象的哪些属性以哪种方式与其他对象交互。我认为这是FRP的任何类型存在的问题。
如果一些Haskell巫师能够证明我是错的,那将是很棒的,但我真的看不到解决它的方法。此外,如果我的解释不好,我很抱歉,但是没有亲自尝试是很难理解的。