Haskell Gloss,在动画功能中从控制台读取不会更新绘图

标签 haskell io gloss

我正在使用 haskell 简单地实现 LOGO。

对于图形部分,我使用 Gloss,特别是 Graphics.Gloss.Interface.IO.Simulate 模块中的函数 simulateIO

我用它来制作一个窗口并保存我的程序的状态。问题在于更新,它使用类型为 ViewPort -> Float -> model -> IO model 的函数,其中 model 是状态的类型。我不使用 Viweport 和 Float 参数。我从控制台读取一行,对其进行解析并对其求值,以获得我在函数结束时返回的新状态。

在第一次执行和更新显示后,它不再更新。 当我打印状态时,我可以看到它正在更新,但显示器没有。 放置一个常量值而不是获取输入可以解决问题,但这也不是很有用:)。

这是我的代码的一小部分:

runProgram :: Display -> IO ()
runProgram d = simulateIO d white 10 defaultEnv env2Pic step

env2Pic :: Env -> IO Picture
env2Pic e =
   ...
   in return $ pictures piccc

step :: ViewPort -> Float -> Env -> IO Env
step v f e = do
  minput <- getLine
  case minput of
    "" -> step v f e
    _ -> case parserComm minput of
      Nothing -> print "no parse" >> step v f e
      Just cms -> evalPrint e cms

evalPrint 返回 IO Env

有没有办法强制重绘?

编辑 看来我的功能运行良好,确实在修改状态。我认为问题是函数 env2Pic 没有被 simulateIO 函数调用,只是在开始时调用了几次。

我还是不明白为什么。

最佳答案

显然 step 函数不应该阻塞,因此您不应该在该函数中运行像 getLine 这样的阻塞操作。您可以通过在后台线程中运行 getLine 来解决这个问题。这是一个最小的工作示例:

import Control.Concurrent (forkIO)
import Control.Monad (forever)
import Data.IORef (IORef, atomicWriteIORef, newIORef, readIORef)
import Graphics.Gloss (Display (InWindow), Picture (Text), white)
import Graphics.Gloss.Interface.IO.Simulate
  ( ViewPort,
    simulateIO,
  )

runProgram :: IORef String -> Display -> IO ()
runProgram r d = simulateIO d white 10 "" env2Pic (step r)

type Env = String

env2Pic :: Applicative f => Env -> f Picture
env2Pic e = pure (Text e)

step :: IORef String -> ViewPort -> Float -> Env -> IO Env
step r _ _ _ = readIORef r

background :: IORef String -> IO b
background r = forever $ do
  x <- getLine
  atomicWriteIORef r x

main :: IO ()
main = do
  r <- newIORef ""
  forkIO $ background r
  runProgram r (InWindow "test" (500, 500) (100, 100))

关于Haskell Gloss,在动画功能中从控制台读取不会更新绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70283210/

相关文章:

Haskell Recursive HashMap 任意深度的数据结构

haskell - 在 if 内执行 readLine

类函数的 C++ 提取运算符

haskell - 为什么 `do` block 中的类型在下一行匹配,但在同一行不匹配?

haskell - 为什么 Gloss 不能以原始分辨率渲染?

haskell - 使用 case 时解析输入 '->' 错误

Haskell:定义具有函数作用域的新数据类型

haskell - 禁止赋值