ecstasy-0.1.0.1: src/Data/Ecstasy/Types.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Ecstasy.Types where
import Control.Monad.Trans.Maybe (MaybeT)
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.State (StateT)
import Data.Functor.Identity (Identity)
import Data.IntMap (IntMap)
------------------------------------------------------------------------------
-- | The key for an entity.
newtype Ent = Ent { unEnt :: Int }
deriving (Eq, Ord)
instance Show Ent where
show (Ent e) = "Ent " ++ show e
------------------------------------------------------------------------------
-- | The internal state of the 'SystemT' monad.
type SystemState w = (Int, w 'WorldOf)
------------------------------------------------------------------------------
-- | A monad transformer over an ECS given a world 'w'.
type SystemT w = StateT (SystemState w)
------------------------------------------------------------------------------
-- | A monad over an ECS given a world 'w'.
type System w = SystemT w Identity
------------------------------------------------------------------------------
-- | A computation to run over a particular entity.
type QueryT w m = ReaderT (w 'FieldOf) (MaybeT m)
------------------------------------------------------------------------------
-- | Data kind used to parameterize the ECS record.
data StorageType
= FieldOf -- ^ Used to construct the actual entity.
| WorldOf -- ^ Used to construct the world's storage.
| SetterOf -- ^ Used to construct a setter to update an entity.
deriving (Eq, Ord, Show, Read, Enum, Bounded)
------------------------------------------------------------------------------
-- | Data kind used to parameterize the fields of the ECS record.
data ComponentType
= Field -- ^ This component can be owned by any entity.
| Unique -- ^ This component can be owned by only a single entity at a time.
deriving (Eq, Ord, Show, Read, Enum, Bounded)
------------------------------------------------------------------------------
-- | Describes how we can change an 'a'.
data Update a
= Keep -- ^ Keep the current value.
| Unset -- ^ Delete the current value if it exists.
| Set a -- ^ Set the current value.
deriving (Eq, Ord, Show, Read)
------------------------------------------------------------------------------
-- | A type family to be used in your ECS recrod.
type family Component (s :: StorageType)
(c :: ComponentType)
(a :: *) :: * where
Component 'FieldOf c a = Maybe a
Component 'SetterOf c a = Update a
Component 'WorldOf 'Field a = IntMap a
Component 'WorldOf 'Unique a = Maybe (Int, a)