This library expose a SFML monad which deliver a higher level of abstraction over the low level bindings.
It exposes a SFML
monad you must use and eventually run to go back into IO
.
In doing that, the SFML
monad runs all the destructors for you. This means you
don't have to worry about explicit deallocation of the underlying C resources.
To scrap as much boilerplate as possible, TH has been used. In fact, thanks to the TH machinery, the whole SFML functions has been lifted appropriately here:
This is a 1:1 translation of this example:
module Main where
import Control.Monad.SFML
import qualified SFML.Graphics as G
import qualified SFML.Window as W
import SFML.Graphics.Color
import Paths_SFMLExamples
main :: IO ()
main = runSFML $ do
let ctxSettings = Just $ W.ContextSettings 24 8 0 1 2
wnd <- createRenderWindow (W.VideoMode 640 480 32)
"SFML-Control Demo" [W.SFDefaultStyle] ctxSettings
logoPath <- liftIO $ getDataFileName "Haskell-Logo.png"
fontPath <- liftIO $ getDataFileName "Vera.ttf"
musicPath <- liftIO $ getDataFileName "DST-BreakOut.ogg"
tex <- textureFromFile logoPath Nothing
spr <- createSprite
fnt <- fontFromFile fontPath
txt <- createText
setTextString txt "Haskell-Control\nhandles memory\nfor you"
setTextFont txt fnt
setTextCharacterSize txt 20
setTextColor txt blue
msc <- musicFromFile musicPath
play msc
setTexture spr tex True
loop wnd spr txt
loop :: G.RenderWindow -> G.Sprite -> G.Text -> SFML ()
loop wnd spr txt = do
drawSprite wnd spr Nothing
drawText wnd txt $ Just (G.renderStates { G.transform = G.translation 460 40 })
display wnd
evt <- waitEvent wnd
case evt of
Nothing -> return ()
Just W.SFEvtClosed -> return ()
_ -> loop wnd spr txt
As you can see it's almost a 1:1 translation, you just need to run the monad
and get rid of explicit destroy
!
We decided that the user shouldn't pay the extra burder of a SFML
monad if all he
wants is a low level SFML binding.