es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Haskell Gloss, al leer desde la consola dentro de la función “animate”, la actualización del dibujo no se realiza.

Estoy trabajando en una implementación simple de LOGO en Haskell.

Para la parte gráfica, estoy utilizando Gloss, en particular la función simulateIO del módulo Graphics.Gloss.Interface.IO.Simulate.

La utilizo para crear una ventana y guardar el estado de mi programa. El problema está en las actualizaciones, utiliza una función de tipo ViewPort -> Float -> model -> IO model, donde model es el tipo de estado. No uso los argumentos ViewPort y Float. Leo una línea desde la consola, la analizo y la evalúo para obtener un nuevo estado que retorno al final de la función.

Después de la primera ejecución y actualización de la pantalla, no se actualiza más. Cuando imprimo el estado puedo ver que se está actualizando, pero la pantalla no. Poner un valor constante en lugar de obtener la entrada arregla el problema, pero eso no es muy útil :).

Aquí hay una parte breve de mi código:

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 retorna IO Env.

¿Hay alguna forma de forzar la actualización del dibujo?

EDICIÓN
Parece que mi función está funcionando bien y el estado se está modificando de hecho. Creo que el problema es que la función env2Pic no está siendo llamada por la función simulateIO, solo algunas veces al principio.

Todavía no puedo entender por qué.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Posible solución para forzar el redibujado con Gloss:

    Una posible solución para forzar el redibujado de los gráficos con Gloss es utilizar la función playIO en lugar de simulateIO. playIO toma como argumentos un modo de visualización, un color de fondo, una tasa de cuadros por segundo, un estado inicial, una función para convertir el estado en una imagen, y una función para actualizar el estado.

    La principal diferencia entre playIO y simulateIO es que playIO actualiza la visualización continuamente según la tasa de cuadros, mientras que simulateIO actualiza la visualización solo cuando el estado cambia. Por lo tanto, usar playIO en lugar de simulateIO debería forzar el redibujado de los gráficos incluso si el estado no cambia.

    Aquí tienes un ejemplo de cómo usar playIO en tu caso:

    runProgram :: Display -> IO ()
    runProgram d = playIO d white 10 initialEnv env2Pic step
    
    initialEnv :: Env
    initialEnv = ...
    
    env2Pic :: Env -> IO Picture
    env2Pic e = ...
    
    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
    

    Al usar playIO en lugar de simulateIO, se debería forzar el redibujado de los gráficos incluso si el estado no cambia. Sin embargo, ten en cuenta que esto puede afectar el rendimiento de tu programa, ya que los gráficos se actualizan continuamente según la tasa de cuadros. Por lo tanto, es posible que desees ajustar la tasa de cuadros a un valor más bajo si tu programa se vuelve demasiado lento.

Comments are closed.