SFML-control ============ This library expose a SFML monad which deliver a higher level of abstraction over the low level bindings. # What do you mean by higher level? 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. # How the bindings are achieved? To scrap as much boilerplate as possible, TH has been used. In fact, thanks to the TH machinery, the whole [SFML](https://github.com/SFML-haskell/SFML) functions has been lifted appropriately here: [Conversions](https://github.com/SFML-haskell/SFML-control/blob/master/src/Control/Monad/SFML/Conversions.hs) # Example This is a 1:1 translation of [this](https://github.com/SFML-haskell/SFML/blob/master/demos/hello/main.hs) example: ``` haskell 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` ! # Why two libraries? 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.