aztecs-0.7.0: src/Aztecs/ECS/Access.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
module Aztecs.ECS.Access
( Access,
AccessT (..),
MonadAccess (..),
runAccessT,
)
where
import Aztecs.ECS.Access.Class (MonadAccess (..))
import Aztecs.ECS.World (World (..))
import qualified Aztecs.ECS.World as W
import Aztecs.ECS.World.Bundle (Bundle)
import Control.Monad.Fix (MonadFix)
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Identity (Identity)
import Control.Monad.State.Strict (MonadState (..), StateT (..))
import Prelude hiding (all, lookup, map)
type Access = AccessT Identity
-- | Access into the `World`.
newtype AccessT m a = AccessT {unAccessT :: StateT World m a}
deriving (Functor, Applicative, Monad, MonadFix, MonadIO)
-- | Run an `Access` on a `World`, returning the output and updated `World`.
runAccessT :: (Functor m) => AccessT m a -> World -> m (a, World)
runAccessT a = runStateT $ unAccessT a
instance (Monad m) => MonadAccess Bundle (AccessT m) where
spawn b = AccessT $ do
!w <- get
let !(e, w') = W.spawn b w
put w'
return e
insert e c = AccessT $ do
!w <- get
let !w' = W.insert e c w
put w'
lookup e = AccessT $ do
!w <- get
return $ W.lookup e w
remove e = AccessT $ do
!w <- get
let !(a, w') = W.remove e w
put w'
return a
despawn e = AccessT $ do
!w <- get
let !(_, w') = W.despawn e w
put w'