aztecs-0.8.0: src/Aztecs/ECS/Schedule/Reader.hs
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Aztecs.ECS.Schedule.Reader
( ReaderScheduleT (..),
)
where
import Aztecs.ECS.Access
import Aztecs.ECS.Schedule.Dynamic.Reader
import Aztecs.ECS.Schedule.Reader.Class
import Aztecs.ECS.System.Dynamic.Reader
import Aztecs.ECS.System.Reader
import Aztecs.ECS.World (World (..))
import Aztecs.ECS.World.Components (Components)
import Control.Arrow
import Control.Category
import Control.Monad.Fix
import Control.Monad.State (MonadState (..))
import Control.Monad.Trans
import Prelude hiding (id, (.))
type ReaderSchedule m = ReaderScheduleT (AccessT m)
newtype ReaderScheduleT m i o
= ReaderSchedule {runReaderSchedule :: Components -> (DynamicReaderScheduleT m i o, Components)}
deriving (Functor)
instance (Monad m) => Category (ReaderScheduleT m) where
id = ReaderSchedule $ \cs -> (id, cs)
ReaderSchedule f . ReaderSchedule g = ReaderSchedule $ \cs ->
let (g', cs') = g cs
(f', cs'') = f cs'
in (f' . g', cs'')
instance (Monad m) => Arrow (ReaderScheduleT m) where
arr f = ReaderSchedule $ \cs -> (arr f, cs)
first (ReaderSchedule f) = ReaderSchedule $ \cs -> let (f', cs') = f cs in (first f', cs')
instance (Monad m) => ArrowChoice (ReaderScheduleT m) where
left (ReaderSchedule f) = ReaderSchedule $ \cs -> let (f', cs') = f cs in (left f', cs')
instance (MonadFix m) => ArrowLoop (ReaderScheduleT m) where
loop (ReaderSchedule f) = ReaderSchedule $ \cs -> let (f', cs') = f cs in (loop f', cs')
instance (Monad m) => ArrowReaderSchedule (ReaderSystemT m) (ReaderSchedule m) where
reader s = ReaderSchedule $ \cs ->
let (dynS, _, cs') = runReaderSystem s cs
go dynSAcc i = AccessT $ do
w <- get
let (o, a, dynSAcc') = runReaderSystemDyn dynSAcc (entities w) i
((), w') <- lift $ runAccessT a w
put w'
return (o, DynamicReaderSchedule $ go dynSAcc')
in (DynamicReaderSchedule $ go dynS, cs')