【发布时间】:2016-04-16 14:19:20
【问题描述】:
使用 Reflex-DOM,我想创建一个 Event t (),当浏览器准备好绘制下一帧时触发,即当 requestAnimationFrame 触发时。我试过这样:
{-# LANGUAGE RecursiveDo, TypeFamilies #-}
import Reflex.Dom
import Reflex.Host.Class
import GHCJS.DOM (currentWindow)
import GHCJS.DOM.Window as Window
import GHCJS.DOM.Types (RequestAnimationFrameCallback(..))
import GHCJS.Foreign.Callback
import Control.Monad
import Control.Monad.IO.Class
refresh win = do
(event, ref) <- newEventWithTriggerRef
postGui <- askPostGui
rec cb <- liftIO $ asyncCallback1 $ \_timestamp -> do
scheduleNext
putStrLn "about to fire the event"
postGui $ void $ fireEventRef ref ()
putStrLn "event fired"
let scheduleNext = Window.requestAnimationFrame win $ Just $ RequestAnimationFrameCallback cb
liftIO scheduleNext
return event
我的测试应用如下:
main :: IO ()
main = mainWidget $ do
Just win <- liftIO currentWindow
tick <- refresh win
display =<< count tick
但是,计数没有增加。然而,在浏览器的 JS 控制台上,我确实看到 about to fire the event 和 event fired 重复打印。
【问题讨论】:
-
嗨,我是新来的反应...偶然发现了这个问题...在我看来,askPostGui 可能从 gtk2hs 连接到 postGUIasync 或 postGUIsync,这是我创建的一种解决方法+回到过去,当 GTK2 只能单线程工作时,通过电子邮件发送给 gtk2hs 的维护者。应该将 IO 操作插入 IORef [IO()] 并触发 GTK2 线程执行该操作。触发器将一个字节发送到文件句柄/管道中。如果我的假设是正确的,那么 postGui 不应该发回东西,而且它不会在没有 -threading 运行时的情况下工作。再说一次,只是猜测。
标签: haskell dom requestanimationframe ghcjs reflex