Reputation: 14660
I am learning how to use the Gloss library to make some animations in Haskell.
Consider the code below which animates a circle that shrinks and expands its radius with time.
import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
type Radius = Float
type RealTime = Float
data World = World Radius RealTime
main :: IO ()
main
= do let initWorld = World 100.0 0
let windowSize = (800,800)
let windowPosition = (200,200)
putStrLn "Before play"
play (InWindow "Wobbling Circle" windowSize windowPosition)
white 40 initWorld renderWorld handleEvent stepWorld
putStrLn "After play"
renderWorld :: World -> Picture
renderWorld (World rad rtime ) = Pictures [ Circle rad ]
handleEvent :: Event -> World -> World
handleEvent _ = id
stepWorld :: Float -> World -> World -- wobbling circle
stepWorld _ (World _ rtime) = World (100 * sin rtime) (rtime+0.1)
I compiled this code with ghc --make -O2 -threaded Main.hs
on an Ubuntu 14.04 machine.
When I run the code, the "Before play" statement is printed out and then the animation starts as expected. However, when I close the animation window, the code terminates immediately without printing the "After Play" statement. Why is that?
Upvotes: 5
Views: 1044
Reputation: 14578
Presumably you are using the GLUT backend (the default). Take a look at some of the source code for gloss
(exactly as it appears with comments):
instance Backend GLUTState where
initBackendState = glutStateInit
initializeBackend = initializeGLUT
-- non-freeglut doesn't like this: (\_ -> GLUT.leaveMainLoop)
exitBackend = (\_ -> System.exitWith System.ExitSuccess)
....
When it exits the main loop, gloss
will call exitBackend
, whatever it is. For GLUT, that simply calls System.exitWith
which naturally will terminate your program. The more sensible thing to do would be to call leaveMainLoop
but as the comment in the code says, implementations of glut
other than freeglut
don't work well with that function (why? who knows. This is what the authors of gloss claim).
Your potential solutions are to use freeglut
specifically and modify the source code of gloss
to change exitBackend
; or use the GLFW backend, which doesn't have this problem.
Upvotes: 2