module Game.GoreAndAsh.Core.Arrow(
GameWire
, liftGameMonad
, liftGameMonad1
, liftGameMonad2
, liftGameMonad3
, liftGameMonad4
, liftGameMonadOnce
, liftGameMonad1Once
, liftGameMonad2Once
, liftGameMonad3Once
, liftGameMonad4Once
, once'
, mapE
, filterE
, filterEG
, filterEGM
, filterJustE
, filterJustLE
, liftGameMonadEvent1
, changes
, stateWire
, chainWires
, dispense
, dDispense
, deltaTime
) where
import Control.Monad.Fix
import Control.Wire
import Control.Wire.Unsafe.Event
import Data.Filterable
import Data.Maybe (fromJust, isJust)
import Prelude hiding (id, (.))
import Game.GoreAndAsh.Core.Monad
import Game.GoreAndAsh.Core.Session
type GameWire m a b = Wire GameTime () (GameMonadT m) a b
liftGameMonad :: Monad m => GameMonadT m b -> GameWire m a b
liftGameMonad action = mkGen_ $ \ _ -> do
val <- action
return $ Right val
liftGameMonad1 :: Monad m => (a -> GameMonadT m b) -> GameWire m a b
liftGameMonad1 action = mkGen_ $ \ a -> do
val <- action a
return $ Right val
liftGameMonad2 :: Monad m => (a -> b -> GameMonadT m c) -> GameWire m (a, b) c
liftGameMonad2 action = mkGen_ $ \ (a, b) -> do
val <- action a b
return $ Right val
liftGameMonad3 :: Monad m => (a -> b -> c -> GameMonadT m d) -> GameWire m (a, b, c) d
liftGameMonad3 action = mkGen_ $ \ (a, b, c) -> do
val <- action a b c
return $ Right val
liftGameMonad4 :: Monad m => (a -> b -> c -> d -> GameMonadT m e) -> GameWire m (a, b, c, d) e
liftGameMonad4 action = mkGen_ $ \ (a, b, c, d) -> do
val <- action a b c d
return $ Right val
liftGameMonadOnce :: Monad m => GameMonadT m b -> GameWire m a b
liftGameMonadOnce action = mkGen $ \_ _ -> do
val <- action
return (Right val, pure val)
liftGameMonad1Once :: Monad m => (a -> GameMonadT m b) -> GameWire m a b
liftGameMonad1Once action = mkGen $ \_ a -> do
val <- action a
return (Right val, pure val)
liftGameMonad2Once :: Monad m => (a -> b -> GameMonadT m c) -> GameWire m (a, b) c
liftGameMonad2Once action = mkGen $ \_ (a, b) -> do
val <- action a b
return (Right val, pure val)
liftGameMonad3Once :: Monad m => (a -> b -> c -> GameMonadT m d) -> GameWire m (a, b, c) d
liftGameMonad3Once action = mkGen $ \_ (a, b, c) -> do
val <- action a b c
return (Right val, pure val)
liftGameMonad4Once :: Monad m => (a -> b -> c -> d -> GameMonadT m e) -> GameWire m (a, b, c, d) e
liftGameMonad4Once action = mkGen $ \_ (a, b, c, d) -> do
val <- action a b c d
return (Right val, pure val)
once' :: Monad m => GameWire m a (Event b) -> GameWire m a (Event b)
once' w = proc a -> do
e <- w -< a
drSwitch id -< (e, fmap (const never) e)
mapE :: Monad m => (a -> b) -> GameWire m (Event a) (Event b)
mapE f = arr $ \e -> case e of
NoEvent -> NoEvent
Event a -> Event $ f a
filterEG :: (Foldable f, Filterable f, FilterConstraint f a, Monad m)
=> (a -> Bool)
-> GameWire m (Event (f a)) (Event (f a))
filterEG p = arr $ \e -> case e of
NoEvent -> NoEvent
Event as -> let
as' = fFilter p as
in if fNull as'
then NoEvent
else length as' `seq` Event as'
filterEGM :: (Foldable f, Filterable f, FilterConstraint f a, Monad m)
=> (a -> GameMonadT m Bool)
-> GameWire m (Event (f a)) (Event (f a))
filterEGM p = mkGen_ $ \e -> case e of
NoEvent -> return $! Right NoEvent
Event as -> do
as' <- fFilterM p as
if fNull as'
then return $! Right NoEvent
else return . Right $! length as' `seq` Event as'
filterJustE :: Monad m => GameWire m (Event (Maybe a)) (Event a)
filterJustE = mapE fromJust . filterE isJust
filterJustLE :: (Monad m, Filterable f, FilterConstraint f (Maybe a), Functor f) => GameWire m (Event (f (Maybe a))) (Event (f a))
filterJustLE = mapE (fmap fromJust . fFilter isJust)
liftGameMonadEvent1 :: Monad m => (a -> GameMonadT m b) -> GameWire m (Event a) (Event b)
liftGameMonadEvent1 = onEventM
stateWire :: MonadFix m => b -> GameWire m (a, b) b -> GameWire m a b
stateWire ib w = loop $ proc (a, b_) -> do
b <- delay ib -< b_
b2 <- w -< (a, b)
returnA -< (b2, b2)
chainWires :: Monad m => [GameWire m a a] -> GameWire m a a
chainWires [] = id
chainWires (w:ws) = w . chainWires ws
changes :: (Monad m, Eq a) => GameWire m a (Event a)
changes = mkPureN $ \a -> (Right $! Event a, go a)
where
go cura = mkPureN $ \a -> if a == cura
then (Right NoEvent, go cura)
else a `seq` (Right $! Event a, go a)
dispense :: (Monad m) => [a] -> GameWire m (Event b) a
dispense = go . cycle
where
go [] = error "dispense: empty list"
go (a:as) = mkPureN $ \e -> case e of
NoEvent -> (Right a, go $ a:as)
Event _ -> (Right $ head as, go as)
dDispense :: (Monad m) => [a] -> GameWire m (Event b) a
dDispense = go . cycle
where
go [] = error "dDispense: empty list"
go (a:as) = mkPureN $ \e -> case e of
NoEvent -> (Right a, go $ a:as)
Event _ -> (Right a, go as)
deltaTime :: (Fractional b, Monad m) => GameWire m a b
deltaTime = mkSF $ \ds _ -> let t = realToFrac (dtime ds) in t `seq` (t, deltaTime)