【问题标题】:Reactive Banana: Bindings反应香蕉:绑定
【发布时间】:2017-11-22 05:18:59
【问题描述】:

我正在开发一个基于终端的小型 UI,我想使用 Reactive Banana 来描述交互。我感兴趣的唯一外部事件是用户是否按下了某个键。

根据我从 Frameworks 文档中收集到的信息,我可以使用轮询来获取终端输入缓冲区的状态,或者将“事件处理程序”传递给 Reactive Banana。我更喜欢后者,但我发现事件处理部分令人困惑。我将如何准确描述事件驱动的 getChar 版本?最后,我想对“事件键”流进行操作。

我查看了 SDL 和 wx 绑定,但我发现它们没有多大帮助,因为它们充满了与库相关的特性,我非常感谢更简洁的解释如何事件处理程序、事件循环和活性香蕉混合在一起。

【问题讨论】:

  • 网上有很多例子/教程。你试过什么,怎么没用? (处理按键等用户输入事件的函数是fromAddHandler
  • 是的,我想我已经弄清楚了,就在发布之后。看来我只是需要休息一下。如果有任何兴趣,我会发布我的答案,否则可以关闭问题。谢谢。
  • 无需关闭它 - 编辑问题以包含一些显示您最初遇到问题的代码,然后发布包含您找到的解决方案的答案。自我回答的问题是 SO 的一种完全有效的格式!您不会为任何有兴趣的特定人这样做;它是为所有未来读者的后代。

标签: haskell frp reactive-banana


【解决方案1】:

事实证明,使用 Reactive Banana 处理外部事件非常灵活和简单。所需要的只是创建一个带有“newAddHandler”的事件处理程序,它由两部分组成,一个“AddHandler”,可以使用reactimate函数从中创建事件,一个必须由胶水代码调用的处理程序(绑定)将 Reactive Banana 连接到框架(在我的例子中,我只是将 getChar 的结果提供给处理程序)。

这是一个回显击键的示例代码:

echo = do
  (keyEventHandler, fire) <- newAddHandler

  -- Network Specification (echo keyboard input)
  let networkDescription =
      fromAddHandler keyEventHandler >>= -- Create event stream from handler
      reactimate . fmap print -- Map print over event stream

  compile networkDescription >>= actuate 

  -- Event Loop
  hSetBuffering stdin NoBuffering   
  forever $ do
      ready <- hReady stdin
      if ready
          then getChar >>= fire -- Create keyboad event
          else return ()

响应式香蕉的好处是可以从任何上下文调用回调函数“fire”。因此,事件循环也可以在线程中运行或从 C 库中调用。 Heinrich 对How to implement a game loop in reactive-banana? 的回复可以找到更多相关信息。

然而,在没有轮询的情况下捕获任意键盘输入事件并不像我想象的那么容易,POSIX 不会允许它(如果我没记错的话),即使它这样做了,代码也不会是可移植的。 另请注意,在 Windows 机器上,您必须按 Enter,我仍然必须找到解决该问题的方法。有关此问题的更多信息,请参阅at the Haskell bugtracker

【讨论】:

    猜你喜欢
    • 2013-06-20
    • 2013-11-09
    • 2011-09-25
    • 1970-01-01
    • 2012-06-08
    • 2012-10-15
    • 2011-10-12
    • 2014-06-17
    • 2015-01-28
    相关资源
    最近更新 更多