{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
module FRP.Rhine.Gloss.Pure (
GlossM,
paint,
clear,
paintAll,
GlossClock (..),
GlossClSF,
currentEvent,
flowGloss,
flowGlossClSF,
) where
import qualified Control.Category as Category
import Data.Functor.Identity
import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Writer.Strict
import Control.Monad.Trans.MSF (performOnFirstSample)
import qualified Control.Monad.Trans.MSF.Reader as MSFReader
import qualified Control.Monad.Trans.MSF.Writer as MSFWriter
import Data.MonadicStreamFunction.InternalCore
import Control.Monad.Schedule.Class
import Control.Monad.Schedule.Yield
import FRP.Rhine
import FRP.Rhine.Gloss.Common
newtype GlossM a = GlossM {forall a.
GlossM a
-> YieldT (ReaderT (Float, Maybe Event) (Writer Picture)) a
unGlossM :: YieldT (ReaderT (Float, Maybe Event) (Writer Picture)) a}
deriving (forall a b. a -> GlossM b -> GlossM a
forall a b. (a -> b) -> GlossM a -> GlossM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> GlossM b -> GlossM a
$c<$ :: forall a b. a -> GlossM b -> GlossM a
fmap :: forall a b. (a -> b) -> GlossM a -> GlossM b
$cfmap :: forall a b. (a -> b) -> GlossM a -> GlossM b
Functor, Functor GlossM
forall a. a -> GlossM a
forall a b. GlossM a -> GlossM b -> GlossM a
forall a b. GlossM a -> GlossM b -> GlossM b
forall a b. GlossM (a -> b) -> GlossM a -> GlossM b
forall a b c. (a -> b -> c) -> GlossM a -> GlossM b -> GlossM c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. GlossM a -> GlossM b -> GlossM a
$c<* :: forall a b. GlossM a -> GlossM b -> GlossM a
*> :: forall a b. GlossM a -> GlossM b -> GlossM b
$c*> :: forall a b. GlossM a -> GlossM b -> GlossM b
liftA2 :: forall a b c. (a -> b -> c) -> GlossM a -> GlossM b -> GlossM c
$cliftA2 :: forall a b c. (a -> b -> c) -> GlossM a -> GlossM b -> GlossM c
<*> :: forall a b. GlossM (a -> b) -> GlossM a -> GlossM b
$c<*> :: forall a b. GlossM (a -> b) -> GlossM a -> GlossM b
pure :: forall a. a -> GlossM a
$cpure :: forall a. a -> GlossM a
Applicative, Applicative GlossM
forall a. a -> GlossM a
forall a b. GlossM a -> GlossM b -> GlossM b
forall a b. GlossM a -> (a -> GlossM b) -> GlossM b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> GlossM a
$creturn :: forall a. a -> GlossM a
>> :: forall a b. GlossM a -> GlossM b -> GlossM b
$c>> :: forall a b. GlossM a -> GlossM b -> GlossM b
>>= :: forall a b. GlossM a -> (a -> GlossM b) -> GlossM b
$c>>= :: forall a b. GlossM a -> (a -> GlossM b) -> GlossM b
Monad)
instance MonadSchedule GlossM where
schedule :: forall a. NonEmpty (GlossM a) -> GlossM (NonEmpty a, [GlossM a])
schedule NonEmpty (GlossM a)
actions = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a.
YieldT (ReaderT (Float, Maybe Event) (Writer Picture)) a
-> GlossM a
GlossM)) forall a b. (a -> b) -> a -> b
$ forall a.
YieldT (ReaderT (Float, Maybe Event) (Writer Picture)) a
-> GlossM a
GlossM forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadSchedule m =>
NonEmpty (m a) -> m (NonEmpty a, [m a])
schedule forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a.
GlossM a
-> YieldT (ReaderT (Float, Maybe Event) (Writer Picture)) a
unGlossM NonEmpty (GlossM a)
actions
paint :: Picture -> GlossM ()
paint :: Picture -> GlossM ()
paint = forall a.
YieldT (ReaderT (Float, Maybe Event) (Writer Picture)) a
-> GlossM a
GlossM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell
clear :: GlossM ()
clear :: GlossM ()
clear = Picture -> GlossM ()
paint Picture
Blank
paintAll :: Picture -> GlossM ()
paintAll :: Picture -> GlossM ()
paintAll Picture
pic = GlossM ()
clear forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Picture -> GlossM ()
paint Picture
pic
data GlossClock = GlossClock
instance Semigroup GlossClock where
GlossClock
_ <> :: GlossClock -> GlossClock -> GlossClock
<> GlossClock
_ = GlossClock
GlossClock
instance Clock GlossM GlossClock where
type Time GlossClock = Float
type Tag GlossClock = Maybe Event
initClock :: GlossClock
-> RunningClockInit GlossM (Time GlossClock) (Tag GlossClock)
initClock GlossClock
_ = forall (m :: * -> *) a. Monad m => a -> m a
return (forall (m :: * -> *) b a. Monad m => m b -> MSF m a b
constM (forall a.
YieldT (ReaderT (Float, Maybe Event) (Writer Picture)) a
-> GlossM a
GlossM forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Monad m => YieldT m ()
yield forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall (m :: * -> *) r. Monad m => ReaderT r m r
ask) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall v s (m :: * -> *). (VectorSpace v s, Monad m) => MSF m v v
sumS forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
Category.id), Float
0)
instance GetClockProxy GlossClock
type GlossClSF = ClSF GlossM GlossClock () Picture
currentEvent :: ClSF GlossM GlossClock () (Maybe Event)
currentEvent :: ClSF GlossM GlossClock () (Maybe Event)
currentEvent = forall (m :: * -> *) cl a. Monad m => ClSF m cl a (Tag cl)
tagS
flowGlossClSF ::
GlossSettings ->
GlossClSF ->
IO ()
flowGlossClSF :: GlossSettings -> GlossClSF -> IO ()
flowGlossClSF GlossSettings
settings GlossClSF
clsf = forall cl.
(Clock GlossM cl, GetClockProxy cl) =>
GlossSettings -> Rhine GlossM cl () () -> IO ()
flowGloss GlossSettings
settings forall a b. (a -> b) -> a -> b
$ GlossClSF
clsf forall (cat :: * -> * -> *) a b c.
Category cat =>
cat a b -> cat b c -> cat a c
>-> forall (m :: * -> *) a b cl. Monad m => (a -> m b) -> ClSF m cl a b
arrMCl Picture -> GlossM ()
paintAll forall cl (m :: * -> *) a b.
(cl ~ In cl, cl ~ Out cl) =>
ClSF m cl a b -> cl -> Rhine m cl a b
@@ GlossClock
GlossClock
type WorldMSF = MSF Identity ((Float, Maybe Event), ()) (Picture, Maybe ())
flowGloss ::
(Clock GlossM cl, GetClockProxy cl) =>
GlossSettings ->
Rhine GlossM cl () () ->
IO ()
flowGloss :: forall cl.
(Clock GlossM cl, GetClockProxy cl) =>
GlossSettings -> Rhine GlossM cl () () -> IO ()
flowGloss GlossSettings {Int
Display
Color
stepsPerSecond :: GlossSettings -> Int
backgroundColor :: GlossSettings -> Color
display :: GlossSettings -> Display
stepsPerSecond :: Int
backgroundColor :: Color
display :: Display
..} Rhine GlossM cl () ()
rhine =
forall world.
Display
-> Color
-> Int
-> world
-> (world -> Picture)
-> (Event -> world -> world)
-> (Float -> world -> world)
-> IO ()
play Display
display Color
backgroundColor Int
stepsPerSecond (WorldMSF
worldMSF, Picture
Blank) forall {a} {b}. (a, b) -> b
getPic Event -> (WorldMSF, Picture) -> (WorldMSF, Picture)
handleEvent Float -> (WorldMSF, Picture) -> (WorldMSF, Picture)
simStep
where
worldMSF :: WorldMSF
worldMSF :: WorldMSF
worldMSF = forall (m :: * -> *) s a b.
(Functor m, Monad m) =>
MSF (WriterT s m) a b -> MSF m a (s, b)
MSFWriter.runWriterS forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r a b.
Monad m =>
MSF (ReaderT r m) a b -> MSF m (r, a) b
MSFReader.runReaderS forall a b. (a -> b) -> a -> b
$ forall (m2 :: * -> *) (m1 :: * -> *) a b.
(Monad m2, Monad m1) =>
(forall c. m1 c -> m2 c) -> MSF m1 a b -> MSF m2 a b
morphS (forall (m :: * -> *) a. Monad m => YieldT m a -> m a
runYieldT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
GlossM a
-> YieldT (ReaderT (Float, Maybe Event) (Writer Picture)) a
unGlossM) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b. Monad m => m (MSF m a b) -> MSF m a b
performOnFirstSample forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) cl a b.
(Monad m, Clock m cl, GetClockProxy cl) =>
Rhine m cl a b -> m (MSF m a (Maybe b))
eraseClock Rhine GlossM cl () ()
rhine
stepWith :: (Float, Maybe Event) -> (WorldMSF, Picture) -> (WorldMSF, Picture)
stepWith :: (Float, Maybe Event) -> (WorldMSF, Picture) -> (WorldMSF, Picture)
stepWith (Float
diff, Maybe Event
eventMaybe) (WorldMSF
msf, Picture
_) = let ((Picture
picture, Maybe ()
_), WorldMSF
msf') = forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b. MSF m a b -> a -> m (b, MSF m a b)
unMSF WorldMSF
msf ((Float
diff, Maybe Event
eventMaybe), ()) in (WorldMSF
msf', Picture
picture)
getPic :: (a, b) -> b
getPic (a
_, b
pic) = b
pic
handleEvent :: Event -> (WorldMSF, Picture) -> (WorldMSF, Picture)
handleEvent Event
event = (Float, Maybe Event) -> (WorldMSF, Picture) -> (WorldMSF, Picture)
stepWith (Float
0, forall a. a -> Maybe a
Just Event
event)
simStep :: Float -> (WorldMSF, Picture) -> (WorldMSF, Picture)
simStep Float
diff = (Float, Maybe Event) -> (WorldMSF, Picture) -> (WorldMSF, Picture)
stepWith (Float
diff, forall a. Maybe a
Nothing)