[reactive] An adapter for SDL
Facundo Domínguez
facundominguez at gmail.com
Thu Aug 5 11:43:48 EDT 2010
Dear list:
I've been trying to make an adapter for SDL, and it looks like I could
have found some sort of bug. My test program leaks memory as it runs
and does not react to clicks, but I cannot figure out why. I've tested
this on Mac Leopard with ghc-6.12.1 and debian lenny with ghc-6.12.3.
Here's the code:
module Adapter where
import qualified Graphics.UI.SDL as SDL
import Control.Monad(liftM)
import FRP.Reactive
import FRP.Reactive.LegacyAdapters(makeClock,makeEvent,Sink,cGetTime,mkUpdater)
import qualified Graphics.UI.SDL as SDL
-- |Configures a Behavior to run. The first return 'IO' action should be called
-- to update the screen. The second return 'IO' action must be called
-- regularly to poll for events.
configSDLBehavior :: (Event SDL.Event -> Behavior (IO ())) -> IO (IO (), IO ())
configSDLBehavior f = do clock <- makeClock
(evSink,evs) <- makeEvent clock
upd<-mkUpdater (cGetTime clock) (f evs)
return (upd, getNextEvents 30 >>= mapM_ evSink)
-- |Creates an source for sdl events and the 'IO' action that must be called
-- regularly to poll for events.
sdlEvents :: IO (Event SDL.Event, IO ())
sdlEvents = do clock <- makeClock
(evSink,evs) <- makeEvent clock
return (evs, getNextEvents 30 >>= mapM_ evSink)
-- |@getNextEvents n@ polls for at most the next n events.
getNextEvents :: Int -> IO [SDL.Event]
getNextEvents n | n<=0 = return []
| otherwise = do ev<-SDL.pollEvent
case ev of
SDL.NoEvent -> return []
_ -> liftM (ev:)$ getNextEvents (n-1)
-----------
And here is my test program:
measureFPS :: IO Int -> IO ()
measureFPS frame =
do t0<-SDL.getTicks
n<-frame
t1<-SDL.getTicks
putStr$ show (toEnum n/ (toEnum (fromEnum (t1-t0))/1000)) ++ "\n"
testB :: IO () -> Event SDL.Event -> Behavior (IO ())
testB quit evs = return () `stepper` fmap (pure quit) (filterE isKeyDown evs)
isKeyDown e@(SDL.KeyDown _) = True
isKeyDown e = False
main = SDL.withInit [SDL.InitVideo]$
do screen <- SDL.setVideoMode 640 480 8 [SDL.SWSurface,SDL.AnyFormat]
SDL.setCaption "Test" ""
SDL.enableUnicode True
quitv <- newIORef False
(upd,poll) <- configSDLBehavior (testB (writeIORef quitv True))
measureFPS (loop 0 quitv upd poll)
where
loop n quitv upd poll | seq n True =
do b <- readIORef quitv
if b then return n
else do poll
SDL.delay 10
-- threadDelay 10000
upd
loop (n+1) quitv upd poll
Best,
Facundo
More information about the Reactive
mailing list