【发布时间】:2019-06-06 02:03:44
【问题描述】:
我想从多个线程(4 个线程)更新 Haskell Gloss GUI。
我正在查看一个应用程序,其中 Haskell Gloss GUI 上的事件触发一系列步骤,最终创建线程,每个线程都可以并且应该在需要时更改 GUI。我正在使用 Gloss play 函数。
Gloss GUI 函数play 类型:
play
:: Display
-> Color
-> Int
-> world
-> (world -> Picture)
-> (Event -> world -> world)
-> (Float -> world -> world)
-> IO ()
注意参数(Event -> world -> world),它是处理键盘事件的函数。
如果我在键盘上点击说 x,那么handleKeys::Event -> world -> world 会捕获这个event,并采用world(我的应用程序模型,它是由 Gloss 显示的数据结构)并返回 world 有或没有变化。
根据handleKeys::Event -> world -> world 处理的事件,可以使用forkIO :: IO () -> IO ThreadId 生成其他线程。这些产生的线程还应该操作world 并返回world 以供显示。也就是说,每个线程都运行一个world->world 类型的函数。然后我会使用 STM 原语进行并发。这些原语是:
putTMVar :: TMVar a -> a -> STM ()
takeMVar :: MVar a -> IO a
atomically :: STM a -> IO a
retry :: STM a
orElse :: STM a -> STM a -> STM a
正如您已经猜到的那样,Haskell 类型检查器让我头痛。是否有可能运行依赖 STM 并发的 Gloss 应用程序来更新 GUI 而不会违反类型?
【问题讨论】:
-
无法写出答案,但您应该使用来自
Graphics.Gloss.Interface.IO.Game的playIO -
@monocell 有价值的信息,点赞。
-
这不能回答您的问题,但是使用多线程更新光泽度的另一种解决方案是使用并行库(不需要 IO)而不是 STM 库。