{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveFunctor #-} module Affection.Types ( Affection , AffectionData(..) , AffectionConfig(..) , AffectionState(..) -- , AffectionDraw(..) -- , Draw(..) , AffectionStateInner -- , AffectionDrawInner(..) , InitComponents(..) -- , Loop(..) , RGBA(..) , DrawType(..) , DrawRequest(..) -- | Particle system , Particle(..) -- | Convenience exports , liftIO , SDL.WindowConfig(..) , SDL.defaultWindow -- | GEGL reexports , G.GeglRectangle(..) , G.GeglBuffer(..) ) where import qualified SDL.Init as SDL import qualified SDL.Video as SDL import qualified Data.Text as T import qualified GEGL as G import Control.Monad.IO.Class import Control.Monad.State -- import Control.Monad.Reader -- import Control.Concurrent.MVar -- | Configuration for the aplication. needed at startup. data AffectionConfig us = AffectionConfig { initComponents :: InitComponents -- ^ SDL components to initialize at startup , windowTitle :: T.Text -- ^ Window title , windowConfig :: SDL.WindowConfig -- ^ Window configuration , preLoop :: Affection us () -- ^ Actions to be performed, before loop starts , drawLoop :: Affection us () -- ^ Function for updating graphics. , updateLoop :: Double -> Affection us () -- ^ Main update function. Takes fractions of a second as input. , loadState :: SDL.Surface -> IO us -- ^ Provide your own load function to create this data. , cleanUp :: us -> IO () -- ^ Provide your own finisher function to clean your data. } -- | Main type for defining the look, feel and action of the whole application. data AffectionData us = AffectionData -- { affectionConfig :: AffectionConfig us -- ^ Application configuration. { quitEvent :: Bool -- ^ Loop breaker. , userState :: us -- ^ State data provided by user , drawWindow :: SDL.Window -- ^ SDL window , drawSurface :: SDL.Surface -- ^ SDL surface , drawStack :: [DrawRequest] -- ^ Stack of 'DrawRequest's to be processed , clearStack :: [DrawRequest] -- ^ Stack of 'DrawRequest's to be invalidated } -- | This datatype stores information about areas of a 'G.GeglBuffer' to be updated data DrawRequest = DrawRequest { requestNode :: G.GeglNode -- ^ The 'G.GeglNode' to blit , requestArea :: G.GeglRectangle -- ^ The area to update , requestBuffer :: G.GeglBuffer -- ^ Buffer to draw , requestPersist :: Bool -- ^ Shall the drawRequest persist } -- | Components to initialize in SDL. data InitComponents = All | Only [SDL.InitFlag] -- | Inner 'StateT' monad for the update state -- type AffectionStateInner us m a = StateT (AffectionData us) m a type AffectionStateInner us m a = StateT us m a -- | Affection's state monad newtype AffectionState us m a = AffectionState { runState :: AffectionStateInner us m a } deriving (Functor, Applicative, Monad, MonadIO, MonadState us) type Affection us a = AffectionState (AffectionData us) IO a -- -- | Inner 'StateT' monad of Affection -- type AffectionInner us od a = StateT (AffectionState us od) IO a -- -- -- | Affection state monad -- newtype Affection us od a = Affection -- { runAffection :: AffectionInner us od a } -- deriving (Functor, Applicative, Monad, MonadState (AffectionState us od)) -- -- -- | Inner drawing monad of Affection. -- type AffectionDrawInner ds a = ReaderT (Draw ds) a -- -- -- | Affectiondrawinf reader monad. -- newtype AffectionDraw ds a = AffectionDraw -- { runDraw :: (ds -> a) } -- deriving (Functor, Applicative, Monad, MonadReader ds) -- -- -- | Loop state monad to hold elapsed time per frame -- newtype Loop f a = Loop -- { runLoop :: f -> (a, f) } -- deriving (Functor, Applicative, Monad, MonadState (Loop f)) data RGBA = RGBA { r :: Int , g :: Int , b :: Int , a :: Int } -- | Type for defining the draw type of draw functions data DrawType = Fill -- ^ Fill the specified area completely with color | Line -- ^ only draw the outline of the area { lineWidth :: Int -- ^ Width of line in pixels } -- | A single particle data Particle = Particle { particleLife :: Double -- ^ Time to live in seconds , particlePosition :: (Int, Int) -- ^ Position of particle on canvas , particleRotation :: Double -- ^ Particle rotation , particleVelocity :: (Int, Int) -- ^ particle velocity as vector of pixels per second } deriving (Show, Eq)